Error Codes
Reference for all error messages in the Ghost Protocol contracts.
Commitment Errors
| Error | Meaning | Solution |
|---|---|---|
InvalidCommitment | Commitment is zero or invalid field element | Check commitment computation |
CommitmentAlreadyExists | Duplicate commitment | Generate new secrets |
InsufficientFee | Sent less than 0.001 ETH | Send at least 0.001 ETH |
RateLimitExceeded | >10 commits in one block | Wait for next block |
Reveal Errors
| Error | Meaning | Solution |
|---|---|---|
InvalidRoot | Root not in last 100 | Get fresh root, regenerate proof |
NullifierAlreadyUsed | Already revealed | Cannot reveal twice |
InvalidProof | Proof verification failed | Check public input order, proof format |
InvalidRecipient | Recipient is zero address | Provide valid recipient |
Troubleshooting
InvalidProof
This is the most common error. Check:
- Public input order - Must be
[root, nullifier, dataHash, recipient] - Proof array order - snarkjs outputs
bin different order than contract expects - dataHash mismatch - Off-chain computation must match contract's
computeDataHash - nullifier computation - Check the formula uses the correct inputs
InvalidRoot
The root is too old. The protocol only accepts the last 100 roots.
- Get the current root from the CommitmentTree
- Regenerate your Merkle proof with the new root
- Generate a new ZK proof
- Retry the reveal
NullifierAlreadyUsed
The commitment has already been revealed. This is permanent.
# Check if nullifier is spent
cast call 0x03972E4453fD143A5203602020DbE2f7DcF6e0db "isSpent(bytes32)(bool)" <nullifier> \
--rpc-url https://testnet-rpc.umbraline.com
InsufficientFee
Send at least 0.001 ETH with your commit transaction.
await walletClient.writeContract({
// ...
value: parseEther('0.001'),
});
Events to Monitor
When debugging, monitor these events:
// Successful commit
event Committed(bytes32 indexed commitment, uint256 indexed leafIndex, uint256 timestamp);
// Successful reveal
event Revealed(bytes32 indexed nullifier, bytes32 indexed dataHash, address indexed recipient);
// Root updates
event RootUpdated(bytes32 indexed oldRoot, bytes32 indexed newRoot, uint256 leafCount);