combinerawtransaction:把多份半签名交易拼回一笔的旧式汇签 图 1
combinerawtransaction:把多份半签名交易拼回一笔的旧式汇签 · 图 1

在多签钱包和离线签名的早期工作流里,一个反复出现的难题是:交易只能签一次吗?当然不是——正确流程是每个人对同一笔交易各签各的,再把签名汇到一起。PSBT 出现之前,比特币核心承担”汇合”这一步的命令是 combinerawtransaction:接收多份”同一笔交易的不同带签版本”,把散落在各份里的脚本签名字节合并进一份完整交易。今天大多数新集成确实应该直接走 PSBT 与 combinepsbt,但这条旧命令并没有被淘汰,本文按 v31.0 源码讲清它的真实行为和仍然绕不开它的场景。

合并逻辑:只动 scriptSig,其余一律以第一份为准

源码实现的方式非常直白:以数组里第一份交易作为”合并基底”,随后对每个输入位置,把其他各份交易在同一个输入位置上的 scriptSig 逐段解析出来,逐段追加进基底,直到凑齐为止。这里藏着一条容易被误解的前提:命令合并的只有输入脚本里的签名字节,交易的其余部分——输入引用、输出、锁定时间——全部照抄第一份。也就是说,如果各份交易的非签名部分不一致,命令不会做仲裁,它只信任第一份。正确的使用纪律是:基底交易必须就是那笔”大家一致同意”的原始交易,而不是某人的带签版本,否则会出现”签名来自 B 交易、骨架来自 A 交易”的缝合怪,最终在节点验证时整体失效。

combinerawtransaction:把多份半签名交易拼回一笔的旧式汇签 图 2
combinerawtransaction:把多份半签名交易拼回一笔的旧式汇签 · 图 2

每份输入必须描述同一笔交易

为什么旧工作流里各方拿到的原始交易 hex 必须逐字节一致?因为签名的作用域由 sighash 覆盖的交易内容决定。同一套输入输出下,各方在各自的副本上签名,签名字节落在不同输入位置,合并后天然兼容;一旦某个签名者改动了金额或增删了输出再签,他产生的签名对基底交易就是无效签名,合并不会报错,广播时才会整笔被拒。这是”先广播交易草案、再各自签名”这一顺序存在的根本原因,combinerawtransaction 的实现把顺序假设直接写进了合并策略里。

与 combinepsbt 的分界

PSBT 时代的多方汇签正路是:一方 walletcreatefundedpsbt 生成未签 PSBT,各方 walletprocesspsbt 加签,最后 combinepsbt 汇合、finalizepsbt 收尾。combinepsbt 能合并的远不止签名字节——见证栈、redeemScript、各家的元数据都能归并,而 combinerawtransaction 只能搬 scriptSig。两者的适用面因此在 v31.0 里清晰分叉:涉及隔离见证输入的多方签名,旧命令的 scriptSig 合并模型根本装不下见证数据,必须走 PSBT。旧命令剩下的主战场是传统 P2SH 多签的命令行工作流、以及只有裸交易 hex 在手的历史数据修复——比如给陈旧的多签脚本签名档案做拼装验证。

一个实操校验清单

用旧命令做汇签时,一个不依赖运气的自查顺序是:先比对各方手里的原始 hex 是否完全一致(哈希一遍最省事);确认每个输入脚本里的公钥与预期脚本的公钥集合对得上;合并完成后立即用 finalizepsbt 不适用于裸 hex 的事实提醒自己——旧流程的收尾是直接把合并 hex 交给 testmempoolacceptsendrawtransaction 验证,接受度信号应该来自这条验证回路而不是”命令没报错”。combinerawtransaction 对拼不出有效交易的文件不会拒绝你,它只负责搬字节,对不对是共识层说了算。

旧命令的隐喻价值

combinerawtransaction 的合并策略虽然朴素,却把一个多方签名系统的最小真相摊开了:一致的交易骨架、分位置的签名碎片、以及”合并器不做语义仲裁”的职责边界。PSBT 只是把这三件事装进了更结构化的容器。理解了旧命令的行为,再读 PSBT 的字段设计会顺畅很多——那正是这篇旧文档存在的另一重意义。

风险提示:本文介绍的交易构造机制不构成投资与收益建议,涉及资产转移的签名流程请先小额演练验证。