5.4 且慢,且慢

矿工运行共识算法时,要判断是否被修改的单元是区块,而不是交易。当然,交易的修改也体现在区块的修改上,对区块的保护也就是对交易的保护。区块链的使用者关心的是交易是否被修改、交易是否有效,等等。本节我们从使用者的角度来讨论。

5.4.1 “双花”

付款者当然希望“一个钱变两个钱花”,这就是所谓的“双花”,也叫双重支付、多重支付。希望归希望,在现实世界中应该设法避免。

在实物货币场景中,花掉的钱被转移到别人手中,你就不可能再花一次了。当然,如果你的“复印”技术高超,就可以实现“双花”了。在数字货币场景中,“复印”即复制,可以一模一样。那么,该如何避免“双花”呢?

我们对“双花”分两种情况考虑。

(1)显性“双花”:区块链上有两个交易花同一笔钱。

(2)隐性“双花”:区块链上没有两个交易花同一笔钱,但从贸易角度确实有“双花”现象,如其中一人收到的款项后来作废了,相当于在实物货币下,发货后才发现是假钞。

为下面讨论方便,我们先定义一对“双花”交易。

交易1:将冠字号为xyz的“数字钞”,从A账户划转到B账户。

交易2:将冠字号为xyz的“数字钞”,从A账户划转到C账户。

注:这里假定能以某种方式区分不同的“数字钞”(如本书UTXO模型中的OUT),不妨视为“冠字号”(类似于现实中纸币上的冠字号(人民币上的编号)),设A有一张“数字钞”,其冠字号为xyz,则单独从上述两笔交易看,都是正常交易,但放在一起看就是有冲突的“双花”交易。

5.4.2 作恶的付款者

假设付款者客户A是个作恶者,他可以向区块链系统提交上述两“双花”交易,之后,交易由记账员入账,即打包放入区块链中,但守规矩的记账员在打包时保证“自己”的区块符合以下要求(“双花”交易提交容易、入账难)。

(1)同一区块中无双重支付问题。

上述两冲突交易(交易1和交易2)不会在同一区块中,这是由打包该区块的守规矩记账员的操守所决定的。这两笔交易中只能有一笔被记账员“认可”。守规矩的记账员各自独立地保证“自己”的区块正确,但相互间呢?例如,有记账员选交易1记账,包在区块1中,另有记账员选交易2记账,包在区块2中。在这种情况下两个冲突交易可能会位于不同的区块中。

(2)区块间无双重支付问题。

上述交易1和交易2可能各自在不同的区块中(分别被不同的记账员所打包,例如分别在区块1和区块2中),假定区块1和区块2都被广播,则区块1和区块2因为有冲突交易而只能在链的不同“叉”上,再经共识机制的剪枝,一段时间T后,交易1和交易2只能有一个被保留在区块链的“长长的树干”中,另一个则成为“垃圾交易”而被抛弃。

“垃圾交易”包括两类:一是交易本身不合格;二是交易本身合格但在竞争中失去了资格,如上述情况。在网络中剔除“垃圾交易”也是需要考虑的,否则会导致“垃圾交易”泛滥,如可以设定时间上限TimeOut,当交易的发生时间超过这个上限,则认为交易“老死”了,记账员不用理它,甚至在本地删除它即可。另外,由于区块的容量和产生区块的频度限制,在交易火爆期会有大量交易积压,造成大量非“垃圾交易”“老死”而不能被记账。

这就是比特币区块链避免“双花”的原理,即由于守规矩记账员的上述努力,区块链上不可能存在显性“双花”

5.4.3 多次确认

在第4章中,我们知道“长度优先”原则和类似于“猜对有奖”的奖励机制,可以避免记账员“坚持己见”,让记账员及时调整自己的错误选择,这里的错误不是指记账或计算错误,而是指选择错误。因网络延迟等而使这类错误在所难免,因此,共识链上的分叉只发生在记账员还没有发现自己选择错误时。但因发现错误只是个时间问题,故共识链上的分叉只发生在最右边几个区块上,并且从右向左看发生分叉的概率逐渐减少。

因此,共识问题变成了一个概率问题:一个交易T被打包进入了一个区块,创造这个区块时,该区块就在某分支链的最右端,即该区块和所包含的交易被第1次确认。由于该区块有可能被抛弃,该交易还不能算数,一段时间后,该区块要么被抛弃,要么向右长出一个新区块,这样就会使得T所在的区块被剪掉的可能性大大降低,称为该区块和所包含的交易被第2次确认。如此下去,长出一定块数后,如比特币实践检验数据为6个区块,当T所在的区块被剪掉的概率接近0时,全网记账员“认可”这一区块,即达成了共识,这就是所谓的比特币交易需要6次确认的原理。

在第4章中提到过,区块的被确认次数为该区块的深度。在这里我们定义“交易被确认的次数”为该交易所在的区块的被确认次数,如图5.2所示,交易T被确认了三次。

