上一篇我们介绍了比特币系统的局限性 比特币技术入门5(系统吞吐率),以及一种治标不治本的方法:隔离证明,其实扩展块容量只是其副产物,其主产物是解决交易可锻性的问题,今天介绍交易可锻性。
本文预计阅读时间 4 分钟。
交易可锻性
交易可锻性的英文叫 Transaction Malleability,可锻类似重铸钢铁,重铸有个什么特点呢?就是不改变密度和质量,只改变外形。
我们判断一个人是不是一个人,最权威的是通过身份z号判断,但是这个太麻烦了,为了简化,就以一个人的外形判断了。
账单也是类似,先回顾一下账单的内容,包括账单内容(输入输出数量之类的)、对账单内容的签名、账单ID。这个账单ID就是对账单内容和签名的 Hash,如下图:
因此,比特币系统如何快速的验证一笔账单呢?就是看它的ID。只要 ID 不一样,就视为两笔账单。
由于比特币系统签名算法 ECDSA 的问题,节点可以利用之前的签名和账单内容,生成一个不一样的有效签名,这样,账单ID也随之改变。这个算法对于一个内容只存在 2 个有效签名,因此账单只能被锻造一次。
这里的重点是,这个签名有效,账单也是合法的。因此,在比特币网络中会同时存在两笔账单,这两笔账单内容一样,但是账单 ID 不一样。假如用户发出的交易为A,黑客改成了B。
这里有一个前提是,A 和 B 的输入都一样,对于一个节点来说,只要有一个交易被写到链上了,另一笔交易就会失效,因为在这个节点写入交易时会先检查本地链上账单的输入是否已经被消费过了。当两笔账单都在网络中传播时,一个节点接收到两笔账单后,会写入最先接收到的那笔,抛弃另一笔。
实际危害
这两笔内容一样而 ID 不一样的账单最终只会有一笔被写进区块链,看起来也没有啥坏处啊?还记得我们刚才提到的账单是通过 ID 来区分的吗?假如我通过第三方平台来保存我的钱,并发起了一笔提现 *** 作 A,并且把这笔提现交易改了 ID 变成 B。最后 B 被先写入链上了,即我拿到钱了,但是提现 *** 作 A 却失败了。这时候我就可以继续发起提现交易了。
这个需要我有什么能力呢?需要我的计算资源吗?不需要。这个和双重支付无关,这种攻击不需要黑客节点挖矿,黑客节点只需要将新账单发给尽量多的节点就可以了,而其他节点最终会将这笔新账单写到链上。
解决思路
账单可锻性的问题有两种解决方法,第一种是从交易的验证方式下手,之前通过 ID 验证,现在可以通过账单内容验证,但是这样比较耗时。另一种方式是从账单 ID 下手,可以让账单 ID 无法被改变。
隔离证明将这两种方式结合在了一起。即将账单 ID 与签名分开,同时反应账单内容。隔离证明把签名信息从账单的中间位置移到了末尾,并且修改了账单 ID 的生成方法,这样,ID 还很短,就是一个 Hash 结果,并且只与账单内容有关,与签名无关。
这样一搞,就算黑客重新签一次也没用了,因为还是一笔账单。
总结
隔离证明是一个很简单的解决思路。但是交易可锻性的问题根本上是签名算法的缺陷,为什么不使用一种没有这个问题的签名算法呢?这个问题应该从交易可锻性的危险程度、算法的安全性和效率方面综合考虑了。
致谢:DPer
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)