区块链技术的「不可能三角」与多方状态通道解决方案

对区块链技术面比较了解的小伙伴应该都知道当前制约区块链的一个不可能三角,一个是安全,一个是性能,一个是可拓展性。

不可能三角的意思就是无论我们怎么研发,都最多只能同时兼顾这三者之中的两者。举个例子,你要提升性能和可拓展性,那肯定就会牺牲安全性。虽然目前还没有很严谨的证明来验证这个不可能三角的正确性,但是区块链经过这么十来年的发展,说实话的确是在这三个要素之间来回挣扎,有专注做安全的,比如隐私交易;有做高性能的,比如EOS;有做高可拓展性的,比如IoT类的链;当然也有尝试兼顾的,比如Algorand。

但是除了这些在链本身下功夫的项目之外,也有人把眼光投到了链外,比如侧链,比如rollup,也比如状态通道。通过链外处理的方式把那些大量的中间交易放到链外解决,主链只负责最终状态的同步和资产安全的管理。链下方案其实是一个比较合理的方案,甚至可能比现在以太坊拼了老命也想更新的2.0更合理。当然这个只是个人意见,暂且不谈。

而这次被AsiaCCS2022接收的文章就是专注于链下方向之一的状态通道的。论文的名字是「Speedster: An Efficient Multi-party State Channel via Enclaves」, 就是通过可信执行环境来提升状态通道的功能和性能。我的单位为南科大、韦恩州立大学和Neo,合作作者是南科大的张锋巍教授,普渡大学的孙文海教授和韦恩州立大学的施巍松教授。(说起来我自己是个可信执行环境的死忠,奈何这种硬件解决方案不受待见~Neo的小伙伴们目前主要在探索零知识证明的各种方案。)

多方状态通道

状态通道本质是一个在主链上创建的、由两个人共同控制的账户。只有两个人同时操作才可以从这个账户里取钱。由于是两个人共同操作的账户,两个人就可以在链外通过状态通道任意的发送任何交易,这些交易都不需要上链,只需要在两个人想要关闭通道的时候共同协商好这个链上账户的资产分配就行了。

是不是听起来很方便?比如你去一家经常吃饭的饭店吃饭,你就可以用这个状态通道支付,只要提前跟老板创建个状态通道,然后你把钱存进去,以后吃饭只要你们线下交易就可以了,完全不用等待漫长的共识,连手续费都不用付。这里技术细节不再赘述。

但是这个方案好是好,可是不完美。首先是这个方案里每个通道就只能有两个人参与,也就是说你跟老板的通道就只有你俩能玩,别人加不进去。这个重要么?重要!如果我们想要在链下执行复杂的逻辑,那只有两个人才能参与的状态通道显然是满足不了需求的,我们肯定需要能有多人参与的状态通道。

为了解决这个问题,之前有人研究了虚拟状态通道,就是在两个人跟两个人之间的通道上面再虚拟出一个可以多个人参与的通道。有一点类似于网络里的NAT,本来没有的东西,但是我用逻辑给你虚拟出来。Celer Network在做那种围棋(五子棋?)比赛的时候是用的两两匹配,然后晋级的人再匹配的形式(当然他们用了多跳,为了简化介绍不赘述)。那有没有一种形式可以直接把所有人都连接在同一个状态通道里,并且可以像我们的局域网似的,任何人想加入就加入,想离开就离开呢?

这就引出了我们的工作——一种基于可信执行环境的高效多方状态通道。

我们的独特优点如下

支持多方状态通道
可以在链外创建和关闭状态通道
可以实现最高百万级别的TPS

我们的状态通道可以最高实现百万级别的TPS——相对于现在主链上几十上百TPS来讲,百万级别的TPS是很恐怖的。在我们之前也有专注于用可信执行环境来实现状态通道的,叫TeeChain,这个工作是发在计算机顶会SOSP上的,不过这个工作比较早,是专注于比特币的支付通道,而且不支持多方通道TPS也没有我们来的高。

