第19课 深入解析隔离见证(Segarated Witness)- 比特币网络的一个关键技术改进

有兴趣朋友也可以进一步关注公众号“架构之道与术”, 获取原文。 或扫描如下二维码: 这里写图片描述

在第17课 交易延展性(Malleability)攻击 – 门头沟(前世界第1大比特币交易所)倒闭之罪魁祸首 中,我们详细介绍了比特币网络的一个漏洞:“交易延展性攻击”,其原因就是txid在被确认之前,可以被修改。

而隔离见证(Segarated Witness)方案的提出,就是为了修复这个漏洞。当然,隔离见证除了解决这个问题之外,还解决了“扩容”问题,以及其他一些问题。所以隔离见证,它是一个方案的集合,本篇就对这个方案的集合进行一个详细描述。

隔离见证(Segarated Witness)一词的由来
隔离见证这个词,初听起来,不明觉厉。其实呢,没那么复杂。

Witness,见证,其实就是我们在第10课 交易安全性如何保证? – scriptSig/scriptPubKey/Script Engine 中提到的,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

以上就是隔离见证这个词的由来。

隔离见证的最大误解
关于隔离见证,网上一个很大的误解就是:认为witness被隔离走了,witness数据不在Block里,所以一个Block能装更多的Transaction。

其实不是,witness数据仍然在Block里面。并且对于1个Transaction来说,如果把witness数据也算上的话,其raw byte size其实是变大了,而不是变小了!!!
既然Transaction还变大了,那为什么1个Block可以装更多的Transaction呢??

因为隔离见证是软分叉,不是硬分叉,参考第18课 软分叉与硬分叉(比特币的分叉:BCC与BTC)。下面就分别来分析一下,为什么对于老版本节点、新版本节点,1个Block都可以装更多的Transaction呢?

对于老版本节点:
Block Limit Size = 1M,但由于你把witness数据移到了所有Transaction的外面,放在了整个Block的尾部。老版本在计算一个Block大小的时候,只计算了
Block Header + 所有Transaction的数据(witness数据,老版本看不见!!!相当于老版本被欺骗了。)

所以呢,其实整个Block的物理大小(raw block size)已经超过了1M,但老版本的节点不认识尾部的witness数据,所以认为总大小还是 < 1M。

对于新版本节点:
Block的size的计算方式做了调整,引入了Block weight的概念。
block weight = base_size * 4 + witness_size
block weight <= 4M

其中,base_size就是block的前2部分数据(header + 没有witness的所有交易数据)

通过上面的分析,我们会发现,数据还是那么多数据,没有减少,只是重新排布了一下,却变相的把区块链扩容了!!!

隔离见证解决的几大问题
(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。这对于磁盘和网络传输,也有扩容作用。

隔离见证的争议
(1)起初隔离见证是作为一种“硬分叉”方案来搞的,也就是1刀切,不考虑向后兼容,但后来又演变成了软分叉。
软分叉虽然实现了平滑切换,但技术实现很复杂,为了兼容老版本,设计上也有很多妥协,这就增加了出Bug的可能性。
(2)Any One Can Pay
我们知道,隔离见证是作为”软分叉”来部署的,新老版本节点同时存在。

那新版本产生的,带有witness的Transaction,老版本的节点怎么处理呢?
答案是:为了兼容老版本,这种Transaction的验证永远为True,也就是任何人都可以花这笔交易。
但由于95%以上的节点都是新版本的节点,所以即使老版本的节点全部无条件的接受这些Transaction,也没关系。在新版本的节点上,会经过完全的验证。

但假设这样一种情况:隔离见证激活之后,假如发现了这个技术有重大bug,要回滚。那就意味着所有的节点,都会抢着去花那些witness transaction,因为是Any one can pay。这对整个比特币网络,将是一个灾难!!!

相关链接:
《第18课 软分叉与硬分叉(比特币的分叉:BCC与BTC)》
《第17课 交易延展性(Malleability)攻击 – 门头沟(前世界第1大比特币交易所)倒闭之罪魁祸首》