Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
Free 30-min Web3 Consultation
Book Consultation
Smart Contract Security Audits
View Audit Services
Custom DeFi Protocol Development
Explore DeFi
Full-Stack Web3 dApp Development
View App Services
LABS
Guides

Setting Up Selective Disclosure for Security Token Holders

A developer tutorial for implementing cryptographically-enforced selective disclosure protocols. This guide covers smart contract design, Verifiable Credential issuance, and zero-knowledge proof integration for regulated token ecosystems.
Chainscore © 2026
introduction
PRIVACY AND COMPLIANCE

Setting Up Selective Disclosure for Security Token Holders

Selective disclosure allows token issuers to verify investor credentials without exposing sensitive personal data, a critical feature for compliant security token offerings.

Selective disclosure is a cryptographic technique that enables a user to prove they possess certain credentials or meet specific criteria without revealing the underlying data. In the context of security tokens, this allows an investor to prove their accredited investor status or jurisdictional eligibility to a token issuer or transfer agent, while keeping their exact income, net worth, or passport details private. This is achieved using zero-knowledge proofs (ZKPs) or other privacy-preserving protocols, moving beyond the traditional, risky model of submitting full KYC/AML documents.

The technical setup typically involves a verifiable credentials (VC) ecosystem. First, a trusted issuer (like a licensed KYC provider) issues a cryptographically signed credential to the investor's digital wallet. This credential contains the attested claims (e.g., "accredited": true, "jurisdiction": "US"). The investor's wallet then generates a selective disclosure proof. For a transfer, they might prove the statement "I hold a valid credential from Issuer X attesting I am from a permitted jurisdiction" without showing the credential's entire contents.

Implementing this requires choosing a supported framework. For Ethereum-based tokens, the ERC-5849 (ZK KYC) standard or integrations with Veramo or Serto agent frameworks are common starting points. A basic flow involves: 1) The issuer creates a VC schema defining the required fields. 2) Investors complete off-chain verification and receive a signed VC. 3) The smart contract governing the security token includes a verifyProof function that checks ZK proofs submitted by users before allowing a mint or transfer.

For developers, a minimal proof verification in a Solidity smart contract might look like this:

solidity
function mintToken(bytes memory _proof, bytes32 _nullifierHash) public {
    require(verifyZKProof(_proof, _nullifierHash), "Invalid proof");
    require(!nullifierSpent[_nullifierHash], "Proof already used");
    nullifierSpent[_nullifierHash] = true;
    _mint(msg.sender, 1);
}

The verifyZKProof function would contain the circuit logic to validate the investor's hidden credentials against the issuer's public key and the contract's policy.

Key considerations for implementation include selective disclosure granularity (proving a range like "age > 18" vs. exact age), preventing proof replay attacks using nullifiers, and ensuring the trusted credential issuer's public key is securely registered on-chain. Projects like Polygon ID and Sismo offer SDKs and infrastructure to abstract much of this complexity, allowing token issuers to integrate privacy-preserving checks with less custom cryptography.

Adopting selective disclosure reduces liability for issuers by minimizing the storage of sensitive PII and enhances investor privacy. It creates a more scalable and compliant foundation for Security Token Offerings (STOs) and regulated DeFi, aligning blockchain innovation with financial regulations like the Travel Rule. The technology is evolving rapidly, with new standards and more efficient proving systems continually emerging.

prerequisites
FOUNDATION

Prerequisites and System Architecture

This guide outlines the technical foundation required to implement selective disclosure for security token holders, focusing on the core components and their interactions.

Selective disclosure allows token holders to prove specific claims about their holdings—such as being accredited or holding a minimum stake—without revealing their entire wallet balance or transaction history. This is a critical privacy and compliance feature for security tokens, which are subject to regulations like KYC/AML. The system relies on zero-knowledge proofs (ZKPs) or verifiable credentials (VCs) to generate cryptographic attestations. A holder can present a proof to a dApp or service, which can verify its validity on-chain without learning any underlying private data.

The core architecture consists of three main components: the Issuer, the Holder, and the Verifier. The Issuer (e.g., a token issuer or a trusted KYC provider) creates verifiable credentials attesting to a holder's status. The Holder stores these credentials in a secure wallet and generates ZK proofs for specific disclosures. The Verifier (e.g., a gated DeFi protocol or governance platform) checks the proof's validity against the issuer's public key or a smart contract. This trust model, often based on the W3C Verifiable Credentials standard, decentralizes credential issuance while maintaining cryptographic assurance.

