建设中

建设中:我们正在 MainNet 上线前搭建本网站,细节会有变动。

本网站仍在建设中

ZooBC 在公开中建设。你在这里看到的内容是最新且真实的,但并不完整:请把它看作我们当前的状态,而不是最终定论。

从现在到 MainNet 上线,措辞、结构、图片和数据都会有变动。部分页面仍是占位内容。

更广泛的 ZooBC 生态将分阶段到来。随着 MainNet 临近,钱包、区块浏览器和社区渠道会陆续上线,本网站也会随之成长。

如果有内容读起来不对、看起来有问题或可能造成误导,请告诉我们。现在的反馈,比日后精致的发布对我们更有价值。

ZOOBC / 开发者

开发者

程序读写这条链所需的一切。网关是一道 HTTPS 前门:它终结 TLS、进行限流,并把链 API 代理到节点,这样浏览器无需运行节点也能与 ZooBC 通信。

你要基于哪条链构建?

以下示例运行在公开的 TestNet 网关上。地址、余额和交易哈希不能跨网络通用,操作前请先确认你所在的网络。

TestNetzoobc.network
MainNetzoobc.net
链状态API 参考

MainNet 将于 2027 年 2 月 14 日上线

唯一的基础 URL

与链相关的一切都位于本网关的 /api/v1/ 之下,与本页同源,无需处理 CORS,无需申请密钥,也没有调用套餐。

zoobc.network 是公开的 ZooBC TestNet 网关,不是 MainNet。以下示例运行在测试网络上。

curl https://this-gateway/api/v1/blockchain/status

读和写会去往不同的地方,这比听上去更重要:

GET代理到归档节点,它保存着完整的历史:任意高度下的区块、交易和账户。
POST直接代理到全节点,绝不会发往归档节点。提交交易需要内存池,而归档节点是只读的历史服务,过去会对 POST 返回 404,这就是为什么一度无法通过网关广播交易。

你最先会用到的路由

/api/v1/blockchain/status高度、已确认高度、最新区块
/api/v1/blocks/latest完整的最新区块
/api/v1/accounts/<address>余额和可用余额。接受 ZBC_… 地址或原始的 36 字节十六进制
/api/v1/accounts/<address>/tokens该账户持有的所有代币
/api/v1/transactions?limit=25最近的已签名交易
/api/v1/movements/latest由链自身产生的余额变动:奖励、解锁、退款
/api/v1/exchange/markets开放的市场;…/orderbook?market=<id> 查看深度,…/offers 查看兑换包
/api/v1/tokens所有代币,含供应量和小数位数
/api/v1/release/list已发布的版本及其哈希,即 /verify 用来比对的依据
/api/v1/registry/nodes节点注册表;另见 /gateways, /relays, /archivals

有些路由只存在于归档节点上,有些只存在于全节点上。本网关会先尝试归档节点,遇到响应体为空的 404 时再重试节点 API,所以你很少需要关心哪个是哪个;但带有响应体的 404 是真实的答复,而不是走错了路。

提交交易

使用 zbc-cli 构建并签名,它通过 stdin 接收 JSON 参数,因此私钥永远不会出现在 ps 或你的 shell 历史中:

echo '{"sender_privkey":"…","recipient":"ZBC_…","amount":100000000}' \
  | zbc-cli send --json-input --api https://this-gateway

1 ZBC 等于 108 个原子单位。API 中的所有金额都以原子单位表示,传输格式中任何地方都没有小数。

在这些通道上正在构建什么

你在这里调用的交易类型,正是以下进行中工作的基础:

AI 智能体将定时转账、托管和多签用作自主智能体无法自行提高的支出上限。现已可用,并附有在公共 TestNet 上运行的零依赖 Python 参考实现。
去中心化 AI独立运营的模型专家系统,在用户端组装并公开结算,让任何一家公司都无法横亘在个人与其使用的智能之间。MainNet 之后的方向。
ProxCell面向线下当面支付的本地乐观确认,其上叠加按地理分层的结算层。工作论文。

