Zcash
- create
- create("zcash")
- family
- UTXO · utxo
- symbol
- ZEC · 8 decimals
- bip44
- 133
- caip2
- bip122:00040fe8ec8471911baa1db1266ea15d
- explorer
- blockchair.com/zcash
Address format
Four forms, and each one gets decoded, not measured. Transparent t1… and t3… are Base58Check with a two-byte version, 0x1cb8 for a key hash and 0x1cbd for a script hash, 26 bytes with the checksum. Sapling zs1… is Bech32 over 43 bytes. A ZIP-320 tex1… is the same 20-byte key hash as a t1…, written in Bech32m so a wallet knows to send there from transparent funds only.
The Unified Address u1… is the interesting one. It bundles receivers of different pools into one string. Bech32m carries it past BIP-173's 90 characters, so the checksum runs over the whole thing. Under the checksum sits F4Jumble, a four-round Feistel permutation over BLAKE2b, there so that changing a few characters scrambles everything. The check undoes it and wants the 16 bytes at the end to spell u padded with zeros. Then it reads the items, the way ZIP-316 tells a consumer to for Revision 0: typecodes ascending with no repeats, 20 bytes for P2PKH and P2SH, 43 for Sapling and Orchard, never P2PKH and P2SH together, and at least one item that isn't transparent. A typecode it doesn't know passes, because the ZIP says a wallet has to skip those. MUST-understand metadata fails, Revision 0 has no room for it.
What it doesn't do is decompress the curve points inside a Sapling or Orchard receiver. zcash_address doesn't either, it takes the bytes at their length.
Sprout zc… addresses fail on purpose. Canopy closed the Sprout pool to new value in ZIP 211, so nothing can pay one. Testnet forms (tm…, ztestsapling1…, textest1…, utest1…) fail too.
The ZIP lets a Unified Address grow to about four megabytes, and the check reads all of it. That's around two seconds at the very top. A real one is under a millisecond.
The chain started from its own genesis block, so the CAIP-2 reference is plain BIP-122: the first 32 hex digits of the hash zcashd's chainparams.cpp asserts.
import { getChain } from "@agntn/chains";
const chain = getChain("zec");
chain.assertAddress("t1VmmGiyjVNeCjxDZzg7vZmd99WyzVby9yC"); // returned unchanged
chain.assertAddress("tex1s2rt77ggv6q989lr49rkgzmh5slsksa9khdgte"); // the same key hash, as TEX
chain.bip44; // 133
chain.caip2; // "bip122:00040fe8ec8471911baa1db1266ea15d"
Spellings
zcash, zec, Zcash. The key is zcash, the ticker resolves through getChain.