ZRC20 ZRC-20 Token standard for Zcash

DOCUMENTATION

ZRC-20 — a fungible token standard for Zcash

ZRC-20 tokens are inscribed into Zcash shielded memo fields and tracked by off-chain indexers. No new consensus rules, no bridge, no wrapped assets — every operation is an ordinary Zcash transaction.

Contents
  1. Overview
  2. How it works
  3. Memo format
  4. Operations
  5. Indexing rules
  6. Supply & limits
  7. Integration
  8. Resources

Overview

A ZRC-20 token is a ledger of balances derived from data written into Zcash transactions. The Zcash network validates and orders the transactions; indexers read the memo payloads in that order and compute who owns what.

Because the standard lives entirely inside memos, it inherits Zcash's properties: shielded transfers, no smart-contract surface, and no token logic that can be upgraded or paused by anyone.

How it works

Memo format

Every operation is a single JSON object, UTF-8 encoded, written into the 512-byte Zcash memo field. Whitespace is ignored; unknown fields are ignored; malformed JSON is skipped.

{
  "p": "zrc-20",
  "op": "deploy",
  "tick": "ZRC20",
  "max": "21000000",
  "lim": "1000"
}
fieldrequireddescription
pyesProtocol identifier. Always zrc-20.
opyesOne of deploy, mint, transfer.
tickyesTicker, 1–8 characters, case-insensitive.
maxdeployTotal supply cap, as a decimal string.
limdeployMaximum amount per single mint.
decnoDecimals, 0–18. Defaults to 8.
amtmint, transferAmount, as a decimal string.

Operations

deploy

Registers a ticker and fixes its supply rules. The first valid deploy for a ticker wins; every later deploy of the same ticker is ignored.

mint

Claims up to lim tokens. Mints are processed in block order and are accepted until the cap is reached — the transaction that crosses the cap is partially filled, and everything after it is rejected.

transfer

Moves amt tokens from the sender to the address that receives the memo. A transfer that exceeds the sender's balance at that height is ignored in full; it is never partially applied.

IRREVERSIBLE

Memos cannot be undone

An inscribed operation is final once its transaction is mined. Check the ticker, the amount and the recipient address before sending — there is no protocol-level way to reverse or recall a transfer.

Indexing rules

  1. Operations are processed strictly in block order, then by index within the block.
  2. A memo that is not valid JSON, or whose p is not zrc-20, is skipped.
  3. Amounts are decimal strings; values above lim (mint) or above the sender's balance (transfer) are rejected.
  4. A ticker is owned by its first deploy. Duplicate deploys never overwrite it.
  5. Transparent outputs carry no memo field, so ZRC-20 operations only exist in shielded transactions.
  6. State is a pure function of chain history: a reindex from genesis always reproduces the same balances.

Supply & limits

Memo size
512
bytes per operation

The Zcash memo field is fixed at 512 bytes. One operation per output — payloads are never split across outputs.

Applies to every op type.
Ticker
1–8
characters, case-insensitive

zrc20 and ZRC20 are the same ticker. Leading and trailing whitespace is trimmed before comparison.

First valid deploy wins.

Integration

Wallets and explorers read state from an indexer rather than from the chain directly. A minimal balance lookup:

GET /v1/balance/:address?tick=ZRC20

{
  "tick": "ZRC20",
  "address": "u1...",
  "balance": "12500",
  "height": 2712840
}

Always compare the height in the response against the tip before showing a balance as final — an indexer that lags the chain will report stale state.

Resources