完整参考

每个路由、它的参数和响应格式:

打开 API 参考 →  ·  另一种视图

两个地址提供同一份文档。

下载

运营者在本网关上发布的文件通过 /dl/<name> 提供。文件名是 [A-Za-z0-9._-] 的单个路径段,所有内容都以附件形式发送,绝不渲染:这个源同时也提供钱包,在这里渲染的页面会继承钱包的源。

发布包位于 /releases/<version>/<arch>/ 之下,/releases/latest 指明当前版本。节点安装程序位于 /install.

这个网关健康吗?正在检查…

/gateway/status 报告本网关对自身及其可访问节点的了解:模式、域名、白名单上有多少节点、哪些正在响应。

/gateway/system-stats 报告机器状态:CPU、内存、磁盘、运行时间。网关页面上的数据就来源于此。

curl https://this-gateway/gateway/status
curl https://this-gateway/gateway/system-stats

两者都不需要密钥,也都不公开任何链上信息;如需链上信息,请使用上面的 /api/v1/…。

访问某个特定节点

链路由的响应来自本网关所选的任意一个归档节点。要查询指定节点,请把它的 IP 写进主机名,点号改为短横线,还可以用可选的 -p<port> 选择 API 端口:

curl https://ip-192-168-1-100.this-gateway/api/v1/node/info
curl https://ip-192-168-1-100-p8080.this-gateway/api/v1/node/info

只有本网关白名单上的节点才会响应。其他请求一律拒绝而不代理,因此无法利用主机名通过网关访问任意主机。

中继

语音、视频和屏幕共享采用点对点传输;当防火墙阻断直连时,由中继有偿转发流量。/relay/info 会报告中继的地址、费率以及它所结算的链的创世哈希,钱包在付款前会将其与自己节点的创世哈希比对,因为另一条链上的中继无法入账它收到的付款。

curl https://this-gateway/relay/info

管理面板

网关自身的控制界面位于 zoobc.network/admin。它由 /etc/zoobc/gateway.json 中的 admin_api_key 保护,该密钥由安装程序为每台机器单独生成,不存在默认密钥。

白名单

网关只会代理到它被告知的节点。正是这份名单,防止 ip-… 形式的主机名把网关变成开放代理。

POST /gateway/allowlist/add加入一个节点, {"ip":"…","port":8080}
POST /gateway/allowlist/remove移除一个节点
POST /gateway/allowlist/refresh重新读取注册表并重新检查健康状态
GET /gateway/allowlist当前已加入的节点

这三种写操作都需要管理员密钥。在公开模式下,网关还会从链自身的注册表中发现节点;在私有模式下,它只使用 static_nodes.

发布工具

文件哈希工具在浏览器中计算 SHA-256,适合任何你想手动核验的文件;/verify 则将下载的发布包与链上公布的哈希进行比对。

两份文档

硬件钱包团队所需的一切都在这里说明,完整内容见下面两份 PDF。两份文档均已针对 ZooBC 节点 v0.4.0(zoobc-main 分支的 7ad161a4 提交)以及一个实时 v0.4.0 节点所接受的交易向量进行了验证。

2.1 版在一个实质性方面取代了草案 1:交易签名现在与链绑定。对于基于草案 1 开发的人来说,有两项是破坏性变更:签名摘要和 ApprovalEscrow 主体。旧的 v0.3.2 构造已没有任何实现,因此请只依据当前文档开发。

一页摘要

