Skip to main content

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:

OperationMemo layoutPaid amount
REG registerzNS:1:REG:{name}:{address}:{pubkey}:{nonce}:{sig}registration fee for the name length
UPD update addresszNS:1:UPD:{name}:{address}:{pubkey}:{nonce}:{sig}update fee
CHG transfer ownerzNS:1:CHG:{name}:{new_pubkey}:{nonce}:{sig}update fee
LST list for salezNS:1:LST:{name}:{pubkey}:{price}:{nonce}:{sig}update fee
ULT delistzNS:1:ULT:{name}:{pubkey}:{nonce}:{sig}update fee
BUY purchasezNS: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:

  • pubkey is lowercase hex, 64 characters.
  • price appears only for LST.
  • address appears only for REG, UPD and BUY.
  • price and nonce are 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

RuleValue
Charactersa-z, 0-9, hyphen
Length1–64 characters including the zone
Caselowercase only — a name is stored and hashed lowercase
Hyphensnot 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.

tip

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:

  • REG must pay exactly the registration fee for the name length.
  • UPD, CHG, LST, ULT must pay exactly the update fee.
  • BUY must 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.