转移价值。转移数据。一切由你决定。
ZooBC 交易是一个已签名的信封,内含一个小型的类型化主体。信封对所有类型都相同,由主体和少数可选的修饰符决定实际发生什么:普通发送、代币转账、分期解锁的薪资、托管交易、应用走子、定时触发。这是一张完整的地图。
01交易的结构
所有内容以小端序序列化为一个字节缓冲区,然后签名。蓝色字段是信封(所有类型相同);紫色的主体则随类型而变化。
账户地址由 4 字节类型(LE)+ 公钥组成:ZBC 为 00000000+32B ed25519,此外还有 04000000+ETH、05000000+BTC 等。缺失的收款人写为空类型 02000000。消息尾部是普通发送携带备注的位置,SendZBC 的主体仅包含金额;收款人和备注都位于信封中。
02签名
账户类型同时决定地址前缀和签名方案。对整个信封(不含签名字段)签名,并在前面加上签名标签和创世哈希。三种方案都是确定性的,因此浏览器钱包和节点能做到逐字节一致。
ZooBC(ed25519)· 类型 00000000
// digest, then sign digest = SHA3_256("ZBC-TX" ‖ genesis_hash ‖ txBytes) sig = ed25519(digest, privkey) // 64 bytes
Solana、Cardano、Tezos、Polkadot 也使用该方案:相同的 ed25519 密钥,不同的地址前缀和显示编码。
以太坊(secp256k1)· 类型 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 也可以发送其自行签名的 RLP;节点会恢复出发送方,并将其映射为一笔 ZBC 转账。
比特币(secp256k1)· 类型 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
手续费简述
最低手续费与交易大小相关:基础费率 × 网络手续费系数,再加上按字节计算的存储/时长部分。可从 https://zoobc.network/api/v1/blockchain/fee-params 实时读取,或用 /estimate-fee 为某笔交易精确定价,这样钱包与节点的计算结果就能精确一致到原子单位。精确手续费发送中多付的部分会被退还。
与链绑定的摘要(签名版本 2)
自节点 v0.4.0 起,三种方案中最内层的项都相同,因为节点只计算一次该摘要,然后将其交给账户类型所选择的签名方案。
- "ZBC-TX" 是六个 ASCII 字节,不含终止符: 5a 42 43 2d 54 58.
- genesis_hash 是待签名链上第 0 号区块的 32 个原始字节。
从 GET /api/v1/node/info 读取 genesis_hash;同一响应中还包含 signing_version: 2 和 signing_tag: "ZBC-TX"。切勿硬编码:每次测试网络重新启动时它都会改变。
将创世哈希绑定进摘要,使签名只在唯一一个网络上有效,因此为测试链签名的交易无法被重放到另一条链上。直接对 SHA3_256(txBytes) 签名属于签名版本 1,节点会拒绝并返回:
Invalid transaction signature: legacy unbound digest (signing v1); this chain requires signing v2
03三类币种
金额始终以原子单位表示(1 ZBC = 100,000,000)。不同币种之间唯一的区别是 token_id 字段,转移机制完全相同。
① 原生 ZBC
所有地方都是 token_id = 0。它是 gas/手续费币,用于区块奖励和质押。SendZBC(类型 1)是最直接的方式。
② 创世 / 跨链桥代币
在创世时铸造的包装外部资产(ZBTC、ZETH、ZSOL…)。它们是普通的染色代币,拥有在创世配置中分配的固定 token_id,在协议层面并无特殊之处。
③ 用户发行的代币
任何人都可以用 IssueToken(类型 10)铸造代币:符号、供应量、小数位、可选的 ZBC 储备。其 token_id 由发行交易派生。同样适用 TransferToken / MintToken / BurnToken。
凡是主体中有 token_id 的地方(转账、兑换、应用质押、流动支付、解锁…),ZBC 传入 0,染色币则传入该代币的 ID。有储备的代币甚至可以支付自己的手续费(fee_in_token 标志),按其 ZBC 储备定价。
04修饰符:一笔支付,多种形态
除基础类型外,四种时间/信任包装器会改变资金何时以及是否真正到账。正是它们让功能显得如此丰富。
托管
在任何价值交易的信封后附加一个托管段(审批人 · 佣金 · 超时 · 说明)。资金会被冻结,直到指定的审批人签署 ApprovalEscrow(类型 4)予以释放或拒绝,或超时到期。这相当于在任何转账之上叠加一笔条件交易。
流动支付
LiquidPayment(类型 6):在一个时间窗口内的单笔延迟支付。窗口结束时收款人获得全额;如果发送方提前执行 LiquidPaymentStop(类型 262),则收款人按比例获得相应部分。适用于短期(数小时),可用 ZBC 或代币。
定时 / 解锁
ScheduledTransfer(类型 29):按计时器分期释放,可以是解锁(资金预先锁定)或定期薪资(每期扣款)。支持悬崖期、撤销、收款人拒绝、重新指派。适用于长期(数周至数年)。释放以账本变动的形式显示,而不是新的交易。
触发 / 停止
轻量级计时器:CreateTrigger(15)锁定一笔金额,在未来某个高度触发;CancelTrigger(16)将其退还。停止长期支付:CancelSchedule(30)用于撤销/拒绝,LiquidPaymentStop (262).
它们可以叠加。一份同时带托管的月薪、一笔以染色代币发放的解锁授予,这些基础组件可以自由组合。(定期支付与托管的完整组合已列入路线图;所需的构建模块现在都已就绪。)
05让数据对象持续存活
承载数据的链上对象,包括数据集(键/值资料、聊天、商务表单)和代币,需要支付租金才能持续存在。“为对象添加资金”是指为其存续融资充值。
数据集与文件 → 预付存储
你可以用 SetupAccountDataset(类型 3,一个属性 → 值对)写入数据,或用 DFSCreateFile(8)存储文件。每个区块都会从你账户的预付存储中扣除存储租金;余额耗尽时对象会被清除。用 AddPrepaidStorage(类型 9)充值,其主体只是一个金额,直接计入你的预付存储余额。预付越多,存续越久。
代币 → 存续融资
染色代币同样需要付费才能存续。FinanceToken(类型 14)用手续费延长代币的存续期限,从而推迟其未使用储备退还给创建者的时间。思路相同,只是按代币计算。
06完整交易目录
全部 50 种交易类型,附其精确的小端序主体布局。币种 = 支持 token_id · 可修饰 = 接受托管段 · 新链 = 共识层级(随新链启动发布)。