How Zollect works

Zollect makes collectibles on Zcash that people actually own: each item, a zote, is a shielded note on the chain. This page explains the idea, shows how to check every claim yourself, and lists what isn't done yet.

The problem

Zcash mainnet has no token or NFT support. The standard that would add custom assets, Zcash Shielded Assets, isn't active on mainnet. So when a Zcash collectible is "sold" today, the buyer pays ZEC and a marketplace records the new owner in its own database. The buyer holds nothing on the chain and can't prove ownership without that marketplace. Explorers say so plainly: they can't verify ownership, because it isn't on the chain.

Zollect puts the item itself on the chain, today, with no protocol change.

What a zote is

A zote is a zero-value shielded note in Zcash's Ironwood pool. Its encrypted memo names the collection, the item number and the hop count (how many times it has changed hands). It sits at a vault address that holds that zote and nothing else, controlled by the owner's key.

Uniqueness comes from Zcash itself. In an Ironwood action, the new note created is bound to the note being spent in that same action. So when a zote moves, there is exactly one valid successor, and the old note's nullifier is published, which marks it spent forever. Nobody can copy a zote or sell it twice: the network rejects the second spend.

A zote is to Zollect what a token is to an NFT on other chains, except nobody watching the chain can see who holds it.

Mint, own, prove, sell

Mint and seal

The issuer mints each zote in a chain of transactions from its own issuer key, one vault per zote, then sends a final seal note to an address nobody can spend. The issuer's viewing key is published, so anyone can count the collection. A zote minted after the seal fails the check.

Own

Holding a zote means holding the key to its vault. No list of owners exists anywhere.

Prove

A verifier sends a fresh random code. The owner's vault signs that exact code with the key that can spend the zote. The checker confirms the signature matches the note, the note is the current unspent zote of that item, and it traces back through every hop to the sealed mint. A replayed or old proof fails.

Sell

Buyer and seller build one transaction together as a partially created Zcash transaction (PCZT). The buyer adds the payment from their own funding wallet and a fresh vault for the zote, signs only their part, and removes their private details. The seller checks the payment amount, the recipient (their own address), the fee and that exactly their zote is being spent, then signs last and broadcasts. The zote and the ZEC move together or not at all.

Verify it yourself

The fastest way is the Verify and Try to cheat buttons on the main page; they run the real checker against Zcash mainnet. To run it on your own machine:

# build the read-only checker (Rust)
git clone REPO_URL zollect && cd zollect
cargo build --manifest-path verifier/Cargo.toml --release --locked --features mainnet

# 1. Is Lagos Lights #2 genuine, and is the collection sealed?
verifier/target/release/zecathon-carrier-verifier mainnet-verify-item \
  https://na.zec.rocks:443 https://eu.zec.rocks:443 \
  public/lagos-lights.issuer.ufvk lagos-lights 2 public/lagos-lights.mint-txids

Expected output:

FINAL txid=d44ab08a9c212509ad0e88bba0d82f6183ae1852404e67c47dbb435a3fbd61ec action=0 height=3531330
ITEM 1 VALID txid=abfb41a26bc70de6484f7b8edf4828ef079b4b8fda2857cb1858ee79130cfbda action=2
ITEM 2 VALID txid=4971340fa5620a37ddd84b1b1890c3b8c24958100173e8fabb65ccf41ea4cca7 action=2
ITEM 3 VALID txid=9ec4773a8828fac9dfd7a141a0294dbdbe338d263555080ddcaae3ff369fa060 action=0
SUPPLY SEALED count=3
# 2. Tobi's pre-sale proof must now fail, and the sale must link the two notes
zecathon-carrier-verifier mainnet-proof PRIMARY SECONDARY public/proofs/tobi-zote2.json CHALLENGE public/lagos-lights.zote2-chain
zecathon-carrier-verifier mainnet-link  PRIMARY SECONDARY public/proofs/tobi-zote2.json public/proofs/kemi-zote2.json CHALLENGE public/lagos-lights.zote2-chain

Expected: SPENT … spending_txid=c08b51ee… and LINK VALID … same_action=1.

Every check fetches only the listed transactions from two independent light-wallet servers, compares the full responses, and refuses if they disagree. Nothing is signed or broadcast. Each check takes one to five seconds.

Architecture

  • Checker (Rust, read-only): verifies issuance and seal, ownership proofs, and the link between successive owners.
  • Sender tools (Rust): mint, transfer, prepare and sign sales. Every mainnet send requires two-server agreement, a fee guard, a single-zote vault and fees paid from a separate funding wallet.
  • Website (Node): exposes fixed, rate-limited read-only operations. Browsers never send keys or file paths.

Privacy model

  • Chain watchers see shielded transactions only: no owners, buyers, sellers, prices or which zote moved.
  • A verifier learns that a zote is genuine and held, plus that zote's vault history. A vault holds one zote and nothing else, so no wallet balances or other holdings are exposed.
  • The seller learns the buyer's one-time vault for this zote, not their funding wallet.
  • The buyer learns the zote's hop count and dates before buying.
  • The issuer's viewing key is public by design, so anyone can count the collection and see mint-time vault addresses. Vaults are fresh per zote.
  • Light-wallet servers see the IP address and timing of checker requests.

The full threat model is in the repository's THREAT_MODEL.md.

Limits, honestly

  • No wallet support yet. Zodl, Zingo and other wallets don't recognise zotes. Importing a vault seed into an ordinary wallet could spend the zero-value note and destroy the zote. Zotes live in Zollect's own vault tool for now; the Zote standard draft describes what wallets would need.
  • The seal is a checker rule. The network would accept a transaction minting after the seal; the checker rejects it, so it never counts as a genuine zote.
  • Attack tests ran on a test chain (double spend, forged successor, mint after seal). The mainnet "Try to cheat" buttons test old, forged and wrong-key proofs live.
  • The demo collection and owners are ours. Lagos Lights shows the mechanism; it is not user traction.
  • An earlier collection is superseded. Its seal was encrypted so it couldn't be read; the bug was fixed and Lagos Lights replaced it. Both are recorded on the evidence page.
  • Prototype code, not audited.

What's next

  • Propose the Zote standard to Zodl and Zingo so zotes show up in everyday wallets.
  • Sealed-bid primary sales that deliver a zote to the winning bidder.
  • A claim flow so an existing collection can move from a database to real zotes.
  • Route checker traffic over Tor.
  • A lineage proof that lets a buyer verify history without seeing earlier hops.

Credits

The carrier-note idea, using Orchard-style note binding for collectibles, comes from Zarrier, a testnet proof of concept. Zollect is a new implementation for Ironwood mainnet, written for Zecathon. Built on the Zcash Rust crates (orchard, zcash_primitives, zcash_client_backend, pczt).