Zero-Knowledge Proofs on Rootstock with Noir
Zero-knowledge proofs let a user prove they know something (a secret code, a credential, ownership) without ever revealing the secret itself on Rootstock.
This hands-on tutorial teaches you how to use Noir (a developer-friendly ZK DSL - Domain Specific Language) to build a Secret NFT Club: users get an exclusive membership only by proving they know the secret password, the password never appears on-chain or in the browser console.
What You'll Build
A privacy-preserving membership system where:
- Users prove they know a secret password without revealing it
- The proof is verified on-chain using zero-knowledge cryptography
- Members are able to join the club upon successful verification
- The password never appears in transactions, logs, or browser console
Privacy guarantee: Even if someone inspects all blockchain data, they cannot determine the secret password.
Prerequisites
- Node.js ≥ 18
- Rust (for Noir toolchain)
- MetaMask wallet with tRBTC on Rootstock Testnet (Get tRBTC from Faucet)
- Basic knowledge of Solidity and React/Next.js
🚨 Windows Users: Noir (nargo, bb) isn’t natively supported on Windows. Please install and run Noir inside WSL (Windows Subsystem for Linux) using Ubuntu 24.04.. 🚨
Part 1: Setup & Circuit Development
Step 1: Install Noir (Nargo CLI)
We'll use nargo version = 1.0.0-beta.3.
curl -L https://raw.githubusercontent.com/noir-lang/noirup/refs/heads/main/install | bash
noirup -v 1.0.0-beta.3
Verify installation:
nargo --version
# Should output: nargo version = 1.0.0-beta.3
Step 2: Install Barretenberg Backend
Barretenberg is the proving backend that generates and verifies zero-knowledge proofs. We use it for key operations such as generating proofs, producing and checking verification keys, and generating the verifier smart contract. Without Barretenberg, our dApp wouldn’t be able to let users prove they know the club’s secret code privately, without ever revealing the code itself.
curl -L https://raw.githubusercontent.com/AztecProtocol/aztec-packages/refs/heads/master/barretenberg/bbup/install | bash
bbup -v 0.82.2
Verify:
Make sure to open a new terminal to verify your installation if you get the error bb command not found
bb --version
# Should output: v0.82.2
Step 3: Create the ZK Circuit
Create a new Noir project:
nargo new secret_club
cd secret_club
Replace src/main.nr with this circuit:
use std::hash::pedersen_hash;
fn main(secret: Field, public_hash: pub Field) {
let computed_hash = pedersen_hash([secret]);
assert(computed_hash == public_hash);
}
What this does:
- Takes a
secret(private input - never revealed) - Takes a
public_hash(public input - visible to everyone) - Computes Pedersen hash of the secret
- Asserts they match (proof succeeds only if user knows the correct secret)
Compile the circuit:
nargo compile
This creates target/secret_club.json containing the compiled circuit.
Step 4: Compute the Secret Hash
Critical Step: We need to calculate the Pedersen hash of our secret password before deployment. This hash will be public and stored in the smart contract.