区块链研习社区块链大学区块链

《锋哥论道区块链》之四区块链1.0之比特币--隔离见证(Sega

2019-04-24  本文已影响8人  7dfc697cf7a9

1交易延展性(Malleability)攻击 -- 门头沟(前世界第1大比特币交易所)倒闭之罪魁祸首
2014年2月25日,日本时间上午11点,MT.GOX交易所(俗语门头沟)停盘。众所周知,MT.GOX曾经是比特币最大的交易所,一度交易量达到所有比特币交易的80%,也是目前运营时间最长的交易所。门头沟的倒闭,源于黑客的攻击。整个丢失了85万数量的比特币,按当时的币价计算,这些损失的币价值近4.54亿美元。而这就是我们今天要讲的,大名鼎鼎的“交易延展性攻击”。
Transaction Malleability,翻译成“交易延展性”,也有人称为“交易可锻性”,这其实是个比喻。在现实生活中,一个金币在使用中,被人用锤子砸了几下,凹了几处,变得不是很圆。这个金币的本质含金量没变,只是外观看上去与标准的金币有些不同,这个金币依旧是一个被认可的金币。这就是“金币的可锻性”。
交易延展性,或者叫做“交易可锻性”,指的是,比特币支付交易发出后、确认前可被修改(准确说是被伪造复制)。
为什么交易发出后,可能被篡改呢,不是有签名吗? 其中1个原因就是多数挖矿程序是用openssl 库校验用户签名,而openssl兼容多种编码格式,还有,就是椭圆曲线数字签名算法(ECDSA)本身,签名(r,s) 和 签名(r,-s(mod n))都是有效的。所以,对签名字符串本身的表现方式做些调整,依旧是有效签名。我们知道,每个Transaction有个Transaction ID,这个Transaction ID也就是对整个交易做的一个Hash,也是该Transaction的唯一标识。现在你对签名做了微调,签名还是有效签名,但是Transaction ID却因此改变了!!!而黑客就是利用了这个特性,对交易所实施了攻击,下面就来看一下这个攻击过程是怎样的:
Step1: 黑客自己有1个账号,在交易所开了1个账号,把自己的bitcoin转进去。
Step2: 申请提现(withdraw),交易所发起1笔Transaction。
Step3: 这笔交易被广播到网络上,还未打包进区块链之前。黑客收到这笔Transaction,稍微更改了scriptSig的格式,生成1笔新的交易广播出去,此时Transaction id已经变了。
Step4: 黑客的这笔新交易被区块链接收了。然后向交易所投诉,说它没收到钱。交易所根据自己生成的Transaction Id查询该笔交易,发现在网络上查询不到, 会再次转账给黑客,也就是double withdraw! 同1笔钱,被黑客提现了2次,甚至多次! 导致交易所蒙受巨大损失。
总结:
交易延展性攻击之所以会发生,是因为Transaction ID会变(而这是1个Transaction的唯一标识),而Transaction ID会变,是因为里面的scriptSig可以被调整。如果有办法保证Transaction ID在整个交易过程中,都不可能被改变,那也就解决了这个问题,而这就是后续要讲的”隔离见证“。
2隔离见证
上面我们详细介绍了比特币网络的一个漏洞:“交易延展性攻击”,其原因就是txid在被确认之前,可以被修改。而隔离见证(Segarated Witness)方案的提出,就是为了修复这个漏洞。当然,隔离见证除了解决这个问题之外,还解决了“扩容”问题,以及其他一些问题。所以隔离见证,它是一个方案的集合,本篇就对这个方案的集合进行一个详细描述。
(1)隔离见证(Segarated Witness)一词的由来
Witness,见证,其实就是scriptSig。1个Transaction有多个input,多个output;
每个input里面有1个scriptSig(对应付款人的私钥签名);
每个output里面有1个scriptPubKey(对应收款人的公钥Hash)。
那为什么把scriptSig叫做Witness呢?这个是密码学领域的一个对scriptSig的更general的一个称呼,此处就不深入研究了。
隔离,Segatated,就是指把这个scriptSig从每个Transaction的input里面拿出来,放到别的地方去,不要和transaction放在一起。拿出来放到什么地方去呢???放到整个Block的尾部。也就是说,一个Block的数据现在有3部分组成:
Block = Block Header + 所有的交易数据 + 所有交易的所有input对应的witness
以上就是隔离见证这个词的由来。
(2)隔离见证实现的扩容效果
关于隔离见证,网上一个很大的误解就是:认为witness被隔离走了,witness数据不在Block里,所以一个Block能装更多的Transaction。
其实不是,witness数据仍然在Block里面。并且对于1个Transaction来说,如果把witness数据也算上的话,其raw byte size其实是变大了,而不是变小了!!! 既然Transaction还变大了,那为什么1个Block可以装更多的Transaction呢??
因为隔离见证是软分叉,不是硬分叉,下面就分别来分析一下,为什么对于老版本节点、新版本节点,1个Block都可以装更多的Transaction呢?
1)对于老版本节点:
Block Limit Size = 1M,但由于你把witness数据移到了所有Transaction的外面,放在了整个Block的尾部。老版本在计算一个Block大小的时候,只计算了Block Header + 所有Transaction的数据(witness数据,老版本看不见!!!相当于老版本被欺骗了。)所以其实整个Block的物理大小(raw block size)已经超过了1M,但老版本的节点不认识尾部的witness数据,所以认为总大小还是 < 1M。
2)对于新版本节点:
Block的size的计算方式做了调整,引入了Block weight的概念。
block weight = base_size * 4 + witness_size
block weight <= 4M
其中,base_size就是block的前2部分数据(header + 没有witness的所有交易数据)
通过上面的分析,我们会发现,数据还是那么多数据,没有减少,只是重新排布了一下,却变相的把区块链扩容了!!!
(3)隔离见证解决的几大问题
1)交易延展性攻击
因为把scriptSig移到外面去了,scriptSig变成了空值,那么计算出来的txid也就不可能改变了。txid不可能改变,也就解决了交易延展性攻击。
2)扩容
在前面我们说过了,1个Block最多1M,也就装2000多笔交易,每10分钟产生1个新区块,意味着1秒钟就才处理3到4笔交易。这使得现在的比特币网络已经满负荷运行,很多交易要排队等待被打包确认,比特币网络的扩容迫在眉睫。而scriptSig呢,其实占了1个Transaction的很大一部分空间。这是为什么呢?回想第11课 账号被黑客盗取怎么办? -- 多重签名(MultiSig)与P2SH所讲的P2SH交易,scriptSig是个redeem script,尤其在多重签名,或者前面讲的RSMC之类的交易中,占了很大一部分空间,所以把它移出去,的确可以节省很大的空间。
3)增加了script version
类似Block, Transaction,隔离见证为Script也引入了版本号,这使得Script Language也可以以一种后向兼容(backward-compatible)的方式来发展。
4)签名算法复杂度有了大的优化
这个涉及到签名算法,后面有机会再仔细讲这个问题。
5)网络和存储的扩容
因为witness只在交易的验证环节需要,其他环节未必用到。所以在其他环节,可以不存储witness。这对于磁盘和网络传输,也有扩容作用。
(4)隔离见证的争议
1)起初隔离见证是作为一种“硬分叉”方案来搞的,也就是1刀切,不考虑向后兼容,但后来又演变成了软分叉。软分叉虽然实现了平滑切换,但技术实现很复杂,为了兼容老版本,设计上也有很多妥协,这就增加了出Bug的可能性。
2)Any One Can Pay
我们知道,隔离见证是作为"软分叉”来部署的,新老版本节点同时存在。
那新版本产生的,带有witness的Transaction,老版本的节点怎么处理呢?
答案是:为了兼容老版本,这种Transaction的验证永远为True,也就是任何人都可以花这笔交易。但由于95%以上的节点都是新版本的节点,所以即使老版本的节点全部无条件的接受这些Transaction,也没关系。在新版本的节点上,会经过完全的验证。
但假设这样一种情况:隔离见证激活之后,假如发现了这个技术有重大bug,要回滚。那就意味着所有的节点,都会抢着去花那些witness transaction,因为是Any one can pay。这对整个比特币网络,将是一个灾难!!!

上一篇下一篇

猜你喜欢

热点阅读