gettxoutproof 为什么时灵时不灵:默克尔证明与 txindex 的分工 图 1
gettxoutproof 为什么时灵时不灵:默克尔证明与 txindex 的分工 · 图 1

把默克尔证明从节点里取出来给人看

比特币的信任来自验证,而不是听谁说的。有一对互补的 RPC 专门把这种可验证性打包成一小段数据:gettxoutproof 生成证明,verifytxoutproof 校验证明。它们的组合让你能向一个不信任你的对方,也不泄露其他任何交易信息地,证明某笔交易确实进了某个区块。

证明里装了什么

gettxoutproof 接收一组交易哈希,可选地指定区块哈希,返回一段十六进制编码的序列化数据。内容是一枚区块头加上从目标交易到默克尔根所需的那条哈希路径。验证者拿到后自己做两件事:对区块头两次 SHA-256 得到区块哈希,对照它是否落在你声称的那条链上、累计工作量是否足够;沿路径重算默克尔根,和区块头里承诺的根比对。两条都过,数学上就锁死了这些交易在该区块中这个位置的事实,中间多算一个哈希都过不了。

坑在可用性,不在数学

官方文档特意标注了一个注意事项:默认情况下这个函数只是有时能用——只有当该交易还有未花费输出留在 UTXO 集合里时,节点才找得到它的落块位置。原因是节点默认不维护全交易索引:交易一旦花掉,历史位置只能靠交易索引或区块索引回翻。要让证明永远可生成,两个办法:启用 -txindex,或者调用时手工带上当初那个区块的哈希。审计和客服场景最常见的失败就是交易已被花掉又没开索引,此时先查区块浏览器或自己的归档日志找回块高,再带参数重生成。

校验侧的边界

verifytxoutproof 不联网、不查库,它独立检查证明里的区块头哈希与默克尔路径,返回证明中的交易哈希列表,但不会告诉你这笔交易此刻是否仍未花费、是否被重组。因此严谨的验收流程是:先校验证明格式与默克尔根,再取证明内的区块哈希和本地链的该高度做交叉比对。闪电网络、跨链原子交换、法律存证用的都是同一族思路,区别只在把证明送到哪条链上核。对普通人,这对命令的意义是记住一句话:能被证明的才是事实,能截图的不算。字段与行为细节以比特币核心当前版本文档为准,本文不构成任何建议。

证明与轻钱包验证的谱系

这对 RPC 是比特币可验证信息的最小样品。往上一层,SPV 钱包把同族思想用默克尔树加区块头流做成整套自助验证,靠的是工作量最高的链上累计;再往上一层,BIP 157 的紧凑过滤器让客户端在几乎不花带宽的情况下筛出可能相关的区块,再取默克尔证明确认。三层是同一条光谱:你下载的越少,越需要事后能补证。gettxoutproof 恰好是光谱上人工发起的那一端,也是理解其余自动化的钥匙——先有默克尔路径这种数据结构,所有轻客户端信任模型才谈得上成立。

给自动化流水线的建议

用这对命令做审计回查时,别把证明和 txid 一起只存进数据库。证明的价值在于可交付性,验收方应该拿到证明加当时的区块哈希清单,能独立重放校验。批量生成时注意逐笔判断 UTXO 存活情况,对已花的交易回退到带块哈希参数的分支,块高可从交易首次被确认时你落库的记录里取。启用 -txindex 能一劳永逸地消除分支,代价是节点多占十几 GB 磁盘并拖慢同步,值不值取决于你每月要签多少份证明。哈希与字段细节以官方文档当前版本为准。