ZooBC wiki
Integrations

MetaMask and Ethereum-style access

An Ethereum key can control a ZooBC account whose address is that key's ordinary 0x… address (account type 4, see keys and account types). MetaMask does not need to know anything about ZooBC: it signs a normal Ethereum transaction, which travels inside a ZooBC transaction and is checked by every node. The account holds real ZBC. No bridge, no wrapped coin and no extra key are involved.

How a transfer works

  1. MetaMask signs an ordinary Ethereum transfer: EIP-1559, EIP-2930 or legacy with EIP-155, with an empty access list.
  2. The signed Ethereum transaction is placed in the message field of a ZooBC SendZBC from the sender's 0x account to the recipient's 0x account.
  3. Every node parses the Ethereum transaction, recovers its signer from the signature and requires three things: the signer is the sending account, the Ethereum to address is the recipient, and the value matches the ZBC amount.

On this path the node checks the Ethereum signature instead of ZooBC's own transaction digest. The carried transaction may take up to 4,096 bytes of message.

MetaMask signs an Ethereum transaction, the adapter on port 8545 wraps it in a SendZBC's message field, and every node checks signer, recipient and amount
MetaMask signs an Ethereum transaction, the adapter on port 8545 wraps it in a SendZBC's message field, and every node checks signer, recipient and amount

The adapter in every node

Every node embeds an Ethereum JSON-RPC adapter. It is enabled by default (eth_rpc_enabled), listens on port 8545 of the node's own machine (loopback) by default, and forwards to the node's API, also over loopback. It answers the calls a wallet such as MetaMask makes:

  • chain and node: eth_chainId, net_version, web3_clientVersion, eth_syncing, eth_mining, eth_hashrate, eth_coinbase, eth_accounts;
  • state: eth_blockNumber, eth_getBalance, eth_getTransactionCount, eth_getCode, eth_call;
  • fees: eth_estimateGas, eth_gasPrice, eth_maxPriorityFeePerGas;
  • transactions and blocks: eth_sendRawTransaction, eth_getTransactionReceipt, eth_getTransactionByHash, eth_getBlockByNumber, eth_getBlockByHash.

eth_sendRawTransaction does the wrapping. It builds a SendZBC between the two type-4 accounts, sets the amount to the value in wei divided by 10^10, takes the fee from gasLimit × gasPrice divided by 10^10, raised to the node's fee floor when lower, and puts the raw Ethereum transaction in the message.

The chain id is derived from the chain's genesis hash, so each ZooBC chain presents its own id. With eth_rpc_chain_id set to 0, the adapter computes:

chain id = (0x0883 << 16) | first two bytes of the genesis hash

From wei to atomic units

MetaMask counts 18 decimals: it treats one displayed coin as 10^18 wei. ZooBC counts 8: 1 ZBC is 10^8 atomic units (ZBC coin and its units). One atomic unit is therefore 10^10 wei, and 1 ZBC shows in MetaMask as 10^18 wei.

The division is done at full precision; any remainder smaller than one atomic unit is dropped, and a value too large for a signed 64-bit amount is refused. The node's check and the adapter use the same conversion, so they always agree.

MetaMask counts 1 ZBC as 10^18 wei, ZooBC as 10^8 atomic units; 500,000,000,000,000,000 wei divided by 10^10 gives 50,000,000 atomic units, 0.5 ZBC
MetaMask counts 1 ZBC as 10^18 wei, ZooBC as 10^8 atomic units; 500,000,000,000,000,000 wei divided by 10^10 gives 50,000,000 atomic units, 0.5 ZBC

Linking an Ethereum address to an account group

The web wallet also uses MetaMask outside transfers. With eth_requestAccounts and personal_sign it asks MetaMask to sign a consent that links the Ethereum address into an account group.

A Bitcoin-style adapter too

Nodes also include a Bitcoin Core-style RPC adapter. It is off by default, listens on port 8332 when enabled, and needs credentials set by the node's operator.

See also