Skip to main content

NullifierRegistry

An append-only registry of spent nullifiers. Prevents double-reveals — each commitment can only be revealed once.

Address: 0x0987cc3dE6f76c4c8834Dc6205De24968091C58b

How nullifiers work

A nullifier is derived from the user's nullifierSecret and the leaf's position in the Merkle tree:

nullifier = Poseidon2(nullifierSecret, leafIndex)

Since nullifierSecret is private, no observer can determine which commitment a nullifier corresponds to. But if the same commitment is revealed twice, it would produce the same nullifier, which the registry rejects.

Key functions

// Check if a nullifier has been spent
function isSpent(bytes32 nullifier) external view returns (bool);

// Register a nullifier (only callable by vault)
function spend(bytes32 nullifier) external;

Usage examples

# Check if a nullifier is spent
cast call 0x0987cc3dE6f76c4c8834Dc6205De24968091C58b \
"isSpent(bytes32)(bool)" $NULLIFIER \
--rpc-url https://testnet.specterchain.com

Events

event NullifierSpent(bytes32 indexed nullifier);