Key prerequisites include a blockchain supporting smart contracts for verification logic (like Ethereum, Polygon, or a dedicated L2), a wallet capable of storing and presenting VCs (such as a MetaMask Snap or a specialized identity wallet), and an issuer backend. The issuer must run a secure service to perform identity checks and sign credentials. For developers, familiarity with libraries like @veramo/core for credential management, snarkjs or circom for ZK circuits, and Solidity for on-chain verifiers is essential. All system components must be designed to handle private keys for signing with the highest security standards.

A typical data flow begins when a holder completes KYC with an issuer. The issuer's backend creates a signed VC with claims (e.g., { "accredited": true, "jurisdiction": "US" }) and sends it to the holder's wallet. When accessing a gated service, the holder's wallet uses a ZK circuit to prove a statement like "I hold an accredited investor credential from TrustedIssuer Inc." without revealing the credential's full contents. The verifier's smart contract, which holds the issuer's public verification key, validates the proof. This architecture ensures data minimization, giving users control over what they share.

When designing the system, consider the trade-offs between on-chain versus off-chain verification. On-chain verification (using a verifier contract) provides maximum transparency and interoperability but incurs gas costs. Off-chain verification is faster and cheaper but requires the verifier to run a trusted server. For most security token use cases, a hybrid approach is optimal: lightweight proofs are verified on-chain for critical actions (like voting or accessing high-value pools), while off-chain checks handle preliminary screening. The choice of ZK proof system (e.g., Groth16, PLONK) will impact proof generation time, verification cost, and trust assumptions.

Finally, ensure your architecture accounts for credential revocation and key rotation. Issuers must be able to revoke credentials if a holder's status changes. This can be managed via on-chain revocation registries (checking a merkle root) or timestamp-based expiration embedded in the credential. The system should also define clear trust frameworks—which issuers are authorized for which types of claims—and make these policies transparent to holders and verifiers. Properly implemented, this architecture enables compliant, privacy-preserving access to tokenized securities markets.

key-concepts-text
CORE CRYPTOGRAPHIC CONCEPTS

Setting Up Selective Disclosure for Security Token Holders

Selective disclosure allows security token holders to prove specific claims about their identity or credentials without revealing their entire data set, a critical feature for regulatory compliance and privacy.

Selective disclosure is a cryptographic technique that enables a user to reveal only a subset of the information contained within a verifiable credential. In the context of security tokens, which represent ownership in regulated assets like equity or debt, this is essential. A holder might need to prove they are an accredited investor to a platform without exposing their exact net worth or social security number. This is achieved using zero-knowledge proofs (ZKPs) or BBS+ signatures, which allow the creation of a derived proof that is cryptographically linked to the original credential but contains only the disclosed attributes.

The process typically involves three roles: the issuer (e.g., a KYC provider), the holder (the investor), and the verifier (a trading platform). The issuer signs a credential containing multiple claims. The holder then generates a presentation from this credential. Using ZKPs, the holder can prove the credential is valid and was issued to them, while selectively choosing which fields to disclose (e.g., countryOfResidence: "US") and which to keep private (e.g., dateOfBirth). The verifier can cryptographically check the signature and proof without learning the hidden data.

To implement this, developers often use libraries like @mattrglobal/bbs-signatures or frameworks supporting the W3C Verifiable Credentials data model. A basic flow involves creating a BBS+ key pair for the issuer, signing a credential with attributes, and then allowing the holder to create a proof disclosure frame. This frame is a JSON document specifying which attributes to reveal. The cryptographic proof ensures the disclosed data is unaltered and the undisclosed data exists, maintaining the credential's integrity.

For security tokens, common use cases include proving jurisdictional eligibility without revealing full address, demonstrating membership in a specific investor group, or verifying age is over a threshold. This minimizes data leakage and reduces counterparty risk. When designing a system, it's crucial to decide which attributes are always disclosed (like a credential schema ID) and which can be selectively disclosed. The choice of cryptographic suite (BBS+ vs. CL signatures) will affect proof size and computational overhead for mobile holders.

Best practices for integration include storing the original signed credential securely in the holder's wallet (e.g., a mobile app using secure enclaves) and using standard presentation exchange protocols like DIDComm or OpenID for Verifiable Credentials. Verifiers should always check the proof against the issuer's public DID Document retrieved from a verifiable data registry. This creates a trust chain from the issuer to the presented claim, enabling compliant, privacy-preserving interactions in regulated DeFi and traditional capital markets.

