V0.5 Testnet · Noid → Open
Unmask (withdraw)
Unmasking is the door back out: notes are spent and real coins go to a public address. Structurally it is a transfer with one output sent to the public world instead of into a note.
Sent by
The relayer
Proof
withdraw (19 signals)
Pays to
Any address
Notes
up to 4 in → 2 out
Menoid wallet
gathers notes
proves the withdraw
Relayer
validates
submits
NoidPool
verifies · nullifies
pays once, at the end
Receiving address
gets the coins
publicly
| Send (transfer) | Unmask (withdraw) | |
|---|---|---|
| Outputs | 3 notes: receiver, change, relayer | 2 notes: change, relayer — plus a public payout |
| Public signals | 19 | 19, including receiver and withdrawAmount |
| Balance rule | Σ in = Σ out | Σ in = Σ out + withdrawAmount |
| Coins move? | No | Yes — out of the pool |
| Receiver | Private | Public address and amount |
In the wallet
- 1You choose the amount and the receiving address — a flat relayer fee applies.
- 2Gathers and batches notes (at most 4 per proof); each batch’s outputs are your change and the relayer’s fee.
- 3Proves every batch for that one destination.
At the relayer
- 4Validates the calls and submits withdraw(calls, to).
Inside NoidPool
- 5For each call: checks the inputs, rejects duplicate commitments, builds the 19 public signals with publicSignals[0] = the to address, and verifies the proof.
- 6Marks the nullifiers spent, inserts the change and fee commitments, and emits NoteCreated.
- 7Sends the total to the address once, at the end — one transfer for the whole batch. Any failure reverts everything: no partial withdrawals.
The destination is bound into the proof
publicSignals[0] = uint256(uint160(to)) // the contract feeds the destination into the proofThe proof was made for one destination. A relayer that redirects the payout changes publicSignals[0], and verification fails. The relayer is a courier, not a custodian: it can deliver the withdrawal or drop it, never re-address it.
Go deeperThe 19 public signals
| Index | Signal | Count |
|---|---|---|
| 0 | receiver (the destination address) | 1 |
| 1 | relayerCommitment | 1 |
| 2–5 | enabled[] | 4 |
| 6–9 | roots[] | 4 |
| 10–13 | nullifiers[] | 4 |
| 14 | withdrawAmount | 1 |
| 15–16 | out_enabled[] | 2 |
| 17–18 | c_outs[] | 2 |
On-chain, anyone can see
- The amount, the destination and the time
Stays private
- Which notes paid for it — and so which deposit it came from
The pool is the crowd
