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

How to Architect a Private Sale with Zero-Knowledge Proofs

A technical guide for developers on designing a private fundraising smart contract that uses ZK proofs to conceal investor contributions and allocations while enabling on-chain verification.
Chainscore © 2026
introduction
GUIDE

How to Architect a Private Sale with Zero-Knowledge Proofs

A technical guide to designing a fundraising mechanism that protects investor identity and allocation details using zk-SNARKs and zk-STARKs.

Traditional private sales on public blockchains like Ethereum expose sensitive investor data, including wallet addresses and token allocation amounts, to competitors and malicious actors. A privacy-preserving private sale uses zero-knowledge proofs (ZKPs) to cryptographically verify that a fundraising event occurred correctly without revealing the underlying transaction details. This architecture typically involves a commitment scheme where investors deposit funds, a zk-SNARK circuit that validates the sale rules, and a verification contract that mints tokens based on a valid proof.

The core component is the zk-SNARK circuit, written in a domain-specific language like Circom or Noir. This circuit encodes the business logic of the sale: it proves that a user's contribution is within the allowed limits, that the total raised does not exceed the cap, and that the user is on a verified allowlist—all without revealing which user submitted the proof or their specific contribution amount. The circuit's public inputs might only include the total funds raised and a Merkle root of the allowlist, while the private inputs (the user's identity and contribution) remain hidden.

A practical implementation involves several steps. First, the project generates a trusted setup (or uses a perpetual one like the one for Tornado Cash) to create the proving and verification keys for the circuit. Investors then interact with a commitment contract, locking their funds and generating a secret nullifier. Off-chain, they use a prover to generate a zk-SNARK proof attesting their eligibility. Finally, they submit this proof to a verifier contract, which checks it against the verification key and, if valid, mints the corresponding private sale tokens to a fresh, unlinked address provided by the investor.

Key design considerations include privacy vs. compliance. While the on-chain flow is private, an off-chain attestation system can be used for KYC/AML, where a licensed entity issues a signed credential that becomes a private input to the circuit. Another challenge is denial-of-service (DoS) protection; the verifier contract must be designed to prevent spam by requiring a proof of work or a fee. Projects like Aztec Network and zk.money offer frameworks and rollups that can simplify the development of such private applications.

For developers, the stack involves a zk-SNARK library (e.g., snarkjs with Circom), a smart contract framework like Hardhat, and a front-end for proof generation. The gas cost is primarily for the verifier contract, which is a one-time cost per investor. This architecture provides strong privacy guarantees but introduces complexity in user experience for proof generation. The future lies in zk-rollup-based private sales, where the entire logic executes in a private VM, offering scalability and deeper privacy.

prerequisites
FOUNDATIONS

Prerequisites and Required Knowledge

Architecting a private sale with zero-knowledge proofs requires a solid foundation in blockchain development, cryptography, and smart contract security. This guide outlines the essential concepts and tools you need to understand before proceeding.

To build a private sale using zero-knowledge proofs (ZKPs), you must first be comfortable with core blockchain concepts. This includes a working knowledge of Ethereum or similar EVM-compatible networks, as they are the primary platforms for deploying such systems. You should understand how smart contracts function, how transactions are signed and broadcast, and the basics of gas fees and transaction lifecycle. Familiarity with a development framework like Hardhat or Foundry is essential for writing, testing, and deploying your contracts. This foundational layer is non-negotiable for implementing any on-chain logic securely.

A deep understanding of cryptographic primitives is the cornerstone of ZKP systems. You need to grasp the concepts behind hash functions (like Keccak-256), digital signatures (ECDSA), and public-key cryptography. For zero-knowledge proofs specifically, you must understand the trust model: a prover convinces a verifier that a statement is true without revealing the underlying secret data. Key terms include witness (the private input), statement (the public claim), and circuit (the set of constraints defining the computation). Start with resources like the Zcash protocol specification for a rigorous introduction.

You will be writing circuits that define the rules of your private sale. This requires learning a domain-specific language (DSL) for ZKPs. Circom is the most popular choice for writing arithmetic circuits, which are then compiled into R1CS (Rank-1 Constraint System) format. An alternative is Noir, a higher-level language. You must understand how to use these tools to create a circuit that validates a user's eligibility—for example, checking a Merkle proof of inclusion in an allowlist or verifying a signature from a trusted entity—all without revealing the user's specific identity or proof details on-chain.

The on-chain component requires a verifier smart contract. This contract does not perform the complex proof verification itself; instead, it contains the verification key and uses a pre-compiled verification library (like the snarkjs generated Solidity code or a gnark backend) to check the proof's validity. You must learn how to generate this verification key from your circuit, integrate the verifier contract into your sale architecture, and handle the state transition (e.g., minting a token or recording participation) only upon successful proof verification. Security audits for both the circuit logic and the verifier integration are critical.

Finally, consider the user experience and system design. You'll need a backend prover service (or a client-side tool) to generate the ZK proof for eligible users. This involves managing trusted setup parameters (like the ptau ceremony files for Groth16) and ensuring the proving process is efficient and accessible. You should also plan for the data availability of your public inputs (like the Merkle root of the allowlist) and understand the trade-offs between different proof systems (Groth16, PLONK, STARKs) in terms of proof size, verification cost, and setup requirements.

system-architecture-overview
SYSTEM ARCHITECTURE OVERVIEW

How to Architect a Private Sale with Zero-Knowledge Proofs

This guide outlines the core components and data flow for building a private token sale system that uses zero-knowledge proofs to verify eligibility without revealing sensitive investor data.

A private sale with ZK proofs is a multi-party system designed to enforce access control and regulatory compliance while preserving privacy. The architecture typically involves three main actors: the issuer (project team), the investor, and a verifier (often a smart contract). The core innovation is the use of a zero-knowledge Succinct Non-interactive Argument of Knowledge (zk-SNARK) or similar proof system. This allows an investor to cryptographically prove they possess specific credentials—like accreditation status or KYC completion—without disclosing the underlying documents or personal details to the blockchain or the public.

The system's data flow begins off-chain. The issuer defines the eligibility criteria and works with a trusted entity to issue verifiable credentials (VCs) or attestations to approved investors. These credentials are signed cryptographic statements stored privately by the investor. When the sale opens, the investor uses a prover client (e.g., a web app with SnarkJS or Circom) to generate a zk-proof. This proof demonstrates that their private credentials satisfy the public sale rules, and it can also cryptographically link to a specific public commitment (like a nullifier) to prevent double-spending of the allocation.

On-chain, the issuer deploys a verifier smart contract containing the public parameters and the logic of the eligibility circuit. The investor submits only the zk-proof and the public outputs (e.g., a nullifier hash and their public Ethereum address) to this contract. The verifier contract checks the proof's validity. If it passes, the contract executes the sale logic—minting tokens, transferring funds, or registering the commitment—all without ever seeing the investor's private data. This architecture shifts the trust from the issuer's database to cryptographic verification.

Key technical considerations include selecting a proof system (Groth16, PLONK, Halo2), designing the circuit logic in a domain-specific language like Circom or Noir, and managing trusted setup ceremonies for certain SNARKs. The circuit is the program that encodes the eligibility rules; for example, it could verify a signature on a credential and check that a birthdate field within it confirms the investor is over 18. The system must also handle revocation of credentials and manage the nullifier set on-chain to prevent reuse.

In practice, projects like Aztec Network and zkSync have pioneered private transactions, and frameworks like Semaphore offer libraries for anonymous signaling. When architecting your sale, you must decide on the custody model (non-custodial proofs vs. issuer-held credentials), the user experience for proof generation, and gas cost optimization for the verifier contract. The end result is a compliant, trust-minimized fundraising mechanism that offers stronger privacy guarantees than traditional whitelists or transparent KYC hashes on-chain.

zk-circuit-design
ARCHITECTURE GUIDE

Designing the ZK Circuit for Private Contributions

A technical guide to building a zero-knowledge proof system for private token sales, covering circuit design, privacy guarantees, and implementation tools.

01

Circuit Logic for Contribution Proofs

The core circuit logic verifies a user's eligibility and contribution amount without revealing their identity. Key components include:

  • Commitment Scheme: A Pedersen commitment or Poseidon hash to lock the user's address and amount.
  • Range Proofs: Using tools like Bulletproofs or Plookup to prove the contribution is within a valid, non-negative range (e.g., 0.1 to 100 ETH) without disclosing the exact figure.
  • Merkle Tree Membership: Proving the user's address is in a whitelist Merkle tree, where only the root is public. The circuit's public outputs are the new Merkle root and a nullifier to prevent double-spending, while all user inputs remain private.
03

Implementing the Trusted Setup

A Perpetual Powers of Tau (PPoT) ceremony or a project-specific trusted setup is required for most proving systems.

  • Use Existing Ceremonies: For Groth16, leverage the completed Phase 1 PPoT ceremony (over 100 contributors). For PLONK, use the universal setup from Aztec or others.
  • Circuit-Specific Phase 2: After Phase 1, you must run a Phase 2 ceremony for your specific circuit. This generates the proving and verification keys. Tools like snarkjs or rapidsnark automate this process.
  • Security Consideration: Minimize trust by using a multi-party computation (MPC) ceremony with as many participants as possible. A single compromised participant does not break the system's security.
04

On-Chain Verification & Gas Optimization

Deploying the verifier as a smart contract on Ethereum or L2s like zkSync Era is the final step. Gas costs are the primary constraint.

  • Verifier Contract: This contract, generated from your circuit, contains the verification key and a verifyProof function. It checks the ZK proof's validity.
  • Gas Costs: A simple proof verification can cost 200k-500k gas. Optimize by:
    • Using smaller field sizes (e.g., BN254 curve).
    • Minimizing the number of constraints in your circuit.
    • Deploying on an L2 with native ZK support, like StarkNet or Polygon zkEVM, where verification is cheaper.
  • Integration: The sale contract calls the verifier, and only upon successful verification does it mint tokens or record the commitment.
05

Privacy Leaks & Mitigation Strategies

Poor design can leak information through metadata or system interaction.

  • Timing Attacks: If contributions are processed sequentially, the time between transaction submission and inclusion can reveal activity. Use a commit-reveal scheme or batch contributions.
  • Amount Correlation: If the total raised is public, sophisticated analysis could infer individual amounts from a small pool of contributors. Mitigate by using a privacy pool that mixes funds before the sale.
  • Nullifier Reuse: The nullifier hash must be unique per contribution to prevent double-spending but must not reveal the user's identity. Use a hash of a secret nullifier key and the circuit's public inputs.
  • Front-running: Design the contract so that the proof submission and fund claim are atomic within one transaction.
smart-contract-implementation
SMART CONTRACT IMPLEMENTATION

How to Architect a Private Sale with Zero-Knowledge Proofs

A technical guide to building a private token sale using zk-SNARKs to verify investor eligibility without revealing their identity or the sale terms.

Architecting a private sale with zero-knowledge proofs (ZKPs) involves creating a system where investors can cryptographically prove they are eligible to participate—based on criteria like KYC status or accreditation—without revealing their identity or the specific sale parameters to the public blockchain. The core contract logic uses a zk-SNARK verifier to check a proof submitted by the user. This proof confirms that the user possesses a valid credential (a zkKYC token or similar) issued off-chain by a trusted entity, and that their contribution amount falls within allowed limits, all without exposing any of that underlying data on-chain.

The implementation typically requires two main smart contracts and an off-chain component. First, a Verifier Contract is deployed; this contains the cryptographic verification key and a function like verifyProof that accepts a ZK proof and public inputs. This contract is often generated by zk-SNARK tooling like circom and snarkjs. Second, the main Private Sale Contract holds the sale logic: it accepts contributions, calls the verifier, and mints tokens or records allocations only upon successful proof verification. The off-chain component involves a prover service that allows users to generate their proof locally using their private credential and the sale's public parameters.

Here is a simplified interface for the core sale contract function:

solidity
function commitToSale(
    uint256[] calldata _proof,
    uint256[] calldata _publicInputs,
    uint256 _contributionAmount
) external payable {
    require(verifier.verifyProof(_proof, _publicInputs), "Invalid proof");
    require(msg.value == _contributionAmount, "Incorrect amount");
    // Record commitment
    commitments[msg.sender] = _contributionAmount;
}

The _publicInputs might include a public nullifier (to prevent double-spending the credential) and a hash of the sale's terms, which the prover also cryptographically commits to.

Key design considerations include nullifier sets to prevent reuse of credentials, time-locked revelations if eventual disclosure is needed, and graceful failure modes for the off-chain prover. You must also carefully manage the trust assumptions in the credential issuer and the initial setup (trusted ceremony) for the zk-SNARK circuits. Using frameworks like Semaphore or zkKit can abstract much of the circuit development. The final architecture ensures regulatory compliance is enforced privately, moving sensitive checks off the transparent ledger while maintaining cryptographic assurance for the protocol.

TECHNICAL FOUNDATIONS

ZK Framework Comparison: SNARKs vs. STARKs for Private Sales

A comparison of the two dominant ZK proof systems for implementing privacy in token sales, focusing on developer trade-offs.

Feature / MetricSNARKs (zk-SNARK)STARKs (zk-STARK)Best For Private Sales

Cryptographic Assumptions

Requires a trusted setup ceremony

Relies on collision-resistant hashes (post-quantum secure)

STARKs (no trusted setup)

Proof Size

~288 bytes (Groth16)

~45-200 KB

SNARKs (on-chain verification)

Verification Time

< 10 ms

~10-100 ms

SNARKs (faster verification)

Proof Generation Time

Seconds to minutes

Minutes to hours

SNARKs (faster for simple logic)

Scalability with Circuit Size

Proof time scales linearly

Proof time scales quasi-linearly (poly-log)

STARKs (large, complex sales)

Recursive Proof Support

Yes (e.g., Plonk, Halo2)

Yes (native support)

STARKs (easier recursion)

Typical Gas Cost for On-Chain Verify

~200k - 500k gas

~2M - 5M+ gas

SNARKs (lower cost)

Primary Development Frameworks

Circom, Halo2, Noir

Cairo, StarkWare SDK

SNARKs (more mature tooling)

compliance-and-auditing-mechanisms
PRIVATE SALE ARCHITECTURE

Compliance and Auditing Mechanisms

Designing a compliant private sale requires balancing investor verification with privacy. Zero-knowledge proofs enable this by allowing participants to prove eligibility without revealing sensitive data.

PRIVATE SALE ARCHITECTURE

Common Implementation Challenges and Solutions

Implementing a private sale with zero-knowledge proofs introduces unique technical hurdles. This guide addresses the most frequent developer questions and pitfalls, from circuit design to on-chain verification.

Large circuit size is often caused by non-optimal constraint system design, which directly impacts prover time and costs. Common culprits include:

  • Inefficient data structures: Using generic arrays instead of Merkle trees for allowlist verification.
  • Overuse of public inputs: Every public input adds to verification cost. Minimize them by using a single public commitment.
  • Complex business logic in-circuit: Move non-essential checks (e.g., timestamp windows) off-chain when possible.

Solution: Use a layered approach. For an allowlist, implement a Merkle tree proof where the leaf is a hash of the buyer's address and allocation. The circuit only needs to verify the Merkle proof and a signature, keeping it under 10,000 constraints. Tools like circom and snarkjs can help analyze and optimize constraint counts.

ZK PRIVATE SALE ARCHITECTURE

Frequently Asked Questions

Common technical questions and troubleshooting for developers implementing private sales with zero-knowledge proofs.

The core primitive is a zk-SNARK (Zero-Knowledge Succinct Non-Interactive Argument of Knowledge). It allows a user to prove they possess a valid credential (like a whitelist token or KYC proof) without revealing the credential itself or their identity. For a private sale, you typically use a Merkle tree commitment. The sale organizer generates a Merkle root from a list of approved addresses and publishes only the root on-chain. Eligible users can then generate a zk-SNARK proof that they know a valid Merkle proof for their address, which is verified by the sale contract. This keeps the full participant list private.

conclusion-next-steps
ARCHITECTURE REVIEW

Conclusion and Next Steps

This guide has outlined the core components for building a private sale using zero-knowledge proofs. The next steps involve finalizing your architecture and exploring advanced optimizations.

You should now have a functional blueprint for a ZK-powered private sale. The core workflow involves: a user generating a zk-SNARK proof locally to attest they hold a valid whitelist credential without revealing it, submitting this proof and a stealth address to your sale contract, and the contract verifying the proof on-chain via a pre-deployed verifier. Funds are then sent to the stealth address, severing the on-chain link between the buyer's public identity and the purchased tokens. This architecture, using tools like Circom for circuit design and the SnarkJS library for proof generation, provides a strong foundation for regulatory compliance and user privacy.

For production, several critical next steps remain. First, rigorously audit your Circom circuit for logical correctness and potential vulnerabilities—a bug here compromises the entire system. Consider using a trusted setup ceremony (like a Powers of Tau) for your final proving key to ensure security. You must also design a robust off-chain credential issuance system; this could be a simple signed message from a secure server or a more complex solution like a Semaphore group membership. Finally, plan for the user experience: provide clear documentation and potentially a CLI tool or web interface to guide users through the proof generation process, which is currently a significant technical hurdle.

To extend this architecture, explore advanced zero-knowledge primitives. zk-SNARKs are used here for their small proof size and fast verification, but zk-STARKs (used by Starknet) offer quantum resistance and no trusted setup, at the cost of larger proof sizes. For sales requiring complex compliance rules (e.g., tiered allocations based on multiple credentials), look into zk-Proof of Innocence techniques or Merkle tree accumulators within your circuit. The field is rapidly evolving with new frameworks like Noir (an embedded ZK DSL) and zkEVM rollups, which could eventually allow the entire sale logic to be executed privately. Start with the simple, verifiable model described here, then iterate as these technologies mature.