API Reference
GelapShieldedAccount Contract
State Variables
merkleRoot
bytes32 public merkleRootThe current Merkle tree root representing the private state. Updated after each deposit, transaction, or withdrawal.
nullifierUsed
mapping(bytes32 => bool) public nullifierUsedTracks which nullifiers have been consumed to prevent double-spending.
zeroHashes
bytes32[32] public zeroHashesPrecomputed zero hashes for each level of the Merkle tree (0-31).
nextLeafIndex
uint32 public nextLeafIndexThe index for the next available leaf in the Merkle tree. Increments after each deposit.
tree
mapping(uint256 => bytes32) public treeStorage for Merkle tree nodes. Keys are computed using _nodeIndex(level, index).
sp1Verifier
Address of the SP1 verifier contract used to check ZK proofs.
sp1ProgramVKey
The verification key corresponding to the SP1 program.
Public Functions
deposit
depositDeposits ERC20 assets into the shielded pool by inserting a commitment into the Merkle tree.
Parameters:
token: The ERC20 token address being depositedamount: The amount of tokens to transfer from the usercommitment: The 32-byte Pedersen commitment representing the private noteencryptedMemo: Opaque encrypted metadata that the receiver can later decrypt
Requirements:
tokenmust not be the zero addressamountmust be greater than 0Caller must have approved this contract to spend at least
amountoftokenERC20 transfer must succeed
Effects:
Transfers
amountoftokenfrommsg.senderto this contractInserts
commitmentinto the Merkle treeUpdates
merkleRootIncrements
nextLeafIndexEmits
AccountUpdated(commitment, encryptedMemo)
Example:
transact
transactExecutes a private transaction validated via an SP1 ZK proof.
Parameters:
publicInputs: ABI-encodedPublicInputsStructproduced by the SP1 programproofBytes: The raw proof bytes produced by the SP1 prover
Public Inputs Structure:
Requirements:
SP1 proof must be valid for the given
publicInputsAll nullifiers must not have been used before
Effects:
Verifies the ZK proof via
sp1VerifierMarks all
nullifiersas usedUpdates
merkleRoottonewRootEmits
AccountUpdatedfor each new commitmentEmits
TransactionExecuted(newRoot, nullifiers, newCommitments)
Reverts:
If proof verification fails
If any nullifier has already been used ("Nullifier already used")
Example:
withdraw
withdrawWithdraws assets from the shielded pool back to a public EOA using an SP1-verified ZK proof.
Parameters:
publicInputs: ABI-encodedWithdrawPublicInputsStructproduced by SP1proofBytes: The raw ZK proof bytes from the SP1 proverreceiver: The public EOA that will receive the withdrawn funds
Public Inputs Structure:
Requirements:
receivermust not be the zero addressSP1 proof must be valid
receiverargument must matchpublicInputs.receiverAll nullifiers must not have been used before
tokenmust not be the zero addressamountmust be greater than 0Contract must have sufficient token balance
Effects:
Verifies the ZK proof via
sp1VerifierMarks all
nullifiersas usedUpdates
merkleRoottonewRootTransfers
amountoftokentoreceiverEmits
WithdrawExecuted(receiver, token, amount)Emits
AccountUpdatedfor each new commitment (change outputs)
Reverts:
If
receiveris zero address ("Invalid receiver")If proof verification fails
If receiver mismatch ("Receiver mismatch")
If any nullifier already used ("Nullifier already used")
If token is zero address ("Invalid token")
If amount is zero ("Invalid amount")
If token transfer fails ("Token transfer failed")
Example:
Events
AccountUpdated
AccountUpdatedEmitted whenever a new commitment is added to the Merkle tree.
Parameters:
commitment: The inserted Pedersen commitmentencryptedMemo: Encrypted metadata for the receiver wallet (optional, can be empty)
Emitted By:
deposit()- once per deposittransact()- once per new commitmentwithdraw()- once per change commitment
Usage: Wallets and indexers should listen to this event to track new notes and build the Merkle tree state.
TransactionExecuted
TransactionExecutedEmitted whenever a private transaction is executed via SP1.
Parameters:
newRoot: The new Merkle root after applying the transactionnullifiers: The nullifiers consumed by this transactionnewCommitments: The commitments created as outputs
Emitted By:
transact()- once per transaction
Usage: Indexers can use this event to track state transitions and nullifier usage.
WithdrawExecuted
WithdrawExecutedEmitted when a shielded withdrawal is executed.
Parameters:
receiver: The public EOA that received the withdrawn tokenstoken: The ERC20 token that was withdrawnamount: The amount of tokens transferred out
Emitted By:
withdraw()- once per withdrawal
Usage: Track public withdrawals from the shielded pool.
Internal Functions
_initZeroHashes
_initZeroHashesInitializes the zero hash values used for empty Merkle nodes.
Called once during contract construction. Computes:
_nodeIndex
_nodeIndexComputes a compact storage index for a Merkle tree node.
Parameters:
level: The depth of the node in the tree (0-32)index: The index within that level
Returns:
storageKey: A unique key computed as(level << 32) | index
_storeLeaf
_storeLeafStores a leaf node at a given index.
Parameters:
leaf: The commitment hash to storeindex: The leaf index in the tree
_hashPair
_hashPairHashes a pair of Merkle tree nodes using keccak256.
Parameters:
left: The left child hashright: The right child hash
Returns:
The keccak256 hash of the concatenated children
_insertLeaf
_insertLeafInserts a new leaf into the incremental Merkle tree and updates the root.
Parameters:
leaf: The 32-byte commitment being added to the Merkle tree
Returns:
newRoot: The updated Merkle tree root after inserting the leaf
Effects:
Stores the leaf at
nextLeafIndexComputes parent nodes up to the root
Updates
treemapping with new nodesUpdates
merkleRootIncrements
nextLeafIndex
Reverts:
If tree is full (nextLeafIndex >= 2^32) ("Merkle tree full")
Data Structures
PublicInputsStruct
Used for private transactions (transact function).
ABI Encoding:
WithdrawPublicInputsStruct
Used for withdrawals (withdraw function).
ABI Encoding:
Constructor
Parameters:
verifier: Address of the SP1 verifier contractprogramVKey: The verification key for the SP1 program
Effects:
Initializes
zeroHashesarraySets
sp1VerifieraddressSets
sp1ProgramVKey
Example:
Error Messages
"Invalid token"
deposit, withdraw
Token address is zero
"Invalid amount"
deposit, withdraw
Amount is zero
"Token transfer failed"
deposit, withdraw
ERC20 transfer returned false
"Nullifier already used"
transact, withdraw
Attempting to reuse a nullifier
"Invalid receiver"
withdraw
Receiver address is zero
"Receiver mismatch"
withdraw
Receiver doesn't match public inputs
"Merkle tree full"
_insertLeaf
Tree has reached 2^32 leaves
Gas Considerations
Approximate Gas Costs
deposit
~150,000
Includes ERC20 transfer + tree insertion
transact
~200,000 + (50,000 × nullifiers)
Proof verification is expensive
withdraw
~250,000 + (50,000 × nullifiers)
Includes proof + ERC20 transfer
Note: Actual costs depend on:
Number of nullifiers
Number of new commitments
SP1 verifier implementation
ERC20 token implementation
Network congestion
Last updated