gettxoutproof与verifytxoutproof解决的是“某笔交易是否被某个区块的Merkle树包含”,不是“这笔交易永远不会重组”或“交易每个输入都有效”。把能力边界放在第一句,后面的实验才不会被误用。
两台节点组成最小证据链
生成端知道目标txid,调用gettxoutproof取得十六进制证明;验证端不需要重新接收完整区块,只要能够按自己的最佳链验证证明。gettxoutproof接收一个或多个txid,可选blockhash,并返回证明这些交易包含在某个区块中的十六进制序列化证明。
bitcoin-cli gettxoutproof '["<txid>"]' '<blockhash>'
bitcoin-cli verifytxoutproof '<proof-hex>'
生产环境不要把示例中的占位符直接拼入Shell日志。记录网络、节点版本、txid、blockhash、生成高度、证明哈希和验证时间;证明原文可以作为证据附件,但要设置大小和访问控制。
blockhash为什么值得主动保存
不传blockhash时,生成节点需要自己定位交易所在区块。未提供blockhash时,节点需要能够定位交易所在区块;官方文档说明目标交易至少要有一个未花费输出,或节点已启用txindex。 官方给出的可定位条件只有两类:目标交易至少还有一个未花费输出,或节点已经启用txindex。内存池交易尚未进入区块,不能据此生成区块包含证明。对长期复核,显式保存并传入已核验的blockhash更稳定。
| 现象 | 先查什么 | 不能直接下的结论 |
|---|---|---|
| gettxoutproof报错 | txid、blockhash、节点索引与链 | 交易不存在 |
| verify返回txid | 证明承诺这些交易且区块在验证端最佳链 | 绝对最终 |
| verify返回空数组 | 证明无法验证 | 交易必然欺诈 |
| verify抛RPC error | 区块不在验证端最佳链或调用条件错误 | 交易一定不存在 |
| 两节点结果不同 | 链尖、同步、网络与重组 | 任一节点一定恶意 |
验证结果是三层判断
verifytxoutproof返回证明所承诺的txid;证明无法验证时返回空数组,而证明对应区块不在本节点最佳链时会抛出RPC error。 第一层是证明能否验证:无法验证时得到空数组;第二层是证明对应区块是否位于验证节点当前最佳链,不在最佳链时会抛出RPC error;第三层才是业务自己的确认数和重组风险策略。RPC不能替代第三层。
例如支付系统收到有效证明后,还要读取区块高度与当前链尖,计算确认数;发生重组时重新检查该blockhash是否仍在主链。高价值业务可以使用两个独立节点核对,但不能把节点数量机械地当作最终性保证。
一套可重放的测试向量
准备四组数据:最佳链中的已确认交易、已知错误txid、被修改一个字节的证明、测试链重组前后对应的旧区块证明。验收生成端能输出有效证明,验证端能返回正确txid;篡改证明不应被接受;旧分叉证明不应继续被当成最佳链包含证据。
测试还要覆盖多txid证明。调用者应检查返回集合与请求集合,而不是只判断数组非空。顺序和去重规则由调用程序明确处理,任何缺项都进入异常队列;区块不在最佳链的样本应断言RPC error,而不是断言空数组。
它适合哪些场景
适合跨系统传递紧凑的区块包含证据、审计某批交易确实进入特定区块,或在不传输完整区块的组件之间完成验证。它不适合替代钱包余额查询、UTXO可花费性、双花监控和确认数策略。
一份合格验收记录应能让第二台节点在没有口头说明的情况下,凭网络、区块哈希和证明重现同一结果。本文基于Bitcoin Core 31 RPC与BIP 37背景资料,不构成资金最终性或交易安全保证。
证明文件的交接清单
生成端交出的不应只有一段proof hex,还要包含网络、txid集合、blockhash、节点版本与生成时间;验证端另行记录返回集合或RPC error、当前链尖和确认策略。两侧记录能够独立重放,才算完成证据交接。
涉及UTXO、模板和新区块观察时继续查getblocktemplate字段、gettxout确认UTXO、waitfornewblock。本证明无法替代的业务判断是:确认数阈值和重组风险应由业务策略另行定义,证明本身不替代节点同步与链选择。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。