ZooBC wiki
Integrations

Keys and account types

A ZooBC account is controlled by a signature, never by a username, a password or an API key. Which signature depends on the account's type. Besides its native Ed25519 accounts, ZooBC accepts accounts whose addresses are written the way Bitcoin, Ethereum, Solana, Polkadot, Cardano, Ripple, Tron and Tezos write them, and it checks their signatures with each chain's own scheme. A Bitcoin or Ethereum key can therefore control a ZooBC account at the same address it has on its home chain. That account is separate, on ZooBC's own ledger, and holds ZBC.

An address is a type and a payload

An address is a 4-byte type number (little-endian) followed by a payload whose meaning and length the type decides (accounts and addresses). For a native account the payload is the Ed25519 public key itself; for an Ethereum account it is the last 20 bytes of the Keccak-256 hash of the key; for a Bitcoin P2PKH account it is the HASH160 of the key.

TypeAccountWritten asCan sign
0ZooBC, Ed25519ZBC_…yes
1Bitcoin legacy (HASH160)—yes
2Empty ("no recipient")—no
3Estonia eID (reserved)—no
4Ethereum0x…yes
5Bitcoin P2PKH1…yes
6Bitcoin P2SH, verified as P2SH-P2WPKH3…yes
7Bitcoin P2WPKHbc1q…, 42 charactersyes
8Bitcoin P2WSH (script)bc1q…, 62 charactersno
9Bitcoin Taprootbc1p…yes
10Dataset objectZBS_…no
11Solanaas on Solanayes
12Polkadotas on Polkadotyes
13Cardanoaddr1…yes
14Rippler…yes
15TronT…yes
16Tezostz1…yes

Keyless addresses cannot sign either: the protocol's pools, account groups and multisignature accounts have no key, so their funds move only under protocol rules.

The native text form is ZBC_ followed by 56 base32 characters in seven groups of eight: the 32-byte key plus a 3-byte SHA3-256 checksum that also covers the prefix. Separators, spaces and letter case are ignored when it is read. The same 32-byte key can also be written as a node key (ZNK_), a relay key (ZBR_) or a gateway key (ZBG_).

One digest for every scheme

Every account type signs the same chain-bound digest:

digest = SHA3-256("ZBC-TX" ‖ genesis hash ‖ unsigned transaction bytes)

Only this digest is accepted; a signature over the bare bytes is refused. The genesis hash ties every signature to one chain (chain-bound signatures). Some schemes hash the digest once more, as their home chain requires.

Four signature schemes: Ed25519 for ZooBC, Solana, Cardano and Tezos; secp256k1 ECDSA for Bitcoin, Ripple, Ethereum and Tron; BIP-340 Schnorr for Taproot; sr25519 for Polkadot; and the addresses that cannot sign
Four signature schemes: Ed25519 for ZooBC, Solana, Cardano and Tezos; secp256k1 ECDSA for Bitcoin, Ripple, Ethereum and Tron; BIP-340 Schnorr for Taproot; sr25519 for Polkadot; and the addresses that cannot sign

The schemes

  • Ed25519 over the 32-byte digest, for ZooBC (type 0) and Solana (11). Cardano (13) and Tezos (16) also sign with Ed25519, but their addresses are hashes, so the signature field carries the key as well: 98 bytes made of a 2-byte length, the key and the signature. The key is bound to the address by BLAKE2b-28 (Cardano) or BLAKE2b-20 (Tezos).
  • secp256k1 ECDSA, Bitcoin style, for types 1, 5, 6 and 7 and for Ripple (14). The signature field carries the key: a 2-byte length, a 33- or 65-byte key, then the 64-byte signature (r and s). The HASH160 of the key must equal the address, the signed message is the double SHA-256 of the digest, and only low-s signatures are accepted.
  • secp256k1 ECDSA, Ethereum style, for Ethereum (4) and Tron (15): a 65-byte signature (r, s and v) over the Keccak-256 hash of the digest. The key is recovered from the signature and its address compared; high-s signatures are refused.
  • BIP-340 Schnorr for Taproot (9), with the x-only output key; the wallet applies the Taproot tweak.
  • sr25519 for Polkadot (12), under the signing context "substrate".

Taproot accounts can also receive ZBC through SendZBC on every chain from genesis.

Verifying a key that is not stored

An Ethereum-style address is only a 20-byte hash; the public key is stored nowhere on the chain. Ethereum signatures are recoverable: from the signed message and the 65-byte signature, anyone can compute the one public key that produced it. The node does exactly that, takes the last 20 bytes of the Keccak-256 hash of the recovered key, and accepts the signature only if they equal the address. Because high-s signatures are refused, a signature cannot be altered into a second valid form. No registration step and no outside lookup is needed, and 0x accounts can send as freely as they receive.

The signer hashes the ZBC-TX digest with Keccak-256 and signs with secp256k1; the node recovers the public key, hashes it and compares the last 20 bytes with the address; Bitcoin style carries the key and checks its HASH160
The signer hashes the ZBC-TX digest with Keccak-256 and signs with secp256k1; the node recovers the public key, hashes it and compares the last 20 bytes with the address; Bitcoin style carries the key and checks its HASH160

Foreign transactions carried inside

A sender with a foreign account may also put a native transaction of its home chain in the message field of a ZooBC transaction. On this path the node checks the foreign transaction and its signature instead of the ZooBC digest:

  • Ethereum (type 4): an EIP-1559, EIP-2930 or legacy (EIP-155) transaction with an empty access list. Its recovered signer must be the sender, its to the recipient, and its value in wei divided by 10^10 the amount (MetaMask and Ethereum-style access).
  • Solana (type 11): a System transfer whose lamports equal the amount.
  • Bitcoin (types 7 and 5): one input, one or two outputs and a zero miner fee; output 0 pays the recipient and output 1, if any, returns change to the sender.

Such a carrier message may be up to 4,096 bytes, and the transaction may not carry a survival payment (transaction envelope).

Deriving native keys

A native key is derived from a BIP-39 recovery phrase: PBKDF2-HMAC-SHA512 with 2,048 rounds, then SLIP-0010 Ed25519 along m/44'/883'/n', every step hardened. 883 is ZooBC's coin type.

See also