查询”这几笔钱还在不在”,通常是钱包和后端服务的日常。常规做法是对每个输出点各调一次 RPC,问十五次网络往返十五次。比特币核心的 REST 接口里其实藏着一个批量入口:/rest/getutxos,一次请求最多核十五个输出点,返回一张花费位图。本文按 v31.0 源码拆解它的请求形状、限额与返回结构,以及最容易被误用的两个点。
前提:REST 默认是关的
v31.0 源码里 REST 的默认开关是关。也就是说,想用一个不带认证口令的 HTTP 口查链,得先显式打开 -rest 再重启节点。这个默认值本身就是一句风险提示:REST 端点不需要 RPC 凭据,打开等于向能访问这个端口的所有来源开放只读查询。它只该暴露在你信任的网络里。
请求怎么拼
最直观的用法走 URL 路径:把每个输出点写成”交易哈希加连字符加输出序号”,依次串在端点后面,例如 /rest/getutxos/txid-0/txid-1.json。如果想在查询时把内存池也考虑进去,在路径最前面加一段 checkmempool。要拿二进制或十六进制编码的紧凑返回,则把查询以请求体的形式发过来,让输入格式与输出格式保持一致——源码的注释专门强调了这条对称约定。两种投法可以选,但不能混:路径里给了输出点、请求体里又塞一份,会被直接拒绝。
限额是一条硬杠:一次最多十五个输出点,超了会收到写明”最大输出点数超出”的 400 错误,消息里连你这次传了多少都会报出来。做批量轮询的系统要把每批切在十五条以内,并处理”被拒绝”与”查无此币”两种完全不同的失败。
返回长什么样
JSON 返回是一组固定字段:当前链高度与链顶哈希、一张位图、以及一个 UTXO 数组。位图的每一位对应你问的一个输出点,一表示这台节点的当前链上还能找到这笔未花费,零表示花掉了或者压根没找到——注意数组只收录命中的输出点,长度未必等于请求长度,位置对应关系完全靠位图找回,解析时别按”数组第几项对应请求第几个”来写。返回同时带上链高度与链顶哈希,是为了让调用方意识到这份答案只对那个链尖成立。
如果传了 checkmempool,内存池里的花费也算数——被在途交易花掉的输出会标记为零。不传时,内存池的花费不作数,答案只反映已确认世界的状态。同一个输出点,传与不传可以给出不同结果,这是最常见的误读来源。
两个常见的误用
第一,把 REST 当作带证明的权威来源。这个端点回复的是这台节点的视角,不含默克尔证明,链顶哈希也只是让调用方能察觉答案随链尖变化。需要可验证性的场景,要走能提供证明的路径。第二,把它当作无风险的公网接口。REST 没有认证,一旦端口暴露,任何人都能批量探测你关心的输出点,顺带泄露你的监听范围——这类隐私成本在”顺手开了 -rest”的决定里几乎从不被计算。
选哪种编码,以及和 RPC 的分工
JSON 格式适合人工核查与简单集成;二进制与十六进制格式把同样的信息压进最原始的序列化流——链高、链顶哈希、位图、逐枚 coin 依次排列——体积更小,代价是解析代码要自己处理序列化规则。低频核查用 JSON 最省心,轮询频率高、或需要把结果直接送进存储层时,紧凑格式才值得付出解析成本。另一侧的对照是 RPC 的逐笔查询命令:它需要凭据、一次答一孔、返回结构是 RPC 风格;REST 批量端点则像一个免认证的体检口。选哪边取决于你的系统栈是否已经配好凭据管理,还是更愿意向内网暴露一个只读端口——但无论哪边,答案都是这台节点的视角,这一点不因编码格式而变。
风险提示:本文讨论节点查询接口的方法与边界,不构成投资建议;端点行为、限额与返回结构以比特币核心 v31.0 源码为准,不同版本的接口形态可能调整。
参考来源
- 比特币核心 v31.0 源码 src/rest.cpp(GitHub):https://github.com/bitcoin/bitcoin/blob/v31.0/src/rest.cpp
- 比特币核心 v31.0 源码 src/init.cpp(GitHub):https://github.com/bitcoin/bitcoin/blob/v31.0/src/init.cpp
- BIP-64 getutxo 提案(GitHub):https://github.com/bitcoin/bips/blob/master/bip-0064.mediawiki
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。