ZooBC 维基
应用与在 ZooBC 上开发

用一个 HTML 页面构建应用

ZooBC 应用程序可以是一个背后没有服务器的单个 HTML 文件。页面从节点的 HTTP API 读取链,在浏览器中用用户的密钥构造并签署交易,然后提交签名后的字节。用户不需要运行节点,也没有需要申请的 API 密钥。官方钱包就是证明:它本身就是一个 HTML 文件,每个节点都在 / 和 /wallet 提供它(网页钱包)。

一个 HTML 文件用 GET 读取,在浏览器中签名,并把签名后的字节提交给节点或网关。
一个 HTML 文件用 GET 读取,在浏览器中签名,并把签名后的字节提交给节点或网关。

节点 API

每个节点都提供明文的 HTTP/1.1 API,默认端口为 8080,在 /api/v1/ 下有一百多个路由:区块、账户、代币、应用、交易所等(节点 API)。每个响应都带有以下响应头,OPTIONS 请求会立即得到 200 应答,因此托管在任何地方的页面都可以调用任何节点:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, X-Node-Public-Key, X-Timestamp, X-Signature

节点本身没有 TLS。公共域名在网关处终止 TLS,网关会加上自己的 CORS 响应头。浏览器会阻止通过 HTTPS 加载的页面发起明文 HTTP 调用,因此公开页面要与网关通信。

除八个路由外,其余都是无需认证的读取;提交交易也不需要任何密钥,因为交易自带签名。限制按客户端地址计算:每分钟 300 次写请求,超出后返回 429 并附带 Retry-After 响应头;除非运营者设置了限制,读取不受限;5 分钟内 20 次签名认证失败会让该客户端被锁定 300 秒。

在浏览器中签名

页面签署一个把交易绑定到一条链的摘要:

digest = SHA3-256("ZBC-TX" ‖ genesis hash ‖ unsigned transaction bytes)

原生账户用 Ed25519 签署它。页面从 GET /api/v1/node/info 读取 genesis_hash 和 signing_version(2);由于创世哈希在摘要之内,为一条链做出的签名在另一条链上毫无用处(链绑定签名)。不需要 SDK:Ed25519、SHA3-256 和创世哈希就足够了,字节布局见 交易信封。公开工具还提供现成的库,包括一个无依赖、可用 script 标签引入的 JavaScript 文件(命令行工具)。密钥从不离开页面。

提交与跟踪

POST /api/v1/transactions               → 202, with "transaction_hash"
GET  /api/v1/transactions/<hash>/status → staging, mempool, confirmed (with block_height),
                                          rejected (with the reason and stage), or 404 not_found

202 的意思是已接受,而不是已完成。节点已解析该交易,运行了初步检查,并把它收进暂存区;出块者仍需把它打包进区块。在状态显示为 confirmed 之前,没有任何余额发生变化。按每 15 秒一个区块计算,每隔几秒轮询一次就足够了。

如果回应丢失,就重发完全相同的已签名字节。交易的哈希是未签名字节与签名的 SHA3-256,因此已经持有该交易的节点会回应 202 并带上 "duplicate": true,交易进入区块后还会加上 "state": "confirmed",而交易只执行一次。用新的时间戳重新签名会生成另一笔不同的交易,重复付款就是这样发生的。

默认情况下,交易可以在其时间戳之后最多 3,600 秒内被打包进区块;版本 3 交易自行声明其窗口,最长 86,400 秒;时间戳超前未来 3,600 秒以上的交易会被拒绝(有效期与时间戳)。在凭一笔付款发货之前,先等待确认,再等待 finalized 标志:当一个联署的脊链区块覆盖交易所在的区块时,交易就获得该标志(最终性与回滚)。API 还会报告 finalized_height、每个区块的 block_seed_proof、交易的 expiry,以及位于 /spine/blocks/:height 的脊链区块。

202 之后:暂存、内存池、已确认、已最终确定;回应丢失时用相同的字节重发。
202 之后:暂存、内存池、已确认、已最终确定;回应丢失时用相同的字节重发。

应用的路由

应用路由由节点本身而不是归档服务提供:/apps(筛选参数为 status、limit 和 category,后者取 solo、pvp 或 party)、/apps/open、/apps/pool、/apps/stats、/apps/:id(若有结算则一并返回)和 /accounts/:a/apps。

检查清单

  • 通过网关以 HTTPS 读取;通过提交已签名字节写入,密钥保留在页面中。
  • 按哈希跟踪;重试时重发相同的字节,绝不重新签名。
  • 遵守 429 和 Retry-After。
  • 用 textContent 显示链上文本(链上数据是不可信的输入)。
  • 把“confirmed”视为已收到,把“finalized”视为已结清。

另见