图5.2 交易确认次数

5.4.4 何时发货

B收到来自A的一个通知,A声称他已经汇款给B,因要货急,让B尽早发货。在去中心方式下,没有任何人能证明A的可靠。接到这一通知,B该何时发货呢?

上述已谈到“双花”交易最终只有一个体现在区块链中,即它俩是竞争入链的,竞争过程正如民主选举过程,某方可能出现暂时领先而结果失败的情况。

假定在“双花”交易的竞争过程中,B在区块链上看到交易1已被记载,即被确认了(注意:确认的次数还不够),若B在A的催促下发货了,最后交易1竞争失败了,则交易1成为“垃圾交易”而被抛弃,即B受到了损失。但对A来说,实现了“双花”:A收到了B的货,还将会收到交易2的收款方C的货。这就是隐性“双花”,区块链不能避免隐性“双花”。因此,区块链的使用者要知道这种情况,要预防风险,像在现金交易中小心收假钱一样。

综上,B应等到“足够时间”后才发货,而“足够时间”在区块链中就是“足够的确认次数”。此处的“足够的确认次数”是指“交易”所在区块应到达“树干”(再不会被剪掉),比特币认为这个数为6,而且比特币产生区块的频度均值为10分钟,故通常认为B在1小时后发货才安全,而这1小时就是“足够时间”。

上述的1小时只是估计的,因为产生区块的速度在短期看是很不均匀的,而且在交易量大时,会有交易积压,故需要一个较精确的办法确定何时发货。

B应通过自己的客户端软件对该交易进行简单的支付验证,如在使用比特币的情形下,只有SPV返回的确认数超过6次才可发货。关于SPV,参见后面章节。

当然,对于小额支付,则没有必要等待那么多次确认,因为即便损失也是少量的资金,而方便是第一位的,就像口渴了就要去喝水,而谁也不愿等一小时再喝。

5.4.5 连锁交易

类比传统交易,这个时间可以被看成交易的“在途时间”,真是“近在咫尺”,却“远在天涯”。“近”是指在P2P网已全网广播了该交易,它就在你身边;“远”是指在需要足够的时间到达共识状态。

当然,当交易1“在途”,即交易1已在某区块中,而区块已在某分支上,但确认次数不够的时候,B可以提交一个交易x,将该资金转给C,提交是可以成功的,但应设法让记账不成功。

交易资金流向的先后关系不能违背它们在区块链中的先后关系。

在交易x能在交易1还是“在途”时提交的前提下,要求记账员在对交易x和其前置交易,即交易1打包时,两交易所在区块的次序应符合交易次序,即含有交易x的区块在含有交易1的区块的右边。

实际上,从程序的角度可将上述前提修改得更严格:交易x只能在交易1已经在“长长的树干”上时才能提交。更进一步,资金“在途”不可见:付款方交易直到确认到“长长的树干”上时,收款方才能“看到”,如交易1经过了6次确认,即1小时后,B才能在其“钱包”软件中使用他的收款。通常“钱包”软件在查询收款项时,返回结果有该款项当前已被确认的次数,因此可以设参数控制,如只有达到一定确认次数的款项才可以使用。这样,既能避免收款方提前发货的风险,又能避免收款方提前使用该款项失败的麻烦。当前,“钱包”软件安在客户端,客户完全可以修改或重写,故记账员的检查责任还是必不可少的。

总之,对收款方而言,资金的到达有一个“在途”时间,客户不能“急着”启动后续动作,如发货或转出该资金,也就是说,公有区块链不支持强实时性应用。

5.4.6 “双花”趣事

上述我们看到,交易者A同时提交同一款项的两个交易后,由于这两个交易可能“双花”,在软分叉阶段,所以这两个交易在区块链的不同分支上,体现为临时的显性“双花”,而通过剪枝就避免了显性“双花”。若收款人B在这个软分叉的显性“双花”阶段就发货了,但付款给他的交易被剪掉了,则A就实现了隐性“双花”。

回到图5.1,在海底电缆断开期间,若A在“Y”的底部有一笔款项,则可以在他的子网上花掉这笔钱,如在“Y”的右侧分支花掉这笔钱。之后,坐飞机到“Y”的左侧分支所在的大陆,在那里记账员因看不到“Y”的右侧分支上的交易而认为A仍有这笔款项在“Y”的底部,因此,A可以再以一个交易来花掉这笔款项,这样,A就实现了永久的显性“双花”,永久的前提是两子网不再连接。之所以有此现象,是由于这里违背了区块链的前提条件之五:区块链网络要保持足够的“互联”。

若海底电缆修好了,则“Y”面临着剪掉一个分支的情况,而且剪的并不是软分叉情形下的短枝。剪枝后,区块链上的显性“双花”消失,A的显性“双花”变成了隐性“双花”(因为两个交易合同都履行了,但有一个人的收款变成了“假钞”,即被剪掉了)。