术语表 /交易与手续费
交易可塑性
又称交易延展性、Transaction malleability。
- 交易可塑性是什么?
- 交易可塑性是指一种缺陷:第三方可以通过重新编码交易中所含的签名数据,在不改变资金去向的情况下更改交易的 ID。
规定于 BIP-66。
这笔付款依然有效,变的只是它的名称。比特币在2015年至2017年间分阶段堵上了这一漏洞,而 SegWit 为将签名存放在见证数据中的输入彻底完成了修复。传统输入仍然具有可塑性,这是将币存放在 bc1 地址的又一个理由。
运作方式
交易 ID 是交易字节的哈希值,因此改动任何一个字节都会产生不同的 ID,而在传统输入中,签名正是这些字节之一。
有三种宽松之处,使得在不破坏交易的情况下进行改动成为可能。
第一种是算术层面。ECDSA 签名是一对数字 r 和 s,对于每个有效的 s,都存在第二个同样有效的值,即曲线阶减去 s。任何监视网络的人都可以将其翻转,而验证仍然会通过。
第二种是编码层面。签名以 DER 格式封装,而比特币所依赖的库接受松散的变体:多余的前导零字节、不规范的长度标记、任何谨慎的编码器都不会产生的填充。每种变体的哈希值都对应不同的 ID。
第三种是签名周围的解锁脚本。向栈中多压入一个无害的项,脚本的结果不变,而序列化后的字节却不同。
修复是逐层推进的。BIP66 于2015年7月4日在区块高度363,725将严格的 DER 编码列为共识规则,这次激活之所以多被记起,主要是因为当时有几个大型矿池在未经验证的区块头上继续挖矿,当天下午产生了一次六个区块的分叉。Bitcoin Core 0.11.1于2015年10月发布,将低 s 值列为转发策略规则,后来被整理为 BIP146。BIP62 试图枚举并禁止所有剩余的来源,因不具可行性而被放弃,至今状态仍为 Withdrawn。真正解决问题的是 SegWit,它于2017年8月24日在区块高度481,824生效:签名移入见证数据,ID 的计算不包含见证数据,因此对于 segwit 输入,已经没有任何内容可供改动。
在哪里会遇到它
交易可塑性从未造成盗窃,它造成的是记账故障,而这至今仍是该风险的形态。
某个托管方若以自己广播的 ID 来跟踪提币,就可能看到一笔带有不同 ID 的已确认交易,从而断定自己的付款失败,并再次发送这些币。这种模式于2014年在交易所造成了实际损失,也是正规运营方依据输出地址和金额而不仅仅依据 ID 来对账的原因。
链式交易是另一个受害者。花费未确认父交易的子交易以 ID 指明父交易,因此父交易一旦被改动,子交易就永远无法花费。任何在广播注资交易之前就签署退款的协议(开设闪电网络通道正是如此)在 ID 稳定之前都无法安全地构建。
对于购买并持有比特币的人,一个习惯就足以应对所有这些情况:未确认的 ID 并非事实。在传统输入上,它仍可能因交易可塑性而改变,而且现在还会因为一个无关的原因而经常改变,因为 Bitcoin Core 默认转发完整的 replace-by-fee 交易,发送方提高手续费就会发布新的 ID。请等待一次确认,然后再向询问者提供该 ID。
交易可塑性 vs 双花
交易可塑性改变的是标签,双花改变的是资金。在被改动的交易中,相同的币以相同的金额到达相同的地址,只有记住了旧 ID 的软件才会察觉发生了什么。在双花中,一笔竞争交易将这些币发往别处,其中一个版本最终一文不值。把两者混为一谈,会让人们不再信任已确认的付款,而这是错误的结论:已确认的 ID 从未具有可塑性,因为交易可塑性只适用于交易尚未确认的期间。