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
- MetaMask signs an ordinary Ethereum transfer: EIP-1559, EIP-2930 or legacy with EIP-155, with an empty access list.
- 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.
- Every node parses the Ethereum transaction, recovers its signer from the signature and requires three things: the signer is the sending account, the Ethereum
toaddress 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.
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.
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.