Development of Blockchain Credential Verification System
Blockchain credential verification — infrastructure for checking claims: "This address passed KYC", "This company is real", "This developer has a certain skill level". System answers the question: how can a protocol verify facts about a user without centralized identity provider and without revealing unnecessary data?
Verification System Architecture
Credential Issuers
Organizations issuing verifiable credentials:
- KYC providers (Persona, Jumio, Onfido)
- Professional associations
- Educational institutions
- DAOs and protocols (contributor credentials)
- Government bodies (in future)
Each issuer has a known DID and public key. Issuer authenticity is verified through its DID Document.
On-chain Verification Registry
contract CredentialVerificationRegistry {
// Registered trusted issuers
mapping(address => IssuerRecord) public trustedIssuers;
struct IssuerRecord {
string name;
string[] supportedCredentialTypes;
bool active;
uint256 addedAt;
}
// Cache of verified facts (to avoid re-verifying each time)
mapping(address => mapping(bytes32 => VerificationRecord)) public verifications;
struct VerificationRecord {
bool verified;
address verifiedBy; // which issuer
uint256 verifiedAt;
uint256 expiresAt;
bytes32 credentialType;
}
// Verifier records result after off-chain VC verification
function recordVerification(
address subject,
bytes32 credentialType,
uint256 expiresAt
) external onlyTrustedIssuer {
verifications[subject][credentialType] = VerificationRecord({
verified: true,
verifiedBy: msg.sender,
verifiedAt: block.timestamp,
expiresAt: expiresAt,
credentialType: credentialType
});
}
function isVerified(address subject, bytes32 credentialType)
external view returns (bool) {
VerificationRecord memory record = verifications[subject][credentialType];
return record.verified &&
block.timestamp < record.expiresAt;
}
}
Presentation Protocol
User presents credentials for verification through Verifiable Presentation (VP):
// User creates presentation from their credentials
const presentation = {
"@context": ["https://www.w3.org/2018/credentials/v1"],
"type": ["VerifiablePresentation"],
"verifiableCredential": [kycCredential],
"proof": {
"type": "Ed25519Signature2020",
"challenge": nonce, // prevents replay attacks
"domain": "app.example.com",
"created": new Date().toISOString(),
"verificationMethod": `did:ethr:${userAddress}#controller`,
"proofPurpose": "authentication",
"jws": await signPresentation(nonce)
}
};
Challenge-response: server generates nonce, user includes in presentation and signs. Prevents replay attack (presentation valid only for this specific request).
Privacy-preserving Verification
Problem: standard verification reveals entire VC. Protocol learns not only that user passed KYC, but when, which provider, and other data.
ZK-proof verification: user proves fact ("I have valid KYC VC") without revealing VC content.
// Polygon ID style ZK verification
const proofRequest = {
id: "kyc-verification-request",
typ: "application/iden3comm-plain-json",
type: "https://iden3-communication.io/proofs/1.0/contract-invoke-request",
body: {
transaction_data: {
contract_address: verifierContractAddress,
method_id: "submitZKPResponse"
},
scope: [{
id: 1,
circuitId: "credentialAtomicQueryMTP",
query: {
allowedIssuers: ["*"],
type: "KYCVerification",
credentialSubject: {
isVerified: { "$eq": true }
}
}
}]
}
};
On smart contract — Groth16 or PLONK verifier for ZK proof.
Protocol Integration
Lending protocol: before issuing loan — check KYC credential. DAO governance: only holders of Contributor SBT can vote. Compliant DEX: trading only for verified users from whitelisted jurisdictions.
modifier onlyVerifiedUser(address user) {
require(
credentialRegistry.isVerified(user, KYC_CREDENTIAL_TYPE),
"KYC verification required"
);
_;
}
Development of full credential verification system — 8-16 weeks depending on privacy requirements and number of integrated issuers.







