Zcash Naming Service - a naming service for Zcash, built on shielded memos and SP1 proofs

Naming on Zcash has come up a few times over the years. Eric floated the idea of .zec domains back in 2020. Holmes Wilson built Zbay and showed POC for a memo-based name registration on Zcash. However nothing that shipped as a usable system. We took a crack at it.

What is ZNS?

Register a human-readable zcash name by sending a single shielded Zcash transaction. The name resolves to your unified address.

Live on testnet right now: zecname.xyz

The site has a built-in faucet and browser wallet. You can test it out by first getting testnet ZEC and registering a name. Shielded transactions do take a while on testnet so please be patient.

How it works

1. Alice generates an Ed25519 keypair and sends 0.01 ZEC to a deterministic registrar address with a signed memo: `ZNS:v1:REGISTER:alice:::`

2. A scanner watches the registrar using a published Incoming Viewing Key. Ideally anyone can run one.

3. The scanner validates the memo (name rules, fee, signature), inserts the name into a Merkle Tree, and queues a proof record

4. A prover generates a proof for every registration, proving name validity, fee payment, signature correctness, and the SMT state transition

5. Anyone can verify: `GET /v1/resolve/alice` returns the address + Merkle proof against the current root.

Everything runs on shielded transactions. Registration, marketplace purchases, escrow payouts.

Marketplace

Names are tradeable. ZNS has a built-in escrow marketplace where owners can list names for sale at a fixed price. A buyer sends a single shielded transaction to the escrow address with the name and price. The scanner validates the payment, transfers ownership to the buyer’s pubkey, updates the resolved address, and queues a payout to the seller.

SP1 Proofs

You shouldn’t have to trust an indexer to tell you the registry is correct. That’s where SP1 comes in. It’s a RISC-V zkVM by Succinct. We compile our validation logic to a RISC-V binary, run it inside the VM, and get a proof that the computation was correct. Every registration gets its own proof. The proofs chain: each one commits the old and new SMT root, plus the txid and block height of the on-chain transaction. A verifier can walk the chain from genesis and know the entire registry is correct without trusting anyone.

The prover is built and tested locally but not yet connected to the Succinct Prover Network on testnet. The plan for mainnet is to bridge registration fees to fund proof generation automatically with sp1. You register a name, the fee covers the cost of proving it, and the proof gets generated. Proofs on the Succinct network cost fractions of a cent, so even the 0.01 ZEC minimum fee covers it comfortably.

Feedback

ZNS currently runs as a centralized server. We want to change that. Here’s what we’re thinking, and we’d like to know how the community feels.

IPNS / static data : The registry is just a key-value map (name → address). We could publish snapshots to IPNS under a static key, so anyone can fetch name data through any IPFS gateway without hitting our API.

Distributed indexing: The registry is deterministic. The scanner connects to any lightwalletd or Zaino instance, reads one address with one public IVK, applies fixed validation rules, and arrives at one SMT root. Since 2 independent instances processing the same blocks will always produce the same root, zcash is the consensus layer, so there’s no coordination protocol needed between instances. We’re thinking about packaging ZNS as a single Docker container that anyone running Zebra + Zaino can point at their existing setup. The Zcash Operators program has ~50 nodes running already. If even a handful of those chose to run a ZNS instance alongside their stack, you’d have multiple independent resolvers serving the same verifiable data. We’re not sure what the right incentive model looks like here, or if operators would even want this.

Ethereum as a data layer : Another option we’ve been thinking about: store the name-to-address mappings on Ethereum and let anyone retrieve them via a standard RPC call. Ethereum has the infrastructure, the uptime, and the tooling already. The registry data is small, reads are cheap, and it removes the need for clients to trust or even find a ZNS server.

Tor: We already have an onion service running.

-–

Try it: zecname.xyz (testnet)

Docs: docs.zecname.xyz

Tor: fdf3n3xrm2a7vy5iljdghznajti4qibjcpp4eyqluaqvqtdgsaxyvwid.onion

4 Likes

Interesting idea honestly. Using shielded memos for something like a naming layer actually makes sense in the Zcash context since privacy is already built into the design. I’m curious how you plan to handle things like name collisions and updates or transfers later on.

1 Like

“how you plan to handle things like name collisions and updates or transfers later on.”
@zilk On collision if you mean two people simultaneously trying to register the same name, the scanner processes transactions in block order, so first come first serve. Right now the registration fee is burned either way since the registrar address has no spending key, but the memo already includes the sender’s address, so we could route refunds tx fees for failed registrations (something we already so in the marketplace).

As for Updates and transfers, this is already live. Every name is owned by an Ed25519 key that’s included in the registration memo. Once you own a name, you can update the resolved address or transfer ownership to a new pubkey via signed API calls (So you need to keep that key safe).
So if Alice registered alice.zec and later moves to a new wallet, she just signs an UPDATE with her key and the new address. If she wants transfer to Bob, she signs a TRANSFER specifying Bob’s pubkey as the new owner, and Bob starts fresh with nonce 0.

Got it, that clears things up. Tying ownership to an Ed25519 key instead of the wallet address is actually a nice touch, especially for people who rotate wallets over time. The update and transfer flow sounds pretty clean from a design standpoint.

1 Like