TECHNICAL OVERVIEW

Comparison of Selective Disclosure Methods

A comparison of cryptographic and smart contract-based methods for revealing specific token holder data without exposing the full wallet.

Method / FeatureZero-Knowledge Proofs (ZKPs)Commitment SchemesProxy Contracts with Merkle Proofs

Cryptographic Guarantee

Full privacy (zero-knowledge)

Binding but not hiding by default

No cryptographic privacy

On-Chain Data Leakage

None (proofs only)

Commitment hash is public

Merkle root and proofs are public

Gas Cost for Verification

High (100k-1M+ gas)

Low (<50k gas)

Medium (50k-200k gas)

Setup Complexity

High (circuit creation)

Low

Medium (tree management)

Suitable For

Regulatory KYC, private balances

Voting, claim eligibility

Airdrops, whitelists

Trust Assumptions

Trustless (cryptographic)

Trustless (cryptographic)

Trusted data source for Merkle root

Example Protocol

Aztec, zkSNARKs

Semaphore, MACI

Uniswap Merkle Distributor

step-1-vc-issuance
SETTING UP SELECTIVE DISCLOSENCE

Step 1: Issue Verifiable Credentials to Holders

This guide explains how to issue W3C Verifiable Credentials (VCs) to token holders, enabling them to prove specific claims about their holdings without revealing their entire portfolio.

Verifiable Credentials are a W3C standard for creating tamper-proof digital attestations. In the context of security tokens, a VC can represent a claim such as "Holder X owns at least 100 ABC Tokens as of block 20,000,000." The issuer cryptographically signs this claim, creating a portable credential the holder can store in a digital wallet. This moves beyond simple on-chain verification, enabling off-chain proof of compliance or eligibility for services like whitelists, governance participation, or KYC/AML checks.

To issue a credential, you first define a credential schema. This JSON-LD or JSON Schema document structures the data you will attest to, such as tokenId, minimumBalance, issuanceDate, and expiryDate. Using a library like veramo or did-jwt-vc, you create a signed Verifiable Credential. The credential's subject is the holder's Decentralized Identifier (DID), and the proof is a digital signature from the issuer's DID. The resulting VC is a JSON object that can be delivered to the holder via an API endpoint or a QR code.

For security tokens, the credential's claims must be anchored to verifiable on-chain state. Before issuance, your backend service should query the relevant smart contract—like an ERC-1400 or ERC-3643 token—to validate the holder's balance meets the required threshold. This check, combined with a cryptographic nonce to prevent replay attacks, ensures the credential reflects a true and current state. The issuance logic can be automated via off-chain agents or integrated into on-chain functions using oracles like Chainlink.

Holders receive the VC in a compatible wallet, such as one supporting the did:ethr or did:key method. They can now use selective disclosure to share only necessary information. For instance, to prove eligibility for a token-gated event, they could generate a Verifiable Presentation that reveals only the minimumBalance claim, hiding the specific tokenId and other metadata. This is typically done using BBS+ signatures or zero-knowledge proofs (ZKPs) for advanced privacy, supported by protocols like AnonCreds.

Implementing this step establishes the foundation for privacy-preserving compliance. It allows issuers to delegate proof of compliance to the holder, reducing the need for constant on-chain checks and centralized databases. The next step involves configuring the verification logic that services will use to trust and validate these presented credentials, completing the loop of decentralized, user-centric identity for capital markets.

step-2-disclosure-smart-contract
CORE CONTRACT LOGIC

Step 2: Build the Disclosure Verifier Smart Contract

This step implements the on-chain logic for verifying selective disclosures, enabling token holders to prove specific credentials without revealing their entire identity.

The Disclosure Verifier smart contract is the on-chain arbiter of the selective disclosure system. Its primary function is to validate Zero-Knowledge Proofs (ZKPs) submitted by token holders. A holder can generate a proof off-chain, using a tool like Circom or SnarkJS, that cryptographically demonstrates they possess a credential meeting specific criteria—such as being an accredited investor from a certain jurisdiction—without revealing their wallet address or other personal data. The contract's verifyDisclosure function receives this proof and the associated public signals, then uses a verification key to confirm its validity.

Deploying this contract requires a pre-generated verification key, which is a set of elliptic curve parameters specific to the circuit that creates the proofs. This circuit, defined in a domain-specific language, encodes the rules for the disclosure (e.g., "investor accreditation status = true AND country code = US"). You must compile this circuit and extract its verification key before deployment. The contract stores this key immutably, ensuring the verification logic cannot be changed post-deployment. For development, you can use Hardhat or Foundry to script this deployment process.

