Command Format
Every zNS operation is a shielded ZCash transaction to the registrar's protocol address, where the amount is the payment and the memo is the signed command. Both travel in the same note, so intent and payment are atomically bound — there is no separate reference or invoice to correlate.
This page is the exact wire format. A command built to it is one both the registrar and the zero-knowledge circuit will accept.
Anatomy
All commands are colon-separated ASCII, beginning with the protocol marker and version:
zNS:1:{OP}:{name}:…:{ed25519_pubkey_hex}:…:{nonce}:{signature_hex}
The fields between depend on the operation:
| Operation | Memo layout | Paid amount |
|---|---|---|
REG register | zNS:1:REG:{name}:{address}:{pubkey}:{nonce}:{sig} | registration fee for the name length |
UPD update address | zNS:1:UPD:{name}:{address}:{pubkey}:{nonce}:{sig} | update fee |
CHG transfer owner | zNS:1:CHG:{name}:{new_pubkey}:{nonce}:{sig} | update fee |
LST list for sale | zNS:1:LST:{name}:{pubkey}:{price}:{nonce}:{sig} | update fee |
ULT delist | zNS:1:ULT:{name}:{pubkey}:{nonce}:{sig} | update fee |
BUY purchase | zNS:1:BUY:{name}:{address}:{pubkey}:{nonce}:{sig} | exactly the listed price |
For CHG, {new_pubkey} is the incoming owner's key, and the signature is made by the
outgoing owner — it is the current owner who authorises a transfer.
The signed message
The signature covers the command without the trailing :{signature} — that is,
everything from the marker up to and including the nonce:
zNS:1:REG:richard.zcash:u1…:0101…0101:1780000001
The rules are exact, and a client that gets any of them wrong produces a signature the circuit rejects:
pubkeyis lowercase hex, 64 characters.priceappears only forLST.addressappears only forREG,UPDandBUY.priceandnonceare decimal, with no leading zeros, no sign and no padding.- The signature is Ed25519 over those exact bytes, hex-encoded, 128 characters.
Verification is strict: non-canonical signatures and small-order keys are rejected.
Field rules
Name
| Rule | Value |
|---|---|
| Characters | a-z, 0-9, hyphen |
| Length | 1–64 characters including the zone |
| Case | lowercase only — a name is stored and hashed lowercase |
| Hyphens | not leading, not trailing, never doubled |
| Zones | .zcash, .zec, .private, .secure, .safe |
Exactly one dot is allowed, separating the label from the zone.
Target address
The address a name resolves to must be a Unified Address on mainnet carrying an Orchard receiver. Addresses without one are refused.
The reason is practical rather than arbitrary: the registrar receives and pays through Orchard key material, which per ZIP 229 also covers the Ironwood pool. An address with no Orchard receiver cannot be paid, so it cannot be used for refunds or sale proceeds.
Ironwood does not add a receiver
Ironwood is a new value pool, not a new address format. Wallets migrate notes into it while the receiving address stays an Orchard address. A current wallet's Unified Address works unchanged.
Nonce
The nonce is a Unix timestamp in seconds at the moment you sign.
- It must be strictly greater than the nonce currently recorded for that name. This is what prevents replay of an old signed command.
- It may not run ahead of the block that carries it by more than 300 seconds, which absorbs ordinary clock skew without letting a nonce be parked far in the future.
For a first registration, any current timestamp works.
Price
Only LST carries a price. It is an integer number of zatoshi (1 ZEC = 100,000,000
zatoshi) and must be greater than zero.
Re-listing an already-listed name at a new price is allowed — send another LST. The most
recent one wins.
Size limit
A ZCash memo is exactly 512 bytes, and the whole command must fit. The fixed parts consume a predictable amount:
zNS:1:{OP}: … marker, version, operation 11 bytes
{pubkey} 64 hex characters 65 bytes with separator
{nonce} 10 digits today 11 bytes with separator
{signature} 128 hex characters 128 bytes
That leaves roughly 295 bytes to share between the name and the target address. A Unified Address with several receivers can be long, so with a very long name a very long address may not fit. Clients should compute the budget and warn before the user pays, rather than letting the transaction fail after the fact.
Payment
The amount decides validity as much as the memo does:
REGmust pay exactly the registration fee for the name length.UPD,CHG,LST,ULTmust pay exactly the update fee.BUYmust pay exactly the listed price.
Length is measured on the label, excluding the zone: ab.zcash is a 2-character name.
An underpaid or overpaid command is not processed. If the operation and public key are readable, the amount is credited to your internal balance and can be withdrawn — see Q&A.
Ordering
Commands are processed in the order ZCash produced them: block height, then transaction index within the block, then input index. The registrar does not choose the order, and cannot reorder without every independent indexer computing a different root.
For contested operations — two REGs for the same name, or two BUYs for the same
listing — the first in that ordering wins and the others are refunded to internal balance.
Worked example
Registering richard.zcash:
1. Generate an Ed25519 keypair. The public key is your identity across all your names.
2. Build the message to sign (note: no trailing signature field):
zNS:1:REG:richard.zcash:u1mvnsq85wane…:3757ee1a…a53:1780000001
3. Sign it with the private key; hex-encode the 64-byte signature.
4. Append it to form the memo:
zNS:1:REG:richard.zcash:u1mvnsq85wane…:3757ee1a…a53:1780000001:cfec7a58…04
5. Send a shielded transaction to the registrar address, with that memo, paying the
registration fee for a 7-character name.
Within a few minutes the command is batched, proven, and anchored. From then on
richard.zcash resolves through any indexer, with a Merkle proof you can check yourself.