跳转到正文
buybitcoinsmart

术语表 /交易与手续费

交易可塑性

又称交易延展性、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 从未具有可塑性,因为交易可塑性只适用于交易尚未确认的期间。

请勿混淆

常见问题

交易可塑性能被用来盗取比特币吗?

并非直接如此。这些币仍然以预定的金额发往预定的地址。损失来自那些信任未确认交易 ID 的软件:当它记住的 ID 始终没有出现在链上时,软件会重复支付。

交易可塑性已经修复了吗?

对于 segwit 输入,自2017年8月起已经修复。花费以1或3开头的传统地址的输入,其签名仍位于交易中参与哈希计算的部分,因此这些 ID 在确认之前仍可能被改动。

为什么我的未确认交易 ID 一直在变?

几乎总是因为发送方钱包用手续费更高的版本替换了该交易,从而产生了不同的 ID。完整的 replace-by-fee 是现代 Bitcoin Core 的默认转发策略,因此这属于正常行为,而不是攻击。

接着阅读

相关术语

交易与手续费中的更多术语

阅读本页英文版