签名方案Ed25519(RFC 8032,纯 Ed25519,无预哈希变体,无上下文字符串)。64 字节签名,32 字节公钥。
签名对象Ed25519.sign(sk, SHA3-256("ZBC-TX" ‖ genesis_hash(32) ‖ unsigned_bytes))。这个 32 字节的摘要就是 Ed25519 的消息。
链绑定摘要涵盖链的创世区块哈希,因此为一条链生成的签名无法在另一条链上重放。传输格式不变;创世哈希不是交易字段。
签名标签"ZBC-TX",六个 ASCII 字节 5a 42 43 2d 54 58。没有终止符,也没有长度前缀。
哈希函数SHA3-256(FIPS 202)。不是 Keccak-256,也不是 SHA-256。
密钥派生BIP-39 助记词,然后生成种子(PBKDF2-HMAC-SHA512,2048 轮),再经 SLIP-0010 Ed25519 派生,路径为 m/44'/883'/account'。三个硬化层级,没有找零或索引层级。
SLIP-44 币种类型883 (已注册: 883 | ZBC | ZooBC).
账户(传输格式)36 字节:u32le(0) ‖ pubkey(32)。JSON API 接受的是十六进制形式。
地址(显示)ZBC_ 加上 56 个 base32 字符,分为 7 组,每组 8 个。3 字节校验和 = SHA3-256(pubkey ‖ "ZBC")[0..3].
版本字节0x01,保持不变。它没有因链绑定而递增,也不用于区分版本。
原生单位1 ZBC = 100 000 000 原子单位(8 位小数)。金额和手续费均为 u64 小端序原子单位。
字节序传输中的所有内容都是小端序,SLIP-0010 子索引除外(按标准为大端序)。
交易哈希tx_hash = SHA3-256(unsigned_bytes ‖ signature); tx_id = int64le(tx_hash[0..8])。创世哈希只参与签名摘要的计算。
重放保护链绑定,加上哈希唯一性,再加上 3600 秒的打包窗口。没有 nonce。
最低手续费基础费用 0.025 ZBC(2 500 000 原子单位)乘以网络手续费系数,再加上按大小计算的租金。可向节点查询: GET /api/v1/blockchain/estimate-fee.
一级交易类型1 SendZBC, 11 TransferToken, 4 ApprovalEscrow.
链发现GET /api/v1/node/info 返回 genesis_hash、signing_version: 2 和 signing_tag: "ZBC-TX"。请从你将要广播的端点读取。

先读这四点

这四点对实现的影响超过其他所有内容。

1没有 nonce,也没有未签名交易端点。ZooBC 基于账户模型,但在这里,账户模型并不意味着二者之一。由主机自行序列化交易;下文的布局完整无缺,并由测试向量固定。
2签名覆盖的是带标签的前缀,即 "ZBC-TX" 加上链的创世哈希,而不仅仅是交易字节。弄错这一点,每个签名都会以一个笼统的错误失败。
3广播端点不接受已签名交易的二进制数据。它接受的是交易主体字节加上以命名 JSON 键表示的信封,并自行重建信封。
4历史记录按从新到旧返回,受 limit 限制。两个端点结合起来才能得到完整视图,而且金额取决于交易类型,并非信封字段。

密钥派生与地址

参考实现:zoobc-signer/extension/lib/zoobc-crypto.js,与参考钱包逐字节一致;节点端的对应实现位于 src/crypto/slip10.cpp.

seed = PBKDF2-HMAC-SHA512(NFKD(mnemonic), "mnemonic" + passphrase, 2048, 64)
I    = HMAC-SHA512("ed25519 seed", seed);  k = I[0..32], c = I[32..64]

for index in [44, 883, account]:                       # all hardened
    data = 0x00 || k || u32be(index + 0x80000000)
    I    = HMAC-SHA512(c, data);  k = I[0..32], c = I[32..64]

pubkey = Ed25519.publicKeyFromSeed(k)                  # k is the 32-byte seed

账户 0 是 m/44'/883'/0',账户 1 是 m/44'/883'/1',依此类推。密钥派生不受链绑定影响:一套密钥适用于所有 ZooBC 链,只有签名不同。

显示地址由公钥生成,而不是由 36 字节的账户生成:

