比特币中交易延展性问题

Aug 01 2018 blockchain

交易延展性 (Transaction Malleability)

当交易被签名时,签名并没有覆盖交易中所有的数据 (比如位于 txin 中的 scriptSig,由于 scriptSig 中包含公钥和签名数据,不可能对自身自签名),而交易中所有的数据又会被用来生成交易的哈希值来作为该交易的唯一标示。如此,尽管不常见的,比特币网络中的一个节点能够改变你发送的交易 (通过改变 txin 中的签名),导致该交易的哈希值发生变化。注意,攻击者仅仅能够改变该哈希值,交易中的 txout 是无法进行改变的,因此比特币最终也许会转入你原本打算的地址中。然而,这确实意味着,例如,在任何情况下,接收一系列未确认交易的链是不安全的,因为未确认交易的哈希值可能会发生变化,而随后的交易中的 txin 会依赖于先前交易的哈希值。即使交易得到了一个确认,也是不安全的,因为区块链可能会被重新调整。此外,客户端必须一直扫描收到的交易,假定一个 txout 是存在的,因为先前创建该笔交易的客户端可能是不安全的 (可能会发两笔同样 txout 的交易)。

签名延展性 (Signature Malleability)

延展性的第一种形式就是签名本身。每一个签名恰好有一个 DER-encoded ASN.1 octet representation,但是 OpenSSL 并没有强制,只要一笔签名没有极度的改变,它就是可接受的。此外,对于每一个 ECDSA signature(r,s),这个 signature(r,-s(mod N)) 是相同消息的一个有效签名。
在 363742 区块高度处,BIP66 软分叉强制区块链中所有新交易遵循 DER-encoded ASN.1 标准。仍然需要进一步的努力来关闭 DER 签名其它可能的延展性问题。
签名仍然是可以被拥有相应私钥的人改变的。

解锁脚本延展性 (scriptSig Malleability)

比特币中使用的签名算法没有签署 scriptSig 中的任何数据。因为对整个 scriptSig 签名是不可能的,scriptSig 包含签名本身。这意味着,附件的数据能被添加到 scriptSig 中,额外的数据会先于所需的签名和公钥压入栈中。类似的 OP_DROP 能被添加,使得最终栈的状态与 scriptPubKey 执行之前的状态相同。
阻止 scriptSig 延展性正在被考虑当中。目前,如果交易 txin 的 scriptSig 中若包含除了签名与公钥之外其它数据,则该交易被认为是不标准的,不会被节点转发。最终,这个规则会强制在 scriptPubKey 执行完之后,栈中只剩下一个元素。然而,要做到这样,需要比特币随后的扩展。

隔离验证 (segregated witness) 通过将 scriptSig 从交易的 txin 中分离出来,放入到一个新添加的 witness 字段中,来解决相关延展性问题,由于签名数据从交易中分离出来,使得交易结构尺寸变小,可以使得区块能容纳更多的交易,侧面达到了轻微扩容的目的,有关隔离验证的知识,可查看 BIP 141-145。