A demonstration of verifying Noir circuit proofs within Aztec smart contracts using the UltraHonk proving system. This project showcases how to generate zero-knowledge proofs off-chain with Noir and verify them on-chain in an Aztec private smart contract.
This project implements:
- Noir Circuit: A simple circuit that proves two field elements are not equal (x ≠ y)
- Aztec Contract: A private smart contract that verifies Noir proofs and maintains a counter
- Proof Generation: Scripts to generate UltraHonk proofs using Barretenberg
- On-chain Verification: Deployment and interaction scripts for proof verification on Aztec
Aztec Version: 4.2.0-aztecnr-rc.2
- Node.js (v22 or higher) and Yarn
- Aztec CLI (version 4.2.0-aztecnr-rc.2)
- Nargo (version 1.0.0-beta.18) - bundled with the Aztec CLI at
~/.aztec/current/bin/nargo - Linux/macOS (Windows users can use WSL2)
- 8GB+ RAM recommended for proof generation
.
├── circuit/ # Noir circuit that generates proofs
│ ├── src/main.nr # Circuit logic: proves x ≠ y
│ └── Nargo.toml # Circuit configuration
├── contract/ # Aztec smart contract
│ ├── src/main.nr # Contract that verifies Noir proofs
│ ├── artifacts/ # Generated TypeScript bindings
│ └── Nargo.toml # Contract configuration
├── scripts/ # TypeScript utilities
│ ├── generate_data.ts # Generates proof, VK, and public inputs
│ └── run_recursion.ts # Deploys contract and verifies proof
├── tests/ # Integration tests
│ └── recursive_verification.test.ts # Comprehensive test suite
├── CLAUDE.md # Instructions for Claude AI assistants
├── EXPLAINER.md # Detailed technical explanation of the project
├── package.json # Node.js package configuration
├── tsconfig.json # TypeScript configuration
├── data.json # Generated proof data (created by `yarn data`)
└── run-tests.sh # Local test runner script
yarn installbash -i <(curl -s https://install.aztec.network)aztec-up 4.2.0-aztecnr-rc.2This ensures compatibility with the contract dependencies.
The compatible nargo (version 1.0.0-beta.18) is bundled with the Aztec CLI:
~/.aztec/current/bin/nargo --version
# nargo version = 1.0.0-beta.18Ensure ~/.aztec/current/bin is on your PATH (the Aztec installer adds this automatically).
cd circuit && nargo compileThis compiles circuit/src/main.nr and generates target/hello_circuit.json containing the circuit bytecode.
cd circuit && nargo executeGenerates a witness for testing the circuit with default inputs (defined in circuit/Prover.toml).
yarn cccThis command:
- Compiles the Aztec contract (
contract/src/main.nr) - Post-processes for Aztec deployment
- Generates TypeScript bindings in
contract/artifacts/
Generate the verification key, proof, and public inputs:
yarn dataThis runs scripts/generate_data.ts which:
- Executes the circuit with inputs x=1, y=2
- Generates an UltraHonk proof using Barretenberg
- Saves proof data to
data.json(508 field elements for proof, 115 for VK)
Start the local Aztec network:
aztec start --local-networkKeep this running in a separate terminal. The local network runs at http://localhost:8080.
yarn recursionThis runs scripts/run_recursion.ts which:
- Connects to the Aztec PXE (Private eXecution Environment)
- Deploys the
ValueNotEqualcontract - Submits the proof from
data.jsonfor on-chain verification - Increments the counter if verification succeeds
- Displays the final counter value
Expected output:
Contract Deployed at address 0x...
Tx hash: 0x...
Counter value: 11
For a fresh setup, run these commands in order:
# 1. Install dependencies
yarn install
# 2. Setup Aztec
aztec-up 4.2.0-aztecnr-rc.2
# 3. Verify nargo is available (bundled with Aztec CLI)
~/.aztec/current/bin/nargo --version
# 4. Compile circuit
cd circuit && nargo compile && cd ..
# 5. Compile contract
yarn ccc
# 6. Generate proof data
yarn data
# 7. Start local network (in a new terminal)
aztec start --local-network
# 8. Deploy and verify (in original terminal)
yarn recursionThe project includes a comprehensive test suite for contract deployment and proof verification:
# Run all tests
yarn test
# Run tests in watch mode for development
yarn test:watch
# Run full test suite locally (includes compilation)
./run-tests.shcd circuit && nargo testThis runs the tests defined in circuit/src/main.nr. The test verifies that the circuit correctly proves x ≠ y.
The test suite (tests/recursive_verification.test.ts) includes:
- Contract deployment verification
- Proof verification and counter increment tests
- Multi-user counter management
- Multiple proof verification rounds
-
"Cannot find module './contract/artifacts/ValueNotEqual'"
- Run
yarn cccto generate the contract artifacts
- Run
-
"Cannot find module './data.json'"
- Run
yarn datato generate the proof data
- Run
-
"Failed to connect to PXE"
- Ensure the Aztec local network is running:
aztec start --local-network - Check it's accessible at
http://localhost:8080
- Ensure the Aztec local network is running:
-
"Proof verification failed"
- Ensure you've run
yarn dataafter any circuit changes - Verify the circuit was compiled with
cd circuit && nargo compile
- Ensure you've run
-
Memory issues during proof generation
- The Barretenberg prover requires significant RAM
- Close other applications or use a machine with more memory
-
TypeScript/Linting errors with TxStatus
- Ensure you're importing
TxStatusfrom@aztec/aztec.js - Use
TxStatus.SUCCESSinstead of string literal"success"
- Ensure you're importing
If you encounter issues, try a clean rebuild:
# Remove generated files
rm -rf circuit/target contract/target contract/artifacts data.json
# Rebuild everything
cd circuit && nargo compile && cd ..
yarn ccc
yarn data- Circuit: The Noir circuit in
circuit/src/main.nrcreates a zero-knowledge proof that two values are not equal - Proof Generation: Barretenberg generates an UltraHonk proof from the circuit execution
- Contract: The Aztec contract uses
bb_proof_verification::verify_honk_proofto verify the proof on-chain - VK Hash Storage: The verification key hash is stored in contract storage during initialization and read during proof verification
- Counter Management: The contract maintains public counters per user using
PublicMutablestorage
yarn ccc: Compile contract and generate TypeScript artifactsyarn data: Generate proof data (verification key, proof, public inputs)yarn recursion: Deploy contract and verify proof on-chainyarn test: Run integration test suiteyarn test:watch: Run tests in watch mode for development./run-tests.sh: Run full test suite locally (includes compilation)
h/t @satyambnsal for the initial implementation.