# ZooBC Transaction Manual: Types, Byte Layouts and Fees

> The complete ZooBC transaction manual: every transaction type, its byte layout, fees and coins, plus the escrow, liquid, scheduled, and trigger modifiers.

- Canonical page: https://zoobc.com/manuals/transactions/
- Publisher: ZooBC, https://zoobc.com/
- Language: English. Translations: [中文（简体）](https://zoobc.com/zh/manuals/transactions/), [Русский](https://zoobc.com/ru/manuals/transactions/), [Italiano](https://zoobc.com/it/manuals/transactions/), [Español](https://zoobc.com/es/manuals/transactions/), [Français](https://zoobc.com/fr/manuals/transactions/), [日本語](https://zoobc.com/ja/manuals/transactions/), [한국어](https://zoobc.com/ko/manuals/transactions/)
- Last updated: 2026-10-08
- Topics: Blockchain, Digital signature, EdDSA, Escrow, Software documentation
- Keywords: blockchain transaction format, transaction types, byte layout, transaction signing, ed25519, escrow transaction, scheduled transactions, transaction fees, ZooBC transactions
- Site index for language models: https://zoobc.com/llms.txt

---

ZOOBC / MANUAL

## ZooBC Transaction Manual

Every way to move value & data on the chain, layouts, coins, and modifiers

### Move value. Move data. On your terms.

A ZooBC transaction is a signed envelope wrapping a small typed body. The **envelope** is identical for every type, the **body** and a few optional **modifiers** decide what actually happens: a plain send, a token transfer, a vested salary, an escrowed deal, an app move, a scheduled trigger. This is the full map.

### 01Anatomy of a transaction

Everything is serialized little-endian into one byte buffer, then signed. The blue fields are the **envelope** (same for all types); the purple **body** is what changes per type.

**type** 4 **version** 1 **timestamp** 8 **sender** 4+key **recipient** 4+key / empty **fee** 8 **bodyLen** 4 **body** bodyLen **escrow** empty / section **msgLen** 4 **message** msgLen **signature** on send

An **account address** is 4-byte type (LE) + public key, `00000000`+32B ed25519 for ZBC, `04000000`+ETH, `05000000`+BTC, and so on. A missing recipient is written as the **empty** type `02000000`. The **message** tail is where a plain send carries its memo, the body of a SendZBC is *only* the amount; the recipient and memo live in the envelope.

### 02Signing

The account type decides both the address prefix and the signature scheme. Sign over the whole envelope (without the signature field), prefixed with the signing tag and the genesis hash. All three are deterministic, so a browser wallet and the node agree byte-for-byte.

#### ZooBC (ed25519) · type `00000000`

```
// digest, then sign
digest = SHA3_256("ZBC-TX" ‖ genesis_hash ‖ txBytes)
sig    = ed25519(digest, privkey)   // 64 bytes
```

Also the scheme for Solana, Cardano, Tezos, Polkadot, same ed25519 key, different address prefix + display encoding.

#### Ethereum (secp256k1) · type `04000000`

```
// recoverable ECDSA, low-s
digest = keccak256(SHA3_256("ZBC-TX" ‖ genesis_hash ‖ txBytes))
r,s,v  = secp256k1.sign(digest)
sig    = r ‖ s ‖ (v+27)          // 65 bytes
```

MetaMask can also send its own signed RLP; the node recovers the sender and maps it to a ZBC transfer.

#### Bitcoin (secp256k1) · type `05000000`

```
// double-sha over the SHA3 payload
digest = SHA256d(SHA3_256("ZBC-TX" ‖ genesis_hash ‖ txBytes))
sig    = secp256k1.sign(digest)
field  = [len(2)] ‖ compressedPub(33) ‖ sig
```

#### Fee, in short

The minimum fee is size-aware: a base rate × the network **fee-scale**, plus a per-byte storage/duration component. Read it live from `https://zoobc.network/api/v1/blockchain/fee-params` or price an exact tx with `/estimate-fee` so the wallet never disagrees with the node to the atomic unit. Overpayment on a precise-fee send is refunded.

#### The chain-bound digest (signing version 2)

Since node v0.4.0 the innermost term is the same in all three schemes, because the node computes that digest once and hands it to whichever signature scheme the account type selects.

- `"ZBC-TX"` is six ASCII bytes with no terminator: `5a 42 43 2d 54 58`.
- `genesis_hash` is the 32 raw bytes of block 0 of the chain being signed for.

Read `genesis_hash` from `GET /api/v1/node/info`; the same response carries `signing_version: 2` and `signing_tag: "ZBC-TX"`. Never hard-code it: it changes every time a test network is relaunched.

Binding the genesis hash into the digest is what makes a signature valid on exactly one network, so a transaction signed for a test chain cannot be replayed onto another. Signing the bare `SHA3_256(txBytes)` is **signing version 1** and the node refuses it with:

```
Invalid transaction signature: legacy unbound digest (signing v1); this chain requires signing v2
```

### 03The three kinds of coin

Amounts are always **atomic** (1 ZBC = 100,000,000). The only thing that changes between coins is the token\_id field, the movement mechanics are identical.

#### ① Native ZBC

token\_id = 0 everywhere. The gas/fee coin, block rewards, staking. A SendZBC (type 1) is the plain path.

#### ② Genesis / bridge tokens

Wrapped foreign assets minted at genesis (ZBTC, ZETH, ZSOL…). They are ordinary **colored tokens** with a fixed token\_id assigned in the genesis config, nothing special at the protocol level.

#### ③ User-issued tokens

Anyone mints one with IssueToken (type 10): symbol, supply, decimals, optional ZBC backing. Its token\_id derives from the issue tx. Same TransferToken / MintToken / BurnToken apply.

Wherever a body has a token\_id (transfer, swap, app stake, liquid, vesting…), pass 0 for ZBC or the token's id for a colored coin. Backed tokens can even pay their own fee (a fee\_in\_token flag), priced against their ZBC backing.

### 04Modifiers, one payment, many shapes

Beyond the base types, four timing/trust wrappers change *when* and *whether* funds actually land. They are what make the surface feel large.

#### Escrow

Append an **escrow section** to *any* value tx's envelope (approver · commission · timeout · instruction). The funds are held until the named **approver** signs ApprovalEscrow (type 4) to release or reject, or the timeout expires. A conditional deal on top of any transfer.

#### Liquid

LiquidPayment (type 6): a single **delayed** payment over a window. The recipient is paid the full amount when the window completes, or a pro-rata slice if the sender LiquidPaymentStops (type 262) early. Short-term (hours), ZBC or token.

#### Scheduled / Vested

ScheduledTransfer (type 29): release in **tranches on a timer**, vesting (funds pre-locked) or recurring salary (pulled each period). Cliff, revoke, recipient-decline, reassign. Long-term (weeks–years). The releases show up as ledger **movements**, not new txs.

#### Trigger / Stop

The lightweight timer: CreateTrigger (15) locks an amount to fire at a future height; CancelTrigger (16) refunds it. To stop the long ones: CancelSchedule (30) revoke/decline, LiquidPaymentStop (262).

**They stack.** A monthly salary *that is also escrowed*, a vesting grant in a colored token, the primitives compose. (Full composition of recurring-with-escrow is on the roadmap; the building blocks are all here today.)

### 05Keeping data-objects alive

On-chain objects that hold data, **datasets** (key/value profiles, chat, business forms) and **tokens**, pay rent to persist. "Adding funds to an object" means topping up its survival financing.

#### Datasets & files → prepaid storage

You write data with SetupAccountDataset (type 3, a property → value pair) or store a file with DFSCreateFile (8). Each block bills storage rent against your account's **prepaid storage**; when it runs dry the object is pruned. Top it up with AddPrepaidStorage (type 9), body is just an amount, credited straight to your prepaid-storage balance. More prepaid = longer life.

#### Tokens → persistence financing

A colored token also pays to survive. FinanceToken (type 14) tops up a token's persistence horizon from the fee, extending how long it stays live before its unused backing is returned to the creator. Same idea, per-token.

### 06Full transaction catalog

All 50 transaction types, with their exact little-endian body layout. coin = supports token\_id · modifiable = accepts an escrow section · new chain = consensus-level (ships with a chain launch).

Byte layouts are transcribed from the ZooBC node serializers (transaction\_util.cpp, the per-type executors, and the archival decoder). lp4 = 4-byte length prefix + UTF-8 bytes; addr = 4-byte type + key; all integers little-endian; amounts atomic (÷1e8 for ZBC). Reference for integrators building wallets and tooling on ZooBC.
