How this works

Notes, commitments and trees; the four pools; the one equation that gates every deploy; and where each number comes from.

A shielded transaction hides its contents, not its shape

Zcash has one ledger with two kinds of funds on it. Transparent funds work like Bitcoin's: addresses, amounts and inputs in the open. Shielded funds live in notes, encrypted to their owner, and a transaction that moves them publishes only what the network needs to check it: a zero-knowledge proof, a nullifier for each note spent, and a note commitment for each note created. The commitments are appended to a Merkle tree per pool, and that tree only grows.

what a block tells you
for each transaction:
  transparent  inputs, outputs, amounts, addresses
  sapling      spends (nullifiers), outputs (commitments)
  orchard      actions (one nullifier + one commitment each)
  ironwood     actions (same shape, the newest pool)

on the block:
  saplingCommitmentTreeSize, orchardCommitmentTreeSize, ironwoodCommitmentTreeSize

That is enough to count, and counting is what ZecTools does. It never sees an amount, an address or a memo inside a pool, and neither does the server it reads from.

The pools

Four shielded protocols have shipped, each with its own anonymity set. Sprout (2016) is withdraw-only since Canopy. Sapling (2018, zs1…) is live. Orchard (2022, Halo 2, no trusted setup, inside unified u1… addresses) became spend-only at NU6.3. Ironwood (July 2026, block 3,428,143) is the current default: same Halo 2 lineage, a corrected circuit, and it is where new shielded value goes.

The protocol keeps a running value pool for each: ZEC in minus ZEC out, and a consensus rule called the turnstile says no pool may ever go negative. A transfer between pools must reveal its amount, and that is how the network audits that no shielded pool has minted coins without opening any of them.

The replay check

the invariant
tree(height B) - tree(height A)  ==  sum of outputs in blocks A+1 .. B

sapling   outputs
orchard   actions
ironwood  actions

The indexer reads 1,152 blocks and the tree sizes on the first and last, and asserts the equation for each pool. Today: sapling grew 1,239 and the blocks carried 1,239; orchard 667 and 667; ironwood 35,680 and 35,680. If any pair ever disagrees the build exits non-zero and the deploy does not ship. zec pools runs the same check on every call.

Addresses

what zec check recognises
t1…    transparent, pay to public key hash    balance readable
t3…    transparent, pay to script hash        balance readable
tex1…  ZIP 320, transparent-source only       readable by the underlying t-address
zs1…   Sapling shielded                       nothing to read without a viewing key
u1…    unified (ZIP 316), several receivers   nothing to read without a viewing key
zc…    Sprout shielded, legacy                nothing to read without a viewing key

Issuance

the schedule, from the spec
slow start     blocks 0..19,999 ramp from 0 to 12.5 ZEC
pre-Blossom    12.5 ZEC every 150 s
Blossom        653,600: 6.25 ZEC every 75 s (same ZEC per day)
halving 1      1,046,400 (Canopy): 3.125 ZEC
halving 2      2,726,400 (NU6): 1.5625 ZEC
halving 3      4,406,400: 0.78125 ZEC    <- next, in 2.2 years

issued(height) = sum of the subsidy over every block so far

Issuance at height 3,492,480 by that formula is 16,947,001.56 ZEC, 80.7% of the 21 million cap. A full node reports 16,946,632.97 ZEC in existence; the 368.58 ZEC gap is subsidy that miners never claimed, which the rules allow and the other direction never. Of each subsidy, 80% goes to the miner, 8% to Zcash Community Grants and 12% to a lockbox that currently holds 64,890.18 ZEC.

Network upgrades

UpgradeHeightDateBranchWhat it did
Sprout02016-10-2800000000launch; the Sprout shielded pool
Overwinter347,5002018-06-265ba81b19transaction expiry, replay protection, versioning
Sapling419,2002018-10-2876b809bbthe Sapling shielded pool; fast, mobile-sized proofs
Blossom653,6002019-12-112bb40e6075-second blocks; subsidy halved per block to keep issuance
Heartwood903,0002020-07-16f5b9230bshielded coinbase; flyclient-friendly headers
Canopy1,046,4002020-11-18e9ff75a6first halving; Founders' Reward ends, dev fund begins
NU51,687,1042022-05-31c2d6d0b4the Orchard shielded pool, Halo 2, unified addresses
NU62,726,4002024-11-23c8e71055second halving; lockbox dev fund
NU6.13,146,4002025-11-244dec4df0one-time lockbox disbursement (ZIP 271); coin-holder funding model
NU6.23,364,6002026-06-035437f330Orchard circuit soundness fix after the May 2026 emergency
NU6.3 · current3,428,1432026-07-2837a5165bIronwood: the new shielded pool; Orchard becomes spend-only; v6 transactions

The branch id is what the network reports; the name is a lookup in this table. When they do not match, every command says "a branch this build has no name for" rather than picking the nearest.

Where the reads go

lightwalletd (zec.rocks:443, gRPC over TLS): the tip, compact blocks, tree states, transparent balances and the mempool. It is the endpoint wallets sync from, and it needs no key. A public full node, for the one thing lightwalletd does not carry: getblockchaininfo's value pools, read via the Nighthawk explorer and then the Tatum gateway. When neither answers, the figure is null and the page says so.

Schema

one block, as published
{
  "height": 3492480,
  "hash": "000000000068297fc0641fb193e70efc69200c408e4956462cbc4c9aa6b8ee2d",
  "time": 1790095931,
  "txCount": 16,
  "shieldedTx": 4,
  "mixedTx": 5,
  "transparentTx": 7,
  "saplingSpends": 0,
  "saplingOutputs": 0,
  "orchardActions": 0,
  "ironwoodActions": 29,
  "trees": {
    "sapling": 73971813,
    "orchard": 50466384,
    "ironwood": 554487
  }
}

API

No key, no auth, no rate limit, CORS open to everything.

endpoints
GET /api/summary              the counts on the landing page
GET /api/blocks               the last 48 blocks, newest first
GET /api/blocks?limit=5       cap the result
GET /api/blocks?shielded=1    only blocks with a shielded transaction
GET /api/pools                trees, balances, the window, the replay check
GET /api/upgrades             every upgrade, the live branch, the issuance schedule

GET /data/feed.json           the whole thing, as the indexer wrote it
example
curl -s https://zectools.org/api/pools | jq '.pools'

What this is not

It deploys no contracts and holds nothing, so there is nothing to audit and no counterparty. It does not price anything and decrypts nothing. Everything it publishes is recomputable: see verify.