How it works

Shielding tokens

Shielding moves ERC-20 tokens from your wallet into the privacy pool. The contract takes custody of the tokens; you receive a private note — a commitment only you can spend.

Userspending keysdk.shield()SDKgenerate ZK proofcompute commitmentshield(params, proof)PrivacyPoolverify proofinsert Merkle leaftake token custody0G Chainfinalized

Step by step

  1. 1SDK computes commitment = Poseidon2(spendingPubkey, token, amount, salt).
  2. 2SDK generates a ZK proof that the commitment is honestly computed.
  3. 3SDK calls approve() on the token contract, then shield(params, proof) on PrivacyPool.
  4. 4Contract verifies the proof via ShieldVerifier, inserts the commitment into the Merkle tree, and transfers tokens in.
  5. 5A Shielded event is emitted. NoteManager picks it up and adds the note to your local tree.

Circuit public inputs

The shield circuit has one public output: the commitment hash. Everything else is private.

noir
// Private inputs (never revealed)
spending_pubkey: Field
token:           Field  // address as field
amount:          Field
salt:            Field  // random 32-byte value

// Public output
commitment = poseidon2_hash4(spending_pubkey, token, amount, salt)
The salt is generated randomly by the SDK. It ensures two shields of the same amount produce different commitments, preventing correlation.