隔离验证有望能改善比特币的性能表现
扫描二维码
随时随地手机看文章
如果说2015年在香港举行的“比特币扩容研讨会”上最令人兴奋的提议,那毋庸置疑是开发者Pieter Wuille博士提出的隔离验证(Segregated Witness)。这个提议受到技术界人士的好评,隔离验证有望能改善比特币的性能表现,而有些人甚至希望它能提供一种扩容的解决方案,帮助比特币社区恢复一定的和谐。
什么是比特币交易?
为了更好理解隔离验证,最好先了解技术层面上的比特币交易。(如果你对这方面并不陌生,可以直接跳到本文的最后一部分。)
对于初学者而言,要认识到很重要的一点,比特币协议的核心是交易。实际上,点对点网络上的节点并不会相互发送比特币,而是互相发送包含交易数据的包(packages)。
在某种程度上,比特币交易实际上是一套一套的“锁”。更具体点说,每笔交易包含两个主要组成部分。其中一半能有效解锁之前交易中锁定的比特币,使用的数据片段被称为输入,输入包括脚本和如何解锁输入的说明(称为scriptSigs)。
另外一半由一个或多个被称为输出的新锁组成,这些锁会再次锁定相同或更少数量的比特币,输出包括名为scriptPubKeys的脚本。因此,比特币在单笔交易中有效地从输入转移到输出,并同时从一笔交易跳转到另一笔交易。
这条规则有一种主要的例外。一笔coinbase交易(不要与coinbase交易所混淆了)是矿工在找到新区块时创建的交易,并且当中包含了区块奖励:撰文时为25个比特币(现在是12.5)。此外,矿工可以将交易中解锁了但没有再次锁定的比特币增加到coinbase奖励当中:简单来说就是输入和输出的差额,即交易手续费。
所有这些比特币的“解锁”和“锁定”都是由交易发送方完成的,随后以数据包的形式通过比特币网络进行传输。然后,网络上的所有节点都会检查这个解锁和锁定过程是否正确完成。如果没有问题,他们会将交易转发给其他节点。如果某个节点同时也是一个矿工,那它就可能会将交易打包到区块中。然而,是否会被打包进区块取决于矿工,这就是给矿工手续费的原因。
非常重要的一点是,所有节点遵循的交易验证规则与(几乎)所有矿工使用的规则是兼容的。如果某些矿工将交易打包进其他节点拒绝的区块中,则整个区块将被该节点视为无效。如果该节点是矿工,则可能导致双花和网络分叉。
共识规则允许交易同时以几种不同的方式来锁定(和解锁)比特币。但锁定比特币的输出通常至少包括一个scriptPubKey:“证明你拥有(或者知道)对应于该比特币地址的公钥的私钥。”
(用私钥推导出公钥很容易,但几乎不可能通过公钥推导出私钥。同样,通过公钥计算出比特币地址很容易,但很难通过比特币地推导出公钥。因此,从私钥计算出比特币地址也很容易,但不可能通过比特币地址推导出私钥。这是“单向的”。)
当然,用于将比特币锁定在scriptPubKey中的比特币地址是交易接收方提供的。由于接收方使用只有他自己知道的私钥创建出这个比特币地址,因此他是唯一可以创建有效scriptSig的人,也是唯一可以创建新交易并使用被锁定比特币的人。
签名是怎么来的?
为了证明对应于与比特币地址的私钥的所有权,理论上可以在交易的scriptSig中包含私钥,但是这样一点都不安全。最重要的是,任何看到交易的人都可以获取私钥,并创建一笔新的交易(或更改原始交易),将原始交易中的接收方改成自己。如果真是这样的话,对矿工而言偷比特币就会是小菜一碟了,因为他们是挑选交易进行确认的人。
因此,scriptPubys通常要求scriptSig包含一个或多个签名来解锁比特币。
签名是一种密码学技巧,使用私钥与任意其他数据组合来计算出唯一的数字字符串。并且,根据密码学原理,可以使用对应的公钥来验证签名是不是使用该私钥创建的。因此,签名既证明了私钥的所有权,又证明了该私钥的所有者对特定数据片段的批准,同时不需要泄露私钥。
在比特币中,私钥通常用于对交易数据进行签名来减去交易输入。(包括,scriptPubKeys、锁定的数量和一些其他细节。)随后,将签名和用于使用比特币的公钥添加到交易的输入字段中。这样也证明了私钥的所有者确实打算创建交易并确保它不会被篡改。
然后,将所有这些交易数据(包括此时的交易输入)一并哈希运算,创建出交易ID,用于标识出特定交易。如果交易随后被打包入块,那么矿工会将交易ID与另一个交易ID一起哈希运算产生新的哈希值。如果有其他两个交易ID的哈希值,则再次进行哈希处理,一直持续到只剩下一个哈希值为止。这种散列结构称为默克尔树(Merkle Tree),最终产生的哈希值为默克尔根(Merkle Root)。该默克尔根与其他区块数据组合以形成区块头(header),用于标识特定区块。最后,这个区块头的哈希值会被包含在下一个区块的区块头中,从而将区块链接在一起。
比特币被认为是不可篡改的,因为追溯性地更改任意交易的任何部分都会改变交易ID,进而改变区块头。而改变了的区块头不再符合工作量证明的要求,并且由于区块头会影响后续区块头的组成,因此它们中的任何一个都会被视为无效。
什么是隔离验证?
由Wuille在香港提出的隔离验证提议是基于Blockstream的侧链Elements中所使用的一个概念,再结合比特币核心开发人员Luke Dashjr的补充构思。在过去的几个月中,Wuille与比特币核心开发人员Gregory Maxwell和Eric Lombrozo合作对隔离验证进行了概念化,并计划在2016年推出。
因此,对于不使用隔离验证的比特币节点(我们称之为“旧节点”)的而言,接下来一些新创建的交易输出中可能会使用奇怪的scriptPubKeys。之所以奇怪,是因为这些scriptPubKeys几乎不能被认为是锁,基本上标明了它们不需要签名,或者说看起来就像“任何人都可以花”。此外,它们还包括一些无意义的文本。
从旧节点看来,这些交易是疯狂的。他们会以为任何人都可以创建一个新的scriptSig,来解锁这些交易输出,这意味着这些交易非常不安全。但与此同时,旧节点也依然会照常运行。毕竟,又不是他们自己的交易出问题了。无意义的文本虽然奇怪,但也不会导致什么问题。因此,它们依然会确认交易有效,并将其转发给其他节点。
但是,使用了隔离验证的节点(我们称之为“新节点”)会识别出其他东西。他们会在scriptPubKey中看到那些“无意义的文本”,但并不会认为它们毫无意义。相反,新节点会将这段文本识别为另一种非常特殊的输出类型。
与典型的交易输出类似,这种新类型的输出需要一个或多个签名才能解锁比特币。但与典型输出不同,这种新类型的输出不需要将签名包含在后续事务的scriptSig中。相反,它需要将签名包含在交易之外的全新区域中:隔离见证数据区域。
这个隔离验证数据区基本上就是一个带有签名和一些附加数据的“附加组件”。重要的是,隔离验证区域被旧节点完全忽略,但会被新节点识别。此外,它们携带的数据不会与交易的其他部分一起哈希处理到交易ID中。
因此,旧节点和新节点都将会认为包含隔离验证中的签名的交易有效。旧节点会验证它们,因为从他们的角度来看,这些交易根本不需要签名(他们也看不到签名),而新节点也会验证它们,因为所需的签名位于隔离验证区域中。并且由于旧节点和新节点都将交易数据哈希处理到相同的交易ID中,所以每个节点都认可这些区块的组成,乃至整个区块链的结构。
(值得注意的是,所有或者绝大多数矿工都应该使用隔离验证,以防止双花和硬分叉,要么就都不使用。如果所有矿工都使用了隔离验证,尽管网络上的旧节点可能会想知道为什么有些交易没有被打包,但由于打包哪些交易是由矿工决定的,而且这些交易也不是他们的交易,所以旧节点也不会介意。)
但是还存在一个问题:如果签名对区块链的构成没有影响,那么区块链就不能证明交易中包含正确的签名了。
为了确保签名都被嵌入到区块链中,启用隔离验证的矿工也需要添加一种手段。不仅在所有交易中创建默克尔树,还要从所有隔离验证中创建一个默克尔树,来将交易的树进行镜像。
然后,将隔离验证的默克尔根包含在coinbase交易的输入字段中。因此,隔离验证的默克尔根会改变coinbase交易的交易数据以及其交易ID,从而影响区块头,并最终影响区块链的构成。
Wuille的隔离验证提议能够实现从比特币交易中将签名删除,同时保持比特币的不可篡改,并且不违反任何现有的共识机制。