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);