Came out of the distribution table shipping a sent on column that read zero for every miner. That zero was not "nothing left" — it was "nothing left by a route the chain records", because a wormhole transfer does not record who sent it. The privacy is the chain's central feature and the observer currently has nothing to say about it.
A transfer inserts a commitment as a leaf; spending one proves a nullifier, which is then recorded so it cannot be spent twice. Every NativeTransferred we decode carries a leaf_index, so the two halves are joinable from events we already index.
Measured on mainnet
ZkTree::LeafCount 82,644 notes created
Wormhole::UsedNullifiers 47,789 notes spent (map enumerated)
-------
outstanding 34,855 unspent — what is still inside
And the flow, split by the extrinsic that produced each transfer and whether a sender was recorded:
Hidden-sender transfers in block initialisation are mining rewards. The 9,894 from verify_*_batch are real payments with no recorded origin.
Worth noting the ratio: 47,789 nullifiers consumed against 9,894 hidden-sender outputs. Notes are spent in batches far larger than the outputs they produce, which is consolidation and is itself worth showing.
What the route should carry
The pool: notes created, notes spent, outstanding, tree depth and root. Outstanding is the headline — it is the anonymity set, and it is the one number that says how much of this chain's activity is currently unobservable.
Flow by route: the table above, with summed amounts. This is literally "what enters and what leaves".
Per-day: notes created per day, derived from the leaf_index on transfers we already index rather than from ZkTree::LeafInserted, which is in SKIPPED_EVENTS because it fires every block and names no account.
Failures: SegmentsDenied and ExitMintFailed have never fired. A zero there is a finding, not a gap.
Fees: MinerVolumeFeePaid, 713 events across 19 accounts.
The thing to be careful about
Do not describe outstanding notes as "funds locked in the wormhole" without checking what a leaf actually commits to. Balances::Locks is empty on this chain, and account balances are visibly real, so the relationship between a note and a balance needs establishing rather than assuming. Count what can be counted — notes created, notes spent, the difference — and say that, which is true, rather than a token figure that might not be.
Came out of the distribution table shipping a `sent on` column that read zero for every miner. That zero was not "nothing left" — it was "nothing left by a route the chain records", because a wormhole transfer does not record who sent it. The privacy is the chain's central feature and the observer currently has nothing to say about it.
## The mechanism, read off the runtime
```
Wormhole calls verify_private_batch, verify_public_batch
events NativeTransferred, AssetTransferred, ProofVerified,
MinerVolumeFeePaid, SegmentsDenied, ExitMintFailed
storage UsedNullifiers, TransferCount
ZkTree events LeafInserted, TreeGrew
storage Leaves, Nodes, LeafCount, Depth, Root, UnprocessedLeaves
```
A transfer inserts a commitment as a **leaf**; spending one proves a **nullifier**, which is then recorded so it cannot be spent twice. Every `NativeTransferred` we decode carries a `leaf_index`, so the two halves are joinable from events we already index.
## Measured on mainnet
```
ZkTree::LeafCount 82,644 notes created
Wormhole::UsedNullifiers 47,789 notes spent (map enumerated)
-------
outstanding 34,855 unspent — what is still inside
```
And the flow, split by the extrinsic that produced each transfer and whether a sender was recorded:
```
(no extrinsic — initialisation) hidden 23,876 events 72 recipients
Utility::batch_all visible 15,303 2,145
Wormhole::verify_public_batch hidden 8,136 538
Balances::transfer_allow_death visible 6,941 651
Wormhole::verify_private_batch hidden 1,758 116
Balances::transfer_keep_alive visible 127 44
```
Hidden-sender transfers in block initialisation are mining rewards. The 9,894 from `verify_*_batch` are real payments with no recorded origin.
Worth noting the ratio: **47,789 nullifiers consumed against 9,894 hidden-sender outputs**. Notes are spent in batches far larger than the outputs they produce, which is consolidation and is itself worth showing.
## What the route should carry
- **The pool**: notes created, notes spent, outstanding, tree depth and root. Outstanding is the headline — it is the anonymity set, and it is the one number that says how much of this chain's activity is currently unobservable.
- **Flow by route**: the table above, with summed amounts. This is literally "what enters and what leaves".
- **Per-day**: notes created per day, derived from the `leaf_index` on transfers we already index rather than from `ZkTree::LeafInserted`, which is in `SKIPPED_EVENTS` because it fires every block and names no account.
- **Failures**: `SegmentsDenied` and `ExitMintFailed` have never fired. A zero there is a finding, not a gap.
- **Fees**: `MinerVolumeFeePaid`, 713 events across 19 accounts.
## The thing to be careful about
Do not describe outstanding notes as "funds locked in the wormhole" without checking what a leaf actually commits to. `Balances::Locks` is empty on this chain, and account balances are visibly real, so the relationship between a note and a balance needs establishing rather than assuming. Count what can be counted — notes created, notes spent, the difference — and say that, which is true, rather than a token figure that might not be.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Came out of the distribution table shipping a
sent oncolumn that read zero for every miner. That zero was not "nothing left" — it was "nothing left by a route the chain records", because a wormhole transfer does not record who sent it. The privacy is the chain's central feature and the observer currently has nothing to say about it.The mechanism, read off the runtime
A transfer inserts a commitment as a leaf; spending one proves a nullifier, which is then recorded so it cannot be spent twice. Every
NativeTransferredwe decode carries aleaf_index, so the two halves are joinable from events we already index.Measured on mainnet
And the flow, split by the extrinsic that produced each transfer and whether a sender was recorded:
Hidden-sender transfers in block initialisation are mining rewards. The 9,894 from
verify_*_batchare real payments with no recorded origin.Worth noting the ratio: 47,789 nullifiers consumed against 9,894 hidden-sender outputs. Notes are spent in batches far larger than the outputs they produce, which is consolidation and is itself worth showing.
What the route should carry
leaf_indexon transfers we already index rather than fromZkTree::LeafInserted, which is inSKIPPED_EVENTSbecause it fires every block and names no account.SegmentsDeniedandExitMintFailedhave never fired. A zero there is a finding, not a gap.MinerVolumeFeePaid, 713 events across 19 accounts.The thing to be careful about
Do not describe outstanding notes as "funds locked in the wormhole" without checking what a leaf actually commits to.
Balances::Locksis empty on this chain, and account balances are visibly real, so the relationship between a note and a balance needs establishing rather than assuming. Count what can be counted — notes created, notes spent, the difference — and say that, which is true, rather than a token figure that might not be.