我们的工作的原理其实就是在以往只信任区块链主链这种信任模型里加入链外的可信基,就是可信执行环境。

在我们的系统里,用户不仅可以信任区块链,还可以信任这个基于硬件的可信执行环境。用户在这个环境里创建并管理一个账户,然后用这个账户去在线下跟别人交易,别人就会相信你这个账户不会发生双花交易,并且不需要在链上做验证。

也是因为有链下的信任基,所以哪怕多方之间参与共同的状态通道也不会出现问题,只要每一方都使用基于可信执行环境的账户就可以。至于效率方面,我们抛弃了在区块链领域里通用的数字签名机制来给交易的真实性提供保护,转而使用基于对称加密的AES-GCM来保护状态通道中的交易,这个目前在整个区块链领域还是独一份。由于这个转变,交易的执行速度提升了数倍。

运行时随机数

而我跟Neo的小伙伴们当前正在进行的工作,则是为智能合约在运行时提供安全的随机数。

在我之前很多的博文里都有提到过为Neo的合约提供随机数这件事。从18年开始,我就陆陆续续提出了好几个不同思路的方案,甚至有基于可信执行环境的思路。后来EOS大量的博彩类DApp因为随机数暴雷,Chainlink推出了基于VRF的随机数发生器,以太坊2.0里也计划推出基于延迟函数的随机信标,Loot用哈希函数来生成随机数,我就更感觉随机数的研发迫在眉睫。索性去年的时候有了机会可以跟Neo的小伙伴开始一起研究探索随机数方案。

不同于Chainlink,我们不想要那种基于回调机制的随机数方案。用户需要先把交易的参数提交到链上,再由Chainlink的VRF计算出随机数然后通过另一笔交易把随机数推送给合约。主要原因如下

· 我们做过测试,这种方案需要的额外开销是很大的,不管是手续费的开销,还是主链需要承担的额外的数据存储开销都很大。

· 在这种方案里合约的逻辑需要拆开到两个函数中,用户需要等待很长的时间才能得到执行结果。

我们想要的随机数是那种用户发送交易到链上,合约执行过程中直接就可以请求到随机数,用户的交易直接就可以完成执行,并且合约可以请求任意数量的随机数。

目前在区块链领域,Neo以外,除了那些专注于隐私保护智能合约的区块链项目,比如Oasis和Ekiden,还没有项目可以实现运行时随机数。这个问题的难点在于,如果不采用回调的机制,那么攻击者就可以在你生成随机数之后立即针对性的构造攻击载荷实施MEV攻击。

所以想要提供运行时随机数,首先就是要解决掉MEV攻击。我们现在的思路是解决MEV主要靠把区块交易列表的生成权限从议长提案改成共识聚合。从以往议长一个人单独决定交易顺序的模式换成由每一个共识节点都提出自己的交易列表,然后在共识的过程中由多个列表聚合成一个最终的交易列表,这样就可以保证没有任何人可以发动MEV攻击。在解决了随机数之后,再由BLS这种聚合签名算法来为每一个区块生成一个随机数种子。由于BLS本身支持门限签名,因此BLS不会阻碍正常的dBFT共识过程。然后在交易的运行时由伪随机函数来不断地给合约提供随机数。

但是目前我们的工作还有一个较大的问题亟待解决,那就是BLS本身是需要一个秘钥分发的过程来实现初始化,这个初始化的过程如果使用DKG的话,那每次共识节点更新的时候,都要进行一次DKG的过程,而如果DKG失败了或者延迟很高,那很可能会导致新一轮的共识节点之间没有完成BLS的初始化,这样就会导致出块失败。

Neo的小伙伴为此开发了一套很复杂的容错机制,但是需要对共识机制本身进行修改,所以目前还处于研究阶段。另外一个思路则是使用动态秘钥更新机制,这种机制可以实现区块链共识节点的更新,同时实现BLS秘钥的安全转移。目前相关的工作已经完成了论文的撰写,不过想要把运行时随机数真正完成部署还要一些时间。