When developing a credential verification system for a DeFi protocol, we faced the need to verify users' KYC status without disclosing their personal data. Standard blockchain verification reveals all credential attributes, violating privacy. The solution is verifiable credentials using ZK-proof (Groth16 or PLONK), which allow proving only the required fact. This infrastructure is standardized by W3C (W3C Verifiable Credentials Standard) and supported by wallets (MetaMask, WalletConnect) and protocols. We implement the full cycle: issuance, storage, verification, and revocation of digital credentials based on W3C Verifiable Credentials standards. The system can integrate with existing KYC providers (Persona, Jumio) and run on Ethereum, Polygon, or Arbitrum. Gas savings with ZK-proof on L2 amount to up to 70% — with 1000 verifications per day, this saves over $500 per month.
Architecture of Verification on the Blockchain
The system is built from three key components:
-
Issuer — a trusted organization (KYC provider, educational institution, DAO) that issues signed credentials via its own DID.
-
Holder — a user storing credentials (e.g., in a wallet or via Polygon ID).
-
Verifier — a protocol or dApp that checks credentials before granting access.
The verifier generates a unique challenge (nonce); the holder includes it in the Verifiable Presentation and signs it. This prevents replay attacks: the presentation is valid only for that specific request.
// User creates a presentation
const presentation = {
"@context": ["https://www.w3.org/2018/credentials/v1"],
"type": ["VerifiablePresentation"],
"verifiableCredential": [kycCredential],
"proof": {
"type": "Ed25519Signature2020",
"challenge": nonce,
"domain": "app.example.com",
"created": new Date().toISOString(),
"verificationMethod": `did:ethr:${userAddress}#controller`,
"proofPurpose": "authentication",
"jws": await signPresentation(nonce)
}
};
Necessity of ZK-Verification
Standard verification reveals the entire credential: the protocol sees the issuer, issuance date, and all attributes. ZK-proof (Groth16 or PLONK) changes this: the user proves a fact ("I have a valid KYC credential") without revealing its content. This approach is required for:
-
DeFi lending — verify that a borrower passed KYC without disclosing their identity.
-
DAO governance — grant voting rights only to holders of Contributor SBTs, without showing who holds them.
-
Compliant DEX — allow trading only for verified addresses from allowed jurisdictions.
ZK-proof accelerates verification by 3–5 times compared to full verification (when using Plookup-based frameworks) and provides the confidentiality required by GDPR.
How ZK-proof Protects Privacy?
A ZK-proof allows the verifier to be convinced of a statement's truth without seeing the original data. For example, a user proves they are over 18 without presenting their passport. This is achieved with circuits written in circom and snarkjs. An on-chain registry stores only a hash or state snapshot; full credentials remain with the user.
What is On-chain Registry?
An on-chain registry is a smart contract that stores references to current credentials or their fingerprints. When a credential is revoked, the issuer updates the registry, and the verifier checks the status. This approach ensures transparency and immutability but requires gas management. We optimize gas consumption by storing only data necessary for verification.
Our Approach: What's Included in Development
We design the system turnkey from scratch or integrate with an existing architecture. Our development includes:
- Select the standard (W3C VC + DID or Polygon ID for ZK).
- Deploy an on-chain Registry smart contract on Ethereum/Polygon/Arbitrum (your choice).
- Integrate trusted issuers (Persona, Jumio, Onfido, or your own).
- Develop a Verifier SDK (ethers.js, viem) for use in the protocol.
- Implement ZK circuits (circom + snarkjs) and a verifier smart contract (if needed).
- Conduct a security audit (Slither, Mythril, Echidna fuzzing).
- Deliver documentation, tests, and deployment instructions.
Comparison of Verification Methods
| Method |
Privacy |
Gas cost (L2) |
Verification time |
Standard support |
| Standard VC verification |
Low (reveals all data) |
~50,000 gas |
<1 sec |
W3C VC + DID |
| ZK-proof (Groth16) |
High (only fact) |
~300,000 gas |
2–3 sec |
Polygon ID, circom |
| ZK-proof (PLONK) |
High (only fact) |
~200,000 gas |
1–2 sec |
PLONK, Halo2 |
| On-chain commitment + off-chain verification |
Medium (hash) |
~30,000 gas |
<1 sec |
Custom |
Development Stages
| Stage |
Duration |
Result |
| Analytics |
1–2 weeks |
Technical specification, stack selection |
| Design |
1–2 weeks |
Smart contract and ZK circuit architecture |
| Implementation |
4–8 weeks |
Contracts, circuits, SDK, tests |
| Audit |
1–2 weeks |
Security report |
| Deployment |
1 week |
Network deployment, integration |
| Support |
3 months |
Documentation, training, refinements |
Process
-
Analytics — clarify credential types, number of issuers, privacy requirements.
-
Design — choose stack (Foundry/Hardhat, circom/snarkjs), smart contract architecture.
-
Implementation — write contracts, ZK circuits, SDK, tests (unit + integration).
-
Audit — internal and external security audit.
-
Deployment — deploy on the chosen network, integrate with your protocol.
-
Support — documentation, team training, 3-month warranty support.
Example circom configuration for KYC
pragma circom 2.0.0;
include "../../node_modules/circomlib/circuits/comparators.circom";
template KYCCredential(ageThreshold) {
signal input age;
signal input country;
signal input isKYC;
signal output valid;
component ageCheck = GreaterThan(32);
ageCheck.in[0] <== age;
ageCheck.in[1] <== ageThreshold;
valid <== ageCheck.out * isKYC;
}
Timeline and What You Get
Development of a complete credential verification system takes 8–16 weeks depending on complexity. The cost is calculated individually after requirements audit. To assess your project, reach out to us for a consultation.
Note what you will receive:
- Deployable smart contracts (Registry + Verifier) with open source.
- Verifier SDK (TypeScript) for integration into your protocol.
- ZK circuits (if required) with audited code.
- Architecture, deployment, and operation documentation.
- 3 months of support and refinements per your specification.
Our team's experience: 5+ years in blockchain development, 10+ projects in DeFi, NFT, and identity. We guarantee functionality and passing security audits. Order development and get a reliable verification infrastructure.
Digital Identity on Blockchain: DID, SBT, and Verifiable Credentials
We often encounter requests where a Web3 project has built an AMM pool or lending protocol but still authenticates users with JWT and MongoDB. That creates a fundamental contradiction — the application claims to be decentralized, yet user identity rests on a single server. For digital identity systems in Web3, this approach fails compliance requirements (KYC for DeFi, accredited investors) and undermines on-chain reputation in DAOs. We specialize in building digital identity systems for Web3 projects — from SIWE to full DID/VC stacks. Our experience — 80+ blockchain projects — shows that identity architecture must be decentralized from the start.
How does Sign-In with Ethereum solve authentication?
EIP-4361 (SIWE) removes login/password entirely. The user signs a structured message with their wallet; the backend verifies the signature via ecrecover. No credential leaks, no password hashing.
Implementation: siwe library (JS/TS) on the frontend, SiweMessage.verify() on the backend. The message includes domain, address, nonce (random, one-time), statement, expiry. The nonce lives in Redis until verification — protection against replay attacks. Today, SIWE is used by over 80 projects in the top 100 DeFi.
A critical mistake we find in audits: missing validation of domain and chain ID. If the backend does not check message.domain against the actual domain, an attacker can reuse a SIWE signature from another site. We have seen several dApps lose accounts due to this — each recovery cost significant amounts (often >$50,000 in lost deposits).
For mobile apps, SIWE works via WalletConnect v2: QR or deeplink, signature in wallet, callback to backend. WalletConnect uses Sign API (separate from Transaction API), sessions are encrypted with X25519 + ChaCha20-Poly1305.
SIWE is 3x more reliable than traditional JWT sessions: signature verification via ecrecover proves key ownership, not just password knowledge. Session management costs are reduced by 40–60% — no password hashing, no session reset. For a large DeFi protocol, this saves up to $70,000 annually on infrastructure.
What is DID and which method to choose?
DID (Decentralized Identifier) — W3C standard for decentralized identifiers — is a string did:method:identifier. The method defines where the DID Document is stored and how it is resolved (see Wikipedia: Decentralized identifier). The main methods we use in production:
| Method |
Storage Location |
Gas Cost |
Use Case |
did:ethr |
EthereumDIDRegistry (ERC-1056) |
~60,000 gas on write |
DeFi, DAO — key rotation |
did:key |
Deterministically derived from pubkey |
Gasless |
Ephemeral identity, test |
did:web |
HTTPS (/.well-known/did.json) |
Gasless |
Enterprise (DNS trust) |
did:ion |
Bitcoin Layer 2 (Sidetree) |
~5,000 gas |
Long-term, high security |
For most DeFi projects, did:ethr or did:key suffice. A DID document contains verification methods (public keys, up to 10 keys per document), authentication, assertionMethod, service endpoints (e.g., link to KYC service). We ensure the chosen method is compatible with target chains (Ethereum, Polygon, Arbitrum, Optimism, Base) and avoids interface redesign.
Common mistakes when choosing a DID method:
- Choosing
did:web without understanding centralization — if the DNS domain is hijacked, identity is compromised.
- Ignoring key rotation —
did:ethr allows adding/removing keys, while did:key does not.
- Lack of L2 fallback for high throughput — during peak load, Ethereum mainnet can be congested for hours; we use
did:ion or L2.
How does verification work via Verifiable Credentials?
Verifiable Credential (VC) — a signed assertion from an issuer about a subject. W3C format: JSON-LD or JWT. Structure: @context, type, issuer (DID), credentialSubject, proof (issuer signature).
Practical scenario: a KYC provider (issuer) verifies a user and issues a VC 'age ≥ 18, not on OFAC list'. The user stores the VC locally (wallet extension or mobile app). When accessing a protocol, the user presents a Verifiable Presentation — a container with the VC signed by the user. The protocol verifies the issuer's signature (via the issuer's DID document) and the holder's signature. No personal data goes on-chain. The protocol does not store a database of KYC-passed users. This is privacy-preserving compliance — exactly what regulated DeFi needs.
Zero-knowledge proofs for VCs take privacy to another level. Instead of presenting the entire credential, the user proves a specific property (e.g., age ≥ 18) without revealing the value. Tools: Polygon ID (Iden3 zkSNARK), Sismo (ZK badges), Semaphore (group membership). Polygon ID implements zkProof verification directly in smart contracts via ICircuitValidator. Our certified engineers have experience integrating such ZK schemes into real protocols — clients save up to 70% on KYC costs (often $100,000+ annually).
Why are Soulbound Tokens not suitable for mass adoption?
SBTs (EIP-5192, concept by Vitalik Buterin) are non-transferable NFTs. Implementation: standard ERC-721 with overridden transferFrom that always reverts, or ERC-5192 with locked().
Production uses:
- DAO Governance — Snapshot + SBT for one-person-one-vote. Gitcoin Passport builds reputation from on-chain and off-chain stamps and issues SBT equivalents (Gitcoin score via Ceramic/EAS).
- Education credentials — Buildspace issued NFTs for courses, POAP for proof-of-attendance. SBTs make them non-transferable — cannot buy someone else's history.
- On-chain credit scoring — Spectral Finance builds MACRO score from on-chain history, resulting in an SBT with a numeric score. Lending protocols use it for under-collateralized loans.
Key technical limitation: recovery mechanism. Losing access to a wallet means losing all SBTs. Without recovery, mass adoption is impossible. Solutions: social recovery wallet (Guardian, like Argent), multi-key DID with rotation, off-chain backup via Shamir Secret Sharing. We include recovery planning in every SBT project.
Ethereum Attestation Service as a standard identity layer
EAS is deployed on Ethereum mainnet, Optimism, Arbitrum, Base. Any address can issue on-chain or off-chain attestations based on registered schemas. A schema is an ABI-encoded structure. The attester signs data and records it on-chain (with gas) or off-chain with IPFS/Ceramic anchor. Verifiers read via IEAS.getAttestation(uid).
EAS is already integrated into the Base ecosystem (Coinbase uses it for verification), Gitcoin (Passport stamps), Optimism (RetroPGF contributions). It is becoming the de facto standard for on-chain identity layer on L2. Our developers are certified for EAS (experience with 5+ projects). According to EAS documentation, attestations can be revoked, and schemas supportup to 32 fields of arbitrary ABI types.
How can we choose the right identity solution for your project?
- Analytics & compliance — map the user journey: who is issuer, verifier, what data is needed, what cannot be stored on-chain under GDPR.
- Architecture design — choose between on-chain SBT, EAS, DID/VC stack. Data schema, ZK circuit (if needed).
- Implementation — smart contracts (Solidity 0.8.x, Foundry/Hardhat), issuer service (Node.js/Go), holder wallet (ethers.js viem), verifier contract.
- Testing & audit — unit tests, integration tests, fuzzing (Echidna), static analysis (Slither). Engage third-party auditor.
- Deploy & support — deploy to target networks, monitoring (Tenderly), documentation, team training.
Deliverables
- Source code of smart contracts (Solidity, open-sourced under MIT)
- Issuer backend (Node.js/Go) with API for issuing VC/SBT
- Holder wallet integration (ethers.js viem, RainbowKit, WalletConnect)
- Verifier contract/script
- Architecture documentation, deployment runbook
- 2 months post-deployment support
Timeline Estimates
| Phase |
Duration |
| SIWE integration (wallet authentication) |
2 to 4 weeks |
| SBT contracts + minting portal |
3 to 6 weeks |
| EAS attestation schema + verification |
4 to 8 weeks |
| Full DID/VC pipeline (issuer + holder + verifier) |
3 to 6 months |
| ZK-based privacy-preserving credentials |
5 to 9 months |
Cost is calculated individually based on schema complexity, number of chains, and compliance requirements. Contact us to discuss your scenario and get an optimal plan.
Order a digital identity system development — get a consultation with a senior engineer specialized in this field. Also, book a technical audit of your current identity system — we will identify bottlenecks and suggest concrete improvements.