Finish Withdraw

An essential guide to Finalizing the ZK-Mixer Withdraw Function - Learn to implement critical ZK-Mixer withdrawal steps in Solidity: verifying proofs, using low-level calls for fund transfers, and emitting events. This lesson details crafting public inputs for the Verifier contract and implementing robust custom error handling.

1. Introduction
A capstone immersion into Welcome to Our Final Chapter: Advanced Noir Privacy Protocols - Apply your accumulated Noir expertise to construct a sophisticated multi-component privacy mixer. This concluding lesson explores Merkle Trees and commitments, and analyzes Tornado Cash to lay the groundwork for your project. Duration: 2min
2. Disclaimer
A crucial clarification of Foundational Concepts: Disclaimer, Attribution, and Proof Terminology - This lesson details the educational-only intent and legal responsibilities, acknowledges Tornado Cash Core code origins with proper attribution, and clearly distinguishes "proof" (ZK proof) from "Merkle proof." These points provide essential context and accurate understanding for subsequent material. Duration: 2min
3. Tornado Cash
A cryptographic key to Unveiling Tornado Cash: Enhancing Privacy on Transparent Blockchains - Unlock the workings of Tornado Cash, a protocol for private transactions on public ledgers. Discover its operational flow from deposit to withdrawal, and the ZKPs, Merkle trees, and nullifiers that safeguard anonymity. Duration: 20min
4. Creating The Mixer Smart Contract
A foundational introduction to Initializing Your ZK Mixer Project with Foundry - Begin building your ZK Mixer by setting up the project environment with Foundry and creating the initial `Mixer.sol` smart contract. This lesson guides you through implementing the `deposit` function and outlines the design for the `withdraw` function, incorporating ZK proof verification and Merkle tree concepts. Duration: 12min
5. Incremental Merkle Trees
A crucial dive into Understanding Incremental Merkle Trees - Discover how IMTs tackle the challenge of efficient on-chain updates, outperforming standard Merkle trees for dynamic data. This lesson covers their fixed-depth structure, zero-value pre-population, and caching strategies for optimized blockchain interactions. Duration: 17min
6. Creating The IMT Contract
An in-depth look at On-Chain Incremental Merkle Tree Setup - Transition your ZK-Mixer from simple commitment mappings to a powerful Incremental Merkle Tree (IMT) for enhanced data management. Master the initial steps: creating `IncrementalMerkleTree.sol`, defining the `_insert` stub, and setting/validating tree depth with custom errors. Duration: 4min
7. Zero Subtrees
An essential guide to Pre-computing Zero Subtree Hashes for Incremental Merkle Trees - Master the off-chain calculation of zero subtree hashes (`zeros[i]`) using Poseidon, crucial for initializing gas-efficient Incremental Merkle Trees. Implement these pre-computed values directly into your Solidity `zeros` function to represent empty tree states. Duration: 9min
8. Inserting A Leaf
An in-depth guide to Implementing `_insert` for Efficient Incremental Merkle Tree Updates in Solidity - Delve into the core logic of the `_insert` function for adding new leaves sequentially to an Incremental Merkle Tree in Solidity. Unpack the process of iterative hashing, efficient caching of subtree hashes, and using zero hashes to correctly update the tree's root. Duration: 13min
9. Finishing Deposit
A constructive guide to Finalizing the Merkle Tree Insertion Logic - Master the completion of the Merkle tree's `_insert` function, covering new root storage and leaf index handling. See this logic integrated into the Mixer contract, enabling the `deposit` function and event emission for off-chain tree reconstruction. Duration: 5min
10. Nullifier Hash
A crucial look into Understanding Nullifier Hashes in ZK Mixer Withdrawals - Uncover why nullifier hashes are vital for private ZK Mixer withdrawals and robust double-spend prevention. Learn their ZK-friendly generation, on-chain verification steps, and how they secure anonymous transactions with ZK proofs. Duration: 6min
11. Circuit Inputs
A focused examination of Defining ZK Circuit Inputs for a ZK-Mixer Deposit Proof - Pinpoint the exact data, from prover-known secrets (secret, nullifier, Merkle path) to publicly verifiable anchors (root, nullifier hash), for your ZK-SNARK deposit proof circuit. This lesson clarifies their distinct roles in asserting deposit legitimacy, safeguarding anonymity, and enabling unique withdrawals in a ZK-mixer. Duration: 3min
12. Circuit Logic
A constructive walkthrough of Setting Up Your ZK-Mixer Circuit Environment - Build the foundation for your ZK-Mixer by initializing a new Noir project and defining the main circuit's function signature with public and private inputs. This lesson guides you through implementing essential privacy logic, including commitment generation, nullifier verification, Merkle proof validation, and front-running prevention. Duration: 15min
13. Generate Verifier
A foundational breakdown of Generating a Solidity Verifier for Your ZK Circuit with Nargo and Barretenberg - Step through compiling Noir circuits with Nargo and using Barretenberg to produce both verification keys and the crucial `Verifier.sol` contract. This lesson paves the way for deploying smart contracts that verify zero-knowledge proofs directly on the blockchain. Duration: 2min
14. Finish Withdraw
An essential guide to Finalizing the ZK-Mixer Withdraw Function - Learn to implement critical ZK-Mixer withdrawal steps in Solidity: verifying proofs, using low-level calls for fund transfers, and emitting events. This lesson details crafting public inputs for the Verifier contract and implementing robust custom error handling. Duration: 3min
15. Historical Roots
An essential deep-dive into Mitigating Stale Proofs in ZK-Mixers with Historical Merkle Roots - Understand why 'stale Merkle roots' cause issues in ZK-mixers and how implementing a historical root buffer offers a robust fix. This lesson walks through modifying contracts like `IncrementalMerkleTree.sol` and `Mixer.sol` to improve transaction reliability and user experience. Duration: 9min
16. Mid Way Summary
An essential deep dive into zk-Mixer Withdrawals: Solidity Logic and Noir Circuitry - Uncover the step-by-step execution of the `withdraw` function in `Mixer.sol`, from initial Merkle root checks to final fund disbursal and event emission. This lesson further deciphers the companion ZK-SNARK circuit in Noir, vital for preparing a comprehensive testing strategy. Duration: 5min
17. Building The Project
A practical troubleshooting guide to Compiling Your Solidity Project with `forge build` - Learn to compile your Solidity smart contracts using `forge build` and effectively diagnose common issues encountered during the process. This lesson provides step-by-step fixes for errors, from syntax to type conversions, enhancing your Solidity debugging skills. Duration: 1min
18. Setting Up The Tests
An essential primer on Setting Up Foundry Tests for a zk-SNARK Mixer Contract - Get started by creating your test file, importing key contracts such as the Mixer and Verifier, and initializing state variables. This lesson also covers utilizing Foundry's `setUp` function and its Foreign Function Interface (FFI) for generating zk-SNARK commitments. Duration: 5min
19. Generate The Commitment
An illuminating guide to Bridging Off-Chain Logic with On-Chain Tests: An Overview of Foundry FFI - Discover how to enhance Solidity testing by integrating off-chain TypeScript computations using Foundry's Foreign Function Interface (FFI). This lesson walks through creating a TypeScript commitment generator and calling it from your smart contract tests for robust validation. Duration: 11min
20. Testing Making A Deposit
A crucial first step into Crafting Your First ZK-Mixer Test: Verifying Deposits - Discover how to write the initial Foundry test for a ZK-Mixer's `deposit` function, covering Ether transactions in tests and event verification with `vm.expectEmit`. This lesson also prepares the groundwork for withdrawal testing by modifying data handling in helper functions and associated scripts. Duration: 7min
21. Creating The Proof Helper Function
A detailed introduction to Generating Zero-Knowledge Proofs Off-Chain: The `_getProof` Solidity Helper - Discover how to construct the `_getProof` Solidity function, leveraging Foundry's FFI to call external scripts for efficient off-chain ZK proof generation. This lesson explains the preparation of inputs like Merkle tree leaves and private user data, and the process of invoking the external script. Duration: 5min
22. Generate Proof Script
An essential walkthrough of Crafting a `generateProof.ts` Script for Your ZK-Mixer - Learn to develop a TypeScript script for generating ZK proofs in a ZK-Mixer, from Noir circuit interaction to CLI input handling. This lesson covers key cryptographic operations with Barretenberg, Merkle tree data preparation, and ABI-encoding proofs for Ethereum. Duration: 21min
23. Finish Withdraw Test
A capstone guide to Implementing and Testing Private Withdrawals in a zk-SNARK Mixer with Foundry - Master the final steps of developing and validating private withdrawals in a zk-SNARK mixer with Foundry, focusing on incorporating public inputs for proof generation. This lesson details Solidity and JavaScript modifications for a secure, private transaction flow. Duration: 5min
24. Reentrancy
A critical deep dive into Securing Mixer.sol: Understanding Reentrancy and Implementing Guards - Explore the reentrancy vulnerability in the `Mixer.sol` contract's `withdraw` function and the preventative Checks-Effects-Interactions pattern. This lesson guides you through integrating OpenZeppelin's `ReentrancyGuard` for robust contract protection. Duration: 4min
25. Unused Circuit Inputs
A crucial investigation into Optimizing ZK-Proofs: Do Unused Public Inputs Need Dummy Calculations in Noir? - Uncover whether Noir requires the 'dummy calculation' pattern common in Circom for public input security, through a ZK-Mixer case study. This lesson demonstrates that Noir's `pub` keyword inherently secures these inputs, streamlining circuit design and potentially reducing costs. Duration: 5min
26. NATSPEC
A vital guide to Mastering Smart Contract Documentation: A Guide to NatSpec for ZK-Mixer Projects - Master writing comprehensive NatSpec comments for Solidity smart contracts, focusing on ZK-Mixer project applications. This lesson covers essential tags and best practices to ensure your code is clear, maintainable, and provides crucial ZK context. Duration: 4min
27. Summary
An insightful walkthrough of Understanding and Building a ZK Mixer Protocol for Enhanced On-Chain Privacy - Discover how to build a ZK mixer protocol leveraging commitment schemes, Merkle trees, and zero-knowledge proofs to significantly enhance on-chain privacy. This lesson covers the core cryptographic mechanisms, smart contract development in Solidity, and off-chain scripting for proof generation using Noir. Duration: 4min

Course Overview

About the course

What you'll learn

Noir syntax

Create a witness, a proof, and Solidity verifier contracts

Use the Poseidon commitment scheme

Create ZK circuits and build a full ZK protocol

ZK Merkle trees and hashing in Noir

Verify signatures without revealing the signer

Build the backend for a full-stack ZK application with noir.js and bb.js

How to create proofs and verify them in a front-end

Course Description

Who is this course for?

  • Software engineers
  • Solutions Architects
  • ZK Engineers
  • ZK Smart Contract Developers
  • Web3 Developers

Meet your instructors

Ciara Nightingale

Ciara Nightingale

Developer relations at Cyfrin

Last updated on June 12, 2025