buf[35] = pubkey(32) || "ZBC"
h       = SHA3-256(buf);  buf[32..35] = h[0..3]        # 3-byte checksum
s       = base32(buf)                                   # RFC 4648 A-Z2-7, no padding, 56 chars
address = "ZBC_" + s[0..8] + "_" + s[8..16] + ...       # 7 groups, canonical length 66

解码时接受下划线、短横线、空格或无分隔符,大小写均可,并且必须重新计算并比对校验和。上面的 3 字节 SHA3 校验和就是代码和链所使用的定义,因此请依据它来实现,也可参考规范中的参考实现,它能复现文中的示例地址。

未签名交易的传输格式

权威来源:src/util/transaction_util.cpp:144-270。传输格式在 v0.4.0 中没有变化。下面的任何长度或偏移量都不受链绑定影响。

#大小字段说明
14transaction_typeu32le,见下方类型目录
21版本始终为 0x01;节点会拒绝其他任何值
38时间戳u64le,Unix 秒数,大于 0
436发送方00000000 ‖ pubkey(32),适用于 ZBC 签名者
54 或 4+n接收方ZBC 为 36 字节;其他类型为 u32le(type) ‖ payload;没有接收方时仅为 02 00 00 00
68手续费u64le,原子单位
74body_lengthu32le
8n主体按类型的布局
94 或可变托管无托管:4 个字节 02 00 00 00。有托管:approver(36) ‖ commission u64le ‖ timeout u64le ‖ instr_len u32le ‖ instruction ‖ multi_party(1)
104message_lengthu32le
11m消息纯文本,普通交易不超过 256 字节

托管块末尾的 multi_party 字节是必需的。省略它,或用其他值写入无托管标记,节点只会返回“Invalid transaction signature”,没有任何进一步的诊断信息。

完整示例(经链验证)

向自己发送 1 ZBC 的 SendZBC,手续费 0.05 ZBC,时间戳 1700000000,无托管,无消息。这是规范中七个向量里的向量 0。

01000000                 type = 1 (SendZBC)
01                       version
00f1536500000000         timestamp 1700000000
00000000 5e8eb28d...2152 sender    (type 0 + pubkey)
00000000 5e8eb28d...2152 recipient (type 0 + pubkey)
404b4c0000000000         fee 5 000 000
08000000                 body length 8
00e1f50500000000         body: amount 100 000 000
02000000                 no-escrow marker
00000000                 message length 0

共 113 字节。签名原像会在前面再加 38 字节:

5a42432d5458              tag "ZBC-TX"          6 bytes
090ab3c7...a61878         genesis hash         32 bytes
0100000001...00000000     the 113 bytes above 113 bytes
                                              ---------
                                              151 bytes

digest = SHA3-256(preimage) = f37e5340...4644fc,签名 9a3b044d...03bb07,tx_hash = f00a6692...ce78b0。一个实时 v0.4.0 节点返回了 HTTP 202 和完全相同的哈希。

签名流程(设备端)

input : account_index, genesis_hash(32), unsigned_bytes