A minimal Solidity implementation for a verifier using the Groth16 proof system, common with Circom, would import a verifier interface. The core function is straightforward: it calls the verifier contract with the proof and public inputs. It's crucial that the contract also emits an event upon successful verification, logging a unique disclosure session ID and the proven criteria. This on-chain record provides an immutable audit trail for regulators or issuers, while the proof itself reveals nothing about the prover's identity.

For security token platforms, this contract acts as a gatekeeper for permissioned actions. You can integrate it with a token transfer manager or a whitelist contract. For example, before allowing a transfer to a new wallet, the system could require the recipient to submit a valid proof of accreditation. The verifier contract checks the proof, and if valid, the whitelist contract updates its state to permit the transaction. This creates a compliant, privacy-preserving onboarding flow.

Testing is critical. Write comprehensive unit tests that simulate both valid and invalid proof submissions. Use a local development chain like Hardhat Network and pre-calculated proof data from your circuit. Test edge cases, such as expired credentials or tampered public signals, to ensure the contract rejects them. Remember, the trust model shifts: you are trusting the correctness of the cryptographic circuit and the security of the prover's secret data, not the contract to keep data private.

step-3-holder-proof-generation
SELECTIVE DISCLOSURE

Step 3: Generate Proofs from the Holder's Wallet

This step details how a security token holder uses their wallet to generate zero-knowledge proofs, enabling them to prove specific claims about their holdings without revealing the underlying data.

After a holder's credentials are issued and stored in their digital wallet (like MetaMask or a specialized custody solution), they can initiate a selective disclosure request. This typically occurs when interacting with a dApp or service that requires proof of eligibility, such as a token-gated platform or a compliance check. The holder's wallet, acting as a holder agent, uses the stored Verifiable Credential (VC) to generate a Verifiable Presentation (VP). This VP contains the ZK proof, which cryptographically asserts the required claim—for example, "I am an accredited investor" or "I hold more than X tokens"—while keeping the exact balance or credential details private.

The generation process leverages a zk-SNARK or zk-STARK proving system. The wallet executes a proving key, often provided by the issuer or a trusted setup, to create the proof. For a claim like balance > 1000, the proof demonstrates the holder knows a secret (their private key) that corresponds to a public on-chain address with a balance satisfying the condition, without revealing the address or the precise amount. This is computationally intensive but handled client-side by libraries like SnarkJS (for Circom circuits) or Arkworks (for R1CS). The output is a small, verifiable proof string.

From a developer's perspective, integrating this into a wallet or dApp involves calling the proving function. For a Circom circuit compiled with circom, the code snippet might look like this:

javascript
const { proof, publicSignals } = await snarkjs.groth16.fullProve(
  { privateBalance: holderBalance, threshold: 1000 }, // Private inputs
  "./circuit_wasm/circuit.wasm",                     // Compiled circuit
  "./proving_key.zkey"                               // Proving key
);

The holderBalance is a private input known only to the wallet, and the threshold is the public condition. The resulting proof and publicSignals (like the statement "balance > 1000 is true") form the VP.

This step is critical for privacy-preserving DeFi and regulatory compliance. It allows holders to participate in activities like over-collateralized lending without exposing their total portfolio, or prove jurisdiction-specific accreditation to a regulator. The security model assumes the wallet safeguards the private keys and the original VC; a compromised wallet could lead to false proof generation. Therefore, using hardware wallets or MPC (Multi-Party Computation) custody for high-value security tokens is recommended.

