Merkle Tree
Position in the stack: Sits inside the Shielding Layer and interacts directly with the Smart Contract Infrastructure.
Purpose
Efficient membership proofs – Users prove a note exists in the shielded set without revealing which note it is.
Compact state – A single 32‑byte Merkle root represents millions of shielded notes, keeping onchain storage minimal.
Incremental privacy – Every new deposit grows the anonymity set, the Merkle root captures that growth in one hash.
How It Works in Veilon
Deposit → Commitment
When you shield assets, Veilon creates a note commitment (a hash of value + owner + randomness).
Commitment → Merkle Leaf
The commitment becomes a leaf in Veilon’s incremental Merkle tree stored onchain.
Tree → Root
After the leaf is inserted, smart contracts update the Merkle root. This root is the only piece the zk‑SNARK circuit needs.
Spend → zk Proof
To spend privately, you submit a zk proof that:
Knows a path from your leaf to the current root (membership).
Has a nullifier so the same note can’t be spent twice.
Reveals nothing about which leaf you used.
function verifyMerkleProof(
bytes32 leaf,
bytes32[] memory proof,
uint256 index
) public view returns (bool) {
bytes32 hash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
if ((index >> i) & 1 == 1) {
hash = keccak256(abi.encodePacked(proof[i], hash));
} else {
hash = keccak256(abi.encodePacked(hash, proof[i]));
}
}
return hash == currentMerkleRoot;
}Last updated