1. k      = SLIP10(m/44'/883'/account_index')
2. pub    = Ed25519.pub(k);  self = 00000000 || pub
3. parse unsigned_bytes; every length must land exactly at the end
4. require version == 1 and sender == self
5. decode body per type; render the approval screen; wait for the user
6. digest = SHA3-256("ZBC-TX" || genesis_hash || unsigned_bytes)
7. sig    = Ed25519.sign(k, digest)          # the digest IS the message
8. return sig(64), and tx_hash = SHA3-256(unsigned_bytes || sig) for the host to cross-check

使用流式 SHA3,这样第 6 步就不需要把整笔交易放进 RAM。依次输入 6 个标签字节、32 个创世字节,然后是交易本身。

标签是整份规范中最容易出现的实现错误。"ZBC-TX" 是六个 ASCII 字节 5a 42 43 2d 54 58,没有 NUL 终止符,也没有长度前缀。如果固件给字符串加上终止符,或写入七个字节,就会生成一个看似有效、却在链上以笼统错误失败且没有任何诊断信息的签名。请先用向量 0 测试这一点。

链绑定能做什么、不能做什么

32 个创世字节由主机提供,设备不会自行查找。因此签名与具体链无关,同一条代码路径适用于 TestNet、devnet、MainNet,以及任何私有或并行的 ZooBC 链。

能阻止跨链重放。为链 A 生成的签名无法在链 B 上通过验证。这正是它的设计目的,而且完全做到了。
不能阻止被攻破的主机指定错误的链。设备会为交给它的任何哈希签名。

因此,固件中仍需要一张已知创世哈希表,但只用于一个目的:在屏幕上显示可信的网络名称;当哈希不在表中时,回退为显示“UNKNOWN CHAIN”加上前 8 位十六进制。

不要默认拒绝无法识别的链。Devnet 的哈希每次重新启动都会改变,而私有链或并行链在 ZooBC 上很常见,所以一刀切地拒绝会让设备无法用于集成和合法部署。如果厂商需要这种锁定,请将其设为明确的用户设置,并默认关闭。

交易类型:标准固件应支持哪些

类型 id = group + 256 × subtype。共有五十六种类型。这三种涵盖支付 ZBC、支付任意代币和完成托管,而且它们的主体小而固定。

id名称主体接收方
1SendZBCamount u64le (8)必需,任意类型
11TransferTokentoken_id i64le (8) ‖ amount i64le (8) ‖ 可选 fee_in_token u8必需
4ApprovalEscrowapproval u32le ‖ escrowed_transaction_hash (32) = 36 字节空标记;发送方即审批人

token_id 是由哈希派生的有符号 64 位值,因此可能为负数。创世币的 id 为 1 到 14;ZBC 本身的 id 为 0,从不出现在 TransferToken 中。每种代币都有自己的 decimals(0 到 8),设备无法验证。

ApprovalEscrow 在 v0.4.0 中有变化。主体原先是 approval 加一个 8 字节 id(12 字节);现在是 approval 加被托管交易的 32 字节哈希(36 字节),解析器会拒绝任何其他长度。原因直接与硬件钱包有关:只看到 8 字节 id 的签名者无法核实自己在释放什么,而攻击者可以针对展示给设备的伪造托管,通过 2^64 次搜索找到匹配的 8 字节 id。有了完整哈希,设备就能验证它所批准的内容。

设备要验证什么

结构解析 11 个字段。每个长度前缀必须一致,缓冲区必须恰好在消息之后结束。否则一律拒绝。
版本必须为 1。
发送方必须等于设备针对所请求路径自行派生的账户。设备从不信任传给它的发送方字节,而是重新派生并比对全部 36 个字节。这就是“资金从哪里来”的全部保证。
类型必须属于支持的类型集合,或已开启专家模式。
主体长度8 (SendZBC),16 或 17(TransferToken),36(ApprovalEscrow)。有多余字节:拒绝。节点会接受更长的 SendZBC 主体并忽略尾部,而隐藏的载荷正是这样夹带进来的。
托管超时必须大于交易时间戳。
创世哈希必须恰好为 32 字节。设备不会对照列表验证它,但长度错误即属于格式错误的请求。
绝不接受预先计算好的摘要来签名。设备自行对字节进行哈希,包括标签和创世哈希。
大小上限建议:未签名交易不超过 2 KB,消息 256 B,托管指令 512 B,超出者一律以 TOO_LARGE 拒绝。一级交易都小于 300 字节,但 ApprovalEscrow 会附带第二笔交易用于验证,因此上限必须覆盖两个缓冲区。更大的载荷应交给软件钱包处理。

用户在屏幕上批准的内容

每屏一项,按以下顺序,改编自经链验证的参考签名器。

网络根据所提供的创世哈希,从固件的表中取名称;不在表中时显示“UNKNOWN CHAIN”加前 8 位十六进制。
类型“Send ZBC”、“Send token”、“Approve escrow”。
金额amount / 1e8 ,附 ZBC 符号。
接收方完整地址,绝不省略。中间省略的地址,恰恰会被靠靓号生成的相似密钥攻破。
手续费原子单位 / 1e8 ZBC。
转出总额金额加手续费合计为一个数字,仅适用于 ZBC 金额。代币金额和 ZBC 手续费单位不同,不得相加。
消息可打印时直接显示,否则显示“N bytes (binary)”加上其 SHA3-256 的前 8 位十六进制。
托管完整的审批人、佣金、以日期和时间表示的超时、指令文本。
代币(类型 11)代币 id(有符号十进制)和原子单位金额。如果主机提供 decimals 或 symbol 作为显示提示,则显示缩放后的金额并标注“as reported by the app”,因为设备无法验证它们。
托管审批以大号字体显示“APPROVE”或“REJECT”,然后是已验证的托管详情,最后是手续费。

时间戳无需显示。它们对用户没有实际意义,且时间窗口由节点强制执行。

主机与设备协议

传输层使用厂商自己的 USB/HID 层及其现有的分块机制。重要的是内容。

命令请求响应
GET_APP_VERSION无固件版本、支持的类型集合、最大交易大小
GET_PUBLIC_KEYaccount_index, confirm_on_devicepubkey(32), address (66 个字符的字符串)。确认时,设备显示完整地址,供用户与网站上的地址比对。
SIGN_TXaccount_index, genesis_hash(32), unsigned_tx_bytessignature(64), tx_hash(32),或带类型的拒绝: SENDER_MISMATCH, UNSUPPORTED_TYPE, MALFORMED, USER_REJECTED, TOO_LARGE, ESCROW_HASH_MISMATCH
SIGN_MESSAGEaccount_index, message_bytessignature(64),原始 Ed25519 签名,见下方规则

genesis_hash 是关键参数,而不是显示提示。在草案 1 中,网络参数可以是一个枚举值,因为它只用来选择标签。现在它位于摘要之内,因此必须是真实的 32 个字节,错误的值会产生任何链都不会接受的签名。

原始签名规则。原始签名命令绝不能对恰好 32 字节的输入签名,并且只应对能以文本显示的输入签名。32 字节的原始输入可能是用户从未见过的某笔交易的 SHA3 摘要,这会把消息命令变成盲签交易。拒绝长度为 32 的输入即可堵住这个漏洞,无需对链做任何改动。

完整流程

Website (page)         Companion / host           device                    Gateway / node
   |-- connect ---------->|                            |                          |
   |                      |-- GET_PUBLIC_KEY(0) ----->|  (shows ZBC_... address) |
   |<-- address ----------|<-- pubkey, address -------|                          |
   |-- GET /api/v1/node/info  (genesis_hash, signing_version, height) ---------->|
   |-- GET /api/v1/accounts/<addr>  (balances) --------------------------------->|
   |-- GET /api/v1/accounts/<addr>/tokens, /api/v1/tokens/<id> (decimals) ------>|
   |   user fills the form                             |                          |
   |-- GET /api/v1/blockchain/estimate-fee?type=1&body_length=8 ---------------->|
   |<-- {minimum_fee, timestamp} ------------------------------------------------|
   |-- fields {type, recipient, body, fee, message} -->|                          |
   |                      |  serialize the 11 fields   |                          |
   |                      |-- SIGN_TX(0, genesis, -->|  parse, verify, display,  |
   |                      |            bytes)         |  user approves            |
   |                      |<-- signature, tx_hash ---|                          |
   |<-- signature --------|                            |                          |
   |-- POST /api/v1/transactions {JSON} ---------------------------------------->|
   |<-- 202 {status:"success", transaction_hash} --------------------------------|
   |-- GET /api/v1/transactions/<hash>/status  (staging, mempool, confirmed) --->|

主机将节点返回的 transaction_hash 与设备返回的 tx_hash 进行比对。两者必须完全相同,否则说明主机在签名后篡改了字节。

从你将要广播的端点读取 genesis_hash 和 signing_version,因为评判签名的正是那条链。

链身份

ZooBC 唯一的网络标识符是创世区块哈希。节点在建立对等连接前会比对它;没有网络 id 字节。GET /api/v1/node/info 会连同 v0.4.0 新增的两个字段一起返回它:

"genesis_hash": "090ab3c7...", "signing_version": 2, "signing_tag": "ZBC-TX"

signing_version 缺失,表示该节点早于 v0.4.0,执行的是旧版未与链绑定的摘要。只支持当前链的主机可以把它的缺失视为“不要在此签名”。节点输出小写十六进制,而归档 API 输出大写,因此解码时应不区分大小写,如有前导 0x 则去掉。两种情况下字节都相同。

从哪里读取。网关对 /api/v1/node/info 的应答来自归档服务,而不是节点。归档服务会透传它所镜像节点的两个签名字段,自 7ad161a4 构建起,只要节点报告了这两个字段就会原样输出。请从节点端点读取 signing_version,或从运行该构建或更新版本的网关读取,并把字段缺失视为“去问节点”,而不是一个答案。

广播

POST /api/v1/transactions. 在 v0.4.0 中没有变化,也没有新字段。transaction_body_bytes 是仅主体:节点根据命名字段重建信封,在前面加上它自己的创世哈希和标签,然后重新计算摘要,因此每个字段都必须与签名时完全一致。

{
  "version": 1,
  "timestamp": 1700000000,
  "transaction_type": 1,
  "fee": 5000000,
  "sender_account_address":    "00000000 5e8eb28d ... 2152",
  "recipient_account_address": "00000000 5e8eb28d ... 2152",
  "transaction_body_bytes": "00e1f50500000000",
  "signature": "9a3b044d ... 03bb07",
  "message_hex": "...optional...",
  "escrow": { "approver_address": "...", "commission": 0, "timeout": 1700003600 }
}

成功时返回 HTTP 202 和 {"status":"success","duplicate":false,"transaction_hash":"..."}。duplicate:true 表示节点已持有该交易,请勿重新发送。200 也应视为成功。失败时返回 400 和错误响应体,负载过高时返回 503。

一个有用的集成测试:暂存池会先检查签名,因此一笔交易如果遇到后续错误(例如“Sender account does not exist”),说明它已经通过了签名验证。你可以用一个没有资金的密钥来验证你的签名流程。

签名被拒绝时

目前,链不匹配与其他任何签名失败无法区分。旧版摘要和错误链的摘要都会返回完全相同的响应体:

{"success":false,"error":"Transaction validation failed: ValidationError: Invalid transaction signature","code":400}

因此请按以下顺序逐一排查原因,可能性最大的排在前面:

1遗漏了标签,或以 NUL 结尾,或写成了七个字节。
2使用了 Keccak-256 而不是 SHA3-256。
3创世哈希与要广播到的链不匹配。
4遗漏了托管末尾的 multi_party 字节。
5ApprovalEscrow 主体仍为 12 字节,而不是 36 字节。

开发对接的端点

链网关(HTTPS)签名说明
testnethttps://this-gateway正在迁移至 v0.4.0切换完成后即为集成目标
devnethttps://socialconnect.networkv0.4.011 个节点,水龙头位于 /faucet;每次重新启动时创世哈希都会改变
mainnet尚未上线v0.4.0 或更高版本上线后从链上读取其创世哈希

读取请求依次路由到归档节点、网关、节点。广播请发往网关或节点,绝不要发往归档端点.

在运行时读取创世哈希,不要硬编码。devnet 的创世哈希在每次重新启动时都会变化。固件中的哈希表只用于在屏幕上显示名称,因此过期的条目只会降级显示为“UNKNOWN CHAIN”,而不会破坏签名。当 devnet 的哈希确实改变时,此前生成的所有签名都会失效,这正是该机制在正常工作。