一笔转账要签多少次字
很多人以为”签名”是给整笔交易盖一个章。实际规则是:交易里每一个需要授权的输入,都要各自提交一份覆盖特定上下文的消息签名。比特币的签名哈希标志(SIGHASH 类型)决定的就是”这份签名到底覆盖了交易的哪些部分”。默认那档叫 SIGHASH_ALL,意思是:我签的是”这笔输入只允许进入这笔交易、流向这些输出”。理解其他档位,只要问一个问题——签名者放弃了哪些承诺。

老算法的三档加一个标志
在隔离见证之前,签名消息按位掩码裁剪:SIGHASH_NONE 把输出列表清空后哈希,签名者等于说”这笔输入愿意进任何交易、流向任何地方”,而且按老规则 NONE 与 SINGLE 都会让”全部输入序列”这一项退出签名哈希,给费率博弈留了洞;SINGLE 只保留与当前输入位置同一序号的那一个输出,其余输出不参与哈希,历史上因早期实现未处理”输出数少于输入数”的边界而有过著名缺陷,规范里也把它标为不鼓励使用;SIGHASH_ANYONECANPAY 是加在前三种之上的标志位,单独使用时签名者放弃对所有其他输入的约束,任何人拿到这份签名都可以往交易里塞别的输入凑费用。这几种在脚本里合法、在钱包默认路径里几乎绝迹,因为每种都意味着某类可被第三方利用的自由度。一个容易被忽略的规则:签名覆盖哪条路径、花多少钱,由实际执行哪条脚本分支决定——脚本里没被执行的那条路径不参与签名哈希,这也是”多路径脚本互不牵连”的底层原因。
隔离见证换了清单
BIP-143 把签名消息改成十段清单,同样的标志位换了作用对象:ANYONECANPAY 生效时,hashPrevouts 被换成 32 字节全零占位,因为”其他输入是谁”不再属于签名者担保范围;NONE 让 hashOutputs 换成全零;SINGLE 只把序号对应的那一个输出写进哈希;hashSequence 则在 ANYONECANPAY、SINGLE、NONE 任一出现时整体归零。清单式的另一个改动是把被花输入的金额写死进消息,堵上了旧时代”不签金额、无法对费率表态”的缺口。隔离见证签名的验证成本和可缓存性来自这些摘要拆分,和档位选择无关,两者不要混谈。
Taproot 再换一层清单
BIP-341 的签名算法沿用同一组标志位,并新增 SIGHASH_DEFAULT(值 0):效果等同 ALL,但签名可以省略那个标志字节,签名字节直接 64 长度。Taproot 的消息清单进一步把”被花输入的 scriptPubKey 全集与金额”都纳入承诺——这是为离线签名设备设计的:硬件钱包能紧凑地证明”给你看的路径就是全部可执行路径”,避免旧协议下”用另一段合法脚本冒充正确脚本”欺骗设备的攻击面。规范还在验证规则里封死了两类情况:未定义的 hash_type 一律无效——合法取值只有 DEFAULT、ALL、NONE、SINGLE 加三档 ANYONECANPAY 组合,其余字节直接导致验证失败;以及 SIGHASH_SINGLE 若找不到与输入同序号的输出,交易直接无效。对比 BIP-143 时代序号越界时悄悄改用全零摘要的处理,Taproot 把这种模糊地带升级成了硬失败,签出去的字节要么明确承诺了什么,要么整笔交易被拒。
钱包实践与判断标准
对普通用户:钱包默认几乎总该是 SIGHASH_ALL 或 DEFAULT 的等价物。判断一个钱包”签得对不对”,实操上可以问它的开发者两个问题:签名消息里是否承诺了全部输出和输入金额;PSBT 组合时,不同设备给出的 sighash 字段不一致会怎样处理。对高级用户,PSBT(BIP-174)里每个输入都允许声明自己的 sighash 类型,离线签名前务必确认这一位和预期一致——同一份 PSBT,一台设备按 ALL 签、另一台按某自由档位签,拼出来的交易虽然合法,但那条自由签名是将来被人”顺手替换”的入口。所有具体地址与样例都不指向任何真实资产,仅示意结构。涉及真实资产先在小额演练,本文只做机制说明,不构成任何投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。