Finally, the generated Verifiable Presentation, containing the ZK proof, is sent to the verifier (e.g., the dApp's smart contract or backend). The next step involves the verifier validating this proof on-chain or off-chain using a corresponding verification key. This completes the holder's role in the flow, enabling trustless verification of selective attributes derived from their security token holdings.

step-4-integrate-with-token-contract
IMPLEMENTATION

Step 4: Integrate Disclosure with Token Transfer Logic

This step links the disclosure verification system to the token's core transfer function, enforcing compliance before ownership changes.

The core of a compliant security token is a transfer function that checks the recipient's accreditation status. Instead of a simple ERC-20 transfer, you implement a conditional transfer that calls your disclosure verification logic. This creates a programmatic gate that prevents non-compliant transfers at the smart contract level, which is more secure and reliable than off-chain checks. The typical pattern is to override the standard _beforeTokenTransfer hook found in OpenZeppelin's contracts or to create a custom safeTransfer function.

Your integration logic must query the on-chain registry or verification contract you built in the previous step. For example, if you're using a DisclosureRegistry contract, the transfer function would call registry.isVerified(recipient, disclosureId) before proceeding. If the check fails, the transaction should revert with a clear error like "RecipientNotVerified". It's critical to also handle transfer restrictions for specific jurisdictions or investor types, which may require checking additional attributes stored in the verifiable credential.

Consider gas optimization and user experience. Performing on-chain checks for every transfer adds cost. A common optimization is to issue an approval token (a non-transferable NFT or a permit) upon successful disclosure verification. The main transfer function then only needs to check for the presence of this approval token, which is a cheaper SLOAD operation. This pattern separates the expensive verification step from the frequent transfer action.

Always include override functions for the issuer. The compliance officer or token issuer must retain the ability to force-transfer tokens in edge cases, such as legal seizures, court orders, or to rectify errors. These functions should be protected by a multi-signature wallet or a DAO vote and should emit events for full auditability. This ensures the system remains compliant even when automated checks fail.

Finally, thoroughly test the integrated logic. Write tests that simulate: a successful transfer to a verified investor, a blocked transfer to an unverified address, the use of an approval token, and an admin override. Tools like Hardhat or Foundry are essential for this. This step binds your disclosure framework to the token's immutable economics, ensuring lasting regulatory compliance.

SELECTIVE DISCLOSURE

Frequently Asked Questions

Common technical questions and troubleshooting for implementing selective disclosure of on-chain data for security token holders.

Selective disclosure is a privacy-preserving technique that allows a token holder to cryptographically prove specific claims about their on-chain data (like token holdings or transaction history) without revealing the underlying data itself. For security tokens, this is critical for regulatory compliance (like KYC/AML) and institutional adoption.

Key reasons include:

  • Regulatory Compliance: Proving accredited investor status or jurisdiction without exposing personal wallet addresses.
  • Commercial Confidentiality: Large holders can prove ownership for governance or rewards without revealing their full position size.
  • Sybil Resistance: Applications can verify a user holds a minimum token balance to access features without tracking their total wealth.

Technically, this is achieved using zero-knowledge proofs (ZKPs) or digital signatures over verifiable credentials, allowing proofs to be verified against a public registry or smart contract state.

conclusion-next-steps
IMPLEMENTATION SUMMARY

Conclusion and Next Steps

You have successfully configured a system for selective disclosure, enabling token holders to prove specific credentials without revealing their entire identity.

The core mechanism you've implemented uses zero-knowledge proofs (ZKPs) and verifiable credentials (VCs). By leveraging a Soulbound Token (SBT) as a persistent, non-transferable identifier, you anchor a user's claims to their wallet. The Verifier smart contract acts as the trust anchor, checking the validity of ZK proofs against a predefined set of rules, such as proving a user holds a token from a specific SecurityToken contract without disclosing their balance or address. This architecture provides privacy-preserving verification for KYC status, accredited investor checks, or jurisdictional compliance.

For production deployment, several critical steps remain. First, audit your smart contracts, especially the cryptographic verification logic in the Verifier. Use services like CertiK or OpenZeppelin. Second, integrate a secure off-chain prover system. For developers, the SnarkJS library is essential for generating ZK proofs in a Node.js backend. Your API endpoint must securely fetch the user's VCs, generate the proof, and return it to the dApp frontend, ensuring private keys never leave the user's custody.

Consider these advanced patterns to enhance your system. Implement revocation registries using smart contracts or indexed events to invalidate credentials if a user's status changes. Explore schema flexibility by allowing the Verifier logic to validate multiple types of claims from a single SBT. For user experience, design clear frontend flows using SDKs like eth-zkp-credentials to abstract proof generation. Finally, monitor gas costs; while verification is cheap, proof generation off-chain is computationally intensive and may require optimized circuits.

The next evolution is interoperability. Your selective disclosure system can become a reusable primitive across DeFi, DAO governance, and real-world asset platforms. Look towards adopting emerging standards like EIP-7121 for low-gas signature verification of VCs or integrating with cross-chain attestation protocols like Ethereum Attestation Service (EAS) to make credentials portable across multiple networks. Start by testing on a testnet with real user flows before a mainnet launch.

How to Implement Selective Disclosure for Security Tokens | ChainScore Guides