关于区块链的确定性

最近的两年来,我们多次跟络谱的合作伙伴沟通过关于区块链的设计、应用、对接难点,总结下来,其中一个比较普遍的问题是关于如何理解区块链中的事务确定性问题。比如,如何比特币的交易有分叉,络谱是什么样的?以太坊的数据要有统一的 nonce 计数器,导致必须维护一个单点信号,不适合传统的服务器开发,怎么解决?

对于以上问题,我们整理了一份说明,来解释我们如何在络谱平台上解决这些问题。

确定性的价值

对于区块链用户来说,“事务的确定性”是一个很重要的特性,事务(Transaction)的确定性是指,用户应该能够在有限的时间内,能够确定地知道写入的数据是否被共识机制认可,以及,一旦得到了共识机制的认可,结果应该不会再发生变化。不能变化的内容包括事务的所有属性都不能再发生变化(包括事务自身属性,和事务被记录到账本里的时间等)。试想,如果没有确定性,用户将面对一个混乱的账本:向区块链发送了数据却没法确认结果,这时,用户先是不知道应不应该发起重试,接下来重试不成功后又不知道是否可以认为事务一定会失败——所有的事务都处于混沌的状态。

区块链确定性问题的现状

以比特币网络、以太坊网络为代表的公有区块链技术,为保证广泛的节点、网络特性,在很大程度上牺牲了事务的确定性。许可链(也被称为联盟链)在有限的网络范围内,可以保证相对较高的确认速度,因此天然具备确定性特征。
然而某些共识机制在提高性能、提高对开放网络的支持程度时,允许不彻底的确定性,比如,比特币网络里允许出现分叉,使得用户和很多交易所,在收到转账后,需要更长的时间确认,在若干个区块之后,通过一个相对安全的阈值(相对的信心)来决定是否认可这笔交易。

络谱的解决方案

络谱提供的确定性,使得用户能够明确地断言“失败”

建立明确的失败判定策略

关于确定性,我们假设一个场景:银行收到张三的一万元存款,打算把这件事记录到某个分布式账本,交易发上去了,第一个块里没有数据,第二个块里还是没有交易,第三个第四个仍然没有……那么银行是否应该重新发出这笔交易呢?如果重发出一次交易,那么可能被记录为向张三转两笔钱,如果不发出,那么可能交易已经被抛弃了。

一种简单的解决方法,是采用 nonce 机制,及每个交易有唯一的 nonce,只要保证重试时再次用同一个 nonce 发出,就可以让区块链账本抛弃这个请求了。nonce 的设计解决了如何重试的问题,但仍然没有解决一个问题:当没有等到交易结果时,如果不打算重试的话,什么时候才能断言说这笔交易一定不会成立了?根据对等网络的特性,20分钟后突然又出现在区块链上,是有可能的。

络谱自有区块链通过一套我们称为 BlockLimit 的机制,在许可链上真正解决了对于“失败”的确定性问题。在发送交易时,发送方可以指定一个能够等待的最远块,即 BlockLimit,将这个约定跟在交易中发给区块链账本。账本打算打包这笔交易时,会检查这个 BlockLimit,如果区块链当前高度已经超过了 BlockLimit 约定的高度,则拒绝这笔交易。对于应用方来说,只要在任意一个区块链节点内,当区块链高度超过 BlockLimit 的后仍然不能检索到交易,就可以断言这个交易一定是失败了,可以重新发起重试了。

关于失败的确定性 —— 定时出块是十分重要的

关于确定性的另一个问题,在下一个区块出现前如何判定交易是否成功。在很多区块链设计中,为了节省空间,设计者通常倾向于采用“没有交易时不产生区块”的策略,我们称之为空闲期停链的设计。但这个设计会产生一些问题,设想这样一个场景:某银行将张三存款一万元的交易,发送到一个空闲期停链区块链账本的节点上,接下来的两个小时内,银行的查询节点没有得到任何新块,这时银行要如何判断到底是张三的交易在其它节点共识时抛弃了呢?还是已经被记录到其它节点,但本地节点没收到通知?如果没有定时出块机制,银行是无法做出判断的。

络谱平台自主研发的区块链采用定时出块的策略,即使区块链没有收到交易,也会定时产生一个空区块,区块内含有必要的时间、摘要等信息,没有交易。这时银行可以作出判断——如果新块内没有交易,则说明交易确实没有得到最近的共识机制的支持,如果长时间没有收到新块,则说明网络出现故障,需要尽快通过技术修正来解决故障。


关于 nonce 的设计方案,在以太坊白皮书中有一个典型的例子 

《关于区块链的确定性》有1个想法

发表评论

电子邮件地址不会被公开。 必填项已用*标注