术语表 /交易与手续费
签名哈希
又称 Sighash。
- 签名哈希是什么?
- 签名哈希是钱包实际签名的摘要:先重建一份交易副本,按该输入所选的标志位对其进行裁剪,再用 SHA-256对其做两次哈希。
规定于 BIP-143。
没有任何签名覆盖线路上传输的那份交易。每个输入都有各自的摘要,由一套已改写两次的流程生成:2009年的原始流程、用于隔离见证输入的 BIP143,以及用于 Taproot 的 BIP341。摘要没有覆盖的部分,攻击者可以随意修改。
运作方式
构建签名哈希,是构造一份经过修改的交易副本并对其做哈希,而不是对您即将广播的那份交易做哈希。
原始流程如下。取出交易,清空每个输入的解锁脚本,把正在花费的脚本放入您要签名的那一个输入,然后按标志位保留、置空或丢弃输出。将标志位作为四字节数字附在末尾,对整体做两次 SHA-256,再对得到的32字节进行签名。
这一设计带来一项代价,直到交易变大才有人注意到。由于每个输入都要重建并重新哈希整份交易,计算量随输入数量的平方增长。BIP143 给出了具体数字:验证一个普通的1 MB 区块大约需要2秒,而一笔精心构造、包含5,569次签名操作的1 MB 交易可能需要25秒。一笔交易就让全网每个节点停滞这么久,这是一种随时可能被规模化利用的拒绝服务攻击。
BIP143 为隔离见证版本0的输入改写了这一流程,同时解决了两个问题。涵盖输出点、序列号和输出的三个子哈希只计算一次,并供每个输入复用,使成本变为线性。对持币者更重要的是,摘要现在会承诺正在签名的输入的金额。此前,签名设备只能被告知输入值多少,却无从核实,恶意程序因此可以低报输入金额,诱使硬件钱包批准一笔巨额手续费。
BIP341 为 Taproot 第三次改写了这一流程。Taproot 摘要是带标签的哈希,前面加有域字符串,因此绝不会与其他协议的摘要混淆,并且它承诺所有被花费输入的金额和锁定脚本,而不只是被签名的那一个。它还引入了默认标志值零,其覆盖范围与标准规则相同,但不会写入签名。
在哪里会遇到它
您会间接地接触到签名哈希,它正是硬件钱包行为方式的原因。
签名传统格式的输入,要求向设备提供完整的前一笔交易,因为这是设备自行确定该输入金额的唯一途径。Sparrow 和 Electrum 会在签名前把这些交易传送给 Trezor 或 Ledger,如果钱包里有很多旧币,这一步就是花费耗时明显超出预期的原因。隔离见证输入只需要金额,而 PSBT 已经带有金额。
它会直接表现为区块浏览器上传统格式或隔离见证签名的最后一个字节。以 01 结尾的签名,是按覆盖全部内容的规则生成的。任何其他取值,在您依赖该交易之前都值得先弄清楚。
签名哈希 vs SIGHASH_ALL
签名哈希是摘要;SIGHASH_ALL 是构建摘要的规则之一。每个签名都有签名哈希,包括完全不带标志字节的 Taproot 签名。不同的是交易的哪些部分进入了摘要,而标志位只是这一选择的标签。说一笔交易“使用 SIGHASH_ALL”描述的是一种策略;说它有签名哈希,描述的则是比特币历史上每个签名都具备的东西。