前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我们是如何用分片技术把7笔/秒的区块链交易提升到2488笔/秒的?

我们是如何用分片技术把7笔/秒的区块链交易提升到2488笔/秒的?

作者头像
区块链大本营
发布2018-05-11 14:55:41
8280
发布2018-05-11 14:55:41
举报
文章被收录于专栏:区块链大本营区块链大本营

内容 | 贾瑶琪 Zilliqa技术总监、联合创始人

整理 | Aholiab

众所周知,吞吐量一直是区块链的一个痛点。比特币的底层设计仅支持每秒7笔交易,还不及传统支付工具Visa每秒8000笔交易的一个零头,更别说支付宝在去年双十一创造的每秒25.6万笔的记录。这严重制约了去中心化应用的发展。去年以太猫风靡全球,造成了以太坊的大堵塞,以至于人们戏称用是否造成区块链堵塞来评价去中心化应用的热度。

针对如何提高区块链的吞吐量,业界也在不断尝试。为改善比特币网络的吞吐量,去年比特币硬分叉出了比特币现金。

近期,Zilliqa技术总监、联合创始人贾瑶琪谈到了这一问题的解决方案。

贾瑶琪来自Zilliqa团队,之前在新加坡国立大学读博士,博士期间主要研究偏底层的网络协议,以及点对点协议的隐私保护,还有可扩展性问题。2017年,跟师兄还有导师一起创建了Zilliqa团队,主要就是用分片技术,来提高整个公有链的可扩展性,以及实现高吞吐量

说到分片技术,里面包含很多种不同的技术。比如以太坊的分片技术,还有Zilliqa的分片技术。

公有链的吞吐量问题

大家可能都了解比特币、以太坊,以及其他的公有链。区块链技术为大家提供了很多好的特性,比如去中心化、透明性、以及不可篡改性。但如果大家把区块链作为一个记账或者帐本系统,这其中有一个很大的问题,就是关于吞吐量的问题。

比特币每秒最多只能处理7笔的交易,如果用搭火车的例子来讲,比特币就对应着手工检票,每秒只能检7个人。而传统的记帐系统,例如信用卡、VISA或者MasterCard,他们平均的处理效率超过每秒8000笔交易,就类似于现在我们高速公路上使用的ETC,或者检票中刷脸进站的系统,可以迅速地处理大量的交易。

低吞吐量的弊端

由此可见,目前公有链的低吞吐量会带来很多问题,例如大家都会见到的高手续费问题。在去年有一段时间,如果你在比特币上面进行一些交易,比如A转比特币给B,手续费可能就高达50美元。另一个方面,像以太坊去年做ICO,或者做这种代币募资,很多人为了抢资格,就会花费很高很高的手续费,来竞争去加入一个代币募集。

其实,虽然你设置了这么高的手续费,有时候也是抢不到这个资格的。高手续费会限制很多功能,从而导致我们现在没有一个很好的杀手级的应用。大家可能都知道,去年在以太坊上面最火的两个应用,一个就是ICO,另一个就是风靡全网的以太猫。但以太猫在以太坊上比较火的时候,占据了以太坊上超过30%的流量,导致整个以太坊有很多的拥塞。在那个时候,如果你想做一笔简单的转帐,必须支付更高的手续费才能完成这笔交易。

因此,这个低吞吐量导致了目前还没有杀手级应用。我们可以联想到在互联网初期,大家用的整个底层系统可能还没有搭好,同时网络费用又特别得高,我们只能浏览一些简单的网页。但随着整个互联网系统生态的发展,大家慢慢也会看到一些很伟大的公司。例如像Google、Facebook、Twitter,以及国内的百度、阿里巴巴、腾讯,他们的崛起就是因为这个底层生态系统建好了。有了这样的高吞吐量,才使得更多的企业以及程序员参与进来,创建许多杀手级的应用。

公有链的可拓展性

那么如何来解决低吞吐量问题,我们需要公有链有「可扩展性」,但可拓展性其实并不等同于高吞吐量。

很多场景下只需要高吞吐量,不需要可扩展性,所以你只需要一个很强大的服务器来提供一个很高的吞吐量。但是对于可扩展性,就要求你随着节点数的增加,你的吞吐量也得相应地增加(因为可扩展性更多地是指随着节点数目的增加,吞吐量或者性能也增加,所以很多时候大家其实是要求的高吞吐量而不是可扩展性)。

已有的解决方案

目前来看,比特币处理交易的速度小于每秒10笔,以太坊小于每秒20笔,但传统的记帐系统,例如信用卡,交易速度超过每秒8000笔交易。我们如何去解决这个可扩展性,或者说低吞吐量的问题呢?目前有几种方案。

方案一,增加区块的大小。例如比特币,我们现在一个区块的大小可能只有1MB的存储空间。如果要进行交易的话,只能把交易加到这1MB里面。如果大家也做比特币交易,可能都知道去年底的SegWit2x,将区块大小从1MB提高到2MB。但是出于对安全性和其他因素的考虑,最终Bitcoin Core取消了这个SegWit2x硬分叉。导致了当时大量的资金都投向了以太坊的ICO项目。

当你把区块大小从1MB升级到2MB,或者10MB,甚至1GB,但这个方案是否能达到提高100倍吞吐量的效果呢?不一定,因为你虽然可以把区块大小升级到1GB,但由于你的计算性能以及带宽的限制,导致整个网络不能正常运行。像比特币或以太坊,都是要通过工作量证明达成共识,工作量证明之后还要在整个网络进行广播,如果是1MB可能还好,如果1GB的话,要进行这个广播,基本上不可能在10分钟以内通知每一个矿工。所以这里面有一个很大的限制。

方案二,链下交易。对应比特币的闪电网络(Lightning Network)和以太坊的Raiden Network。他们给出的解决方案大致是这样的,你提前支付一些以太坊或比特币作为押金,之后你可以在链下通过一些手段,来跟其他人进行交易。这就类似于你提前在链上存了一些押金,然后其他的终端用户可以在咖啡店里和你进行交易。交易结束后,你要把这个结算放在区块链上面,这样一个链下的方案。因为你链下处理这些交易的话,可以用一个十分强大的服务器来进行处理。这样就可以大幅度提升系统的吞吐量,可以做到每秒上万,甚至是几十万的交易量,类似于淘宝。

但是大家可以看到,这里有一些问题,就是你一旦用链下的话,虽然能够达到高吞吐量,但是交易失去了开放性、透明性的优势,相当于做了客户端服务器的一个终端。同时由于你用链下交易,就没有那么多节点去进行行为监督,那么也就少了去中心化的优势。

方案三,代理人共识协议解决方案。如何选出这些代理人,你可以用权益证明,也可以通过一些官方的验证。例如我有一个公司,这个公司有相应的资质,那么官方就会给我发一张牌照,我就可以作为一个代理人。

不管是7个代理人还是21个代理人,甚至可能是几十个代理人,大家会形成一个小团体。例如我们现在这些人,都可以去做一个代理人。之后我们去运行一些共识协议或者类似功能的协议,来达成一个共识,产生区块,然后再将这个区块广播给整个网络,从而达成整个网络的共识。这样做的好处就是,这个机制可以保证在一个很小的团体内部,很快就达成共识。这样做很简单,只要使用一些已有的共识协议,你就可以很快达成共识。

不过,代理人共识协议也会带来一些问题,我们刚刚也有提到大家对于去中心化的担忧。因为像比特币或以太坊都有成千上万的节点来做共识决策。代理人共识协议目前只有一个小团体的代理人来做共识,难免会被大家质疑你是否去中心化,以及你的安全性。因为这一小部分的节点可能都是一些利益团体选出来的,他们是否能代表绝大多数人的利益呢?这些都是有待考证的。

不过以上这三个解决方案都是很好的解决方案,大家如果从不同维度,不同场景出发,这几个方案都是有很大的用处。而今天我要跟大家分享一下,我们Zilliqa是如何用另外一种解决方案,我们叫做分片技术,来实现这样一个高吞吐量的。我们的方案跟前面的几个方案不在同一个维度,但是几种方案其实是可以共生的。

一种新的解决方案

在讲分片技术前,大家可以先看看整体的结果和运行效果。这些数据都是在亚马逊的EC2上面测试得到的,通过搭测1800个节点、2400个节点以及3600个节点运行我们的算法,得到了下面的数据。直观上看,随着节点数以及分片数的提升,我们的测试数据,可以从每秒1218笔交易,达到每秒2488笔交易。

这样我们可以得出一个结论,相对于比特币或以太坊我们可以获得一个很高的吞吐量。另一点也很有意思,从图中我们可以看到随着节点数目的增加,吞吐量也是在增加的,我们真的实现了这种可扩展性。

讲了这么多,那么这个技术到底是怎样的呢?

分片技术概览

网络分片,简而言之就是并行化的分而治之。例如我们整个网络有1万个节点,我们可以把1万节点,分成不同的小组,每一个小组,可以有不少于600个节点,这样来叫做一个划分。划分之后,我们在每一个分片里,处理不同的交易。之后先在每个分片里面达成共识,然后会有一个单独的分片将共识的结果进行汇总,广播给整个网络。

在这个系统的初始化阶段,我们会将整个网络划分成不同的分片,每个分片不少于600个节点。过了一段时间,可能有一些新的节点想要加入,也可能有一些旧的节点因为自身网络的问题,或者系统的问题,想要离开。这种情况下,我们该如何将这些新的节点加入网络,将那些旧的节点从网络中剔除。

每过一段时间,我们都需要做一次工作量证明。工作量证明部分跟以太坊基本上是一样的,这要求你将上一个区块的哈希值、节点的IP地址和你的公钥一起进行哈希计算。大家都知道,哈希计算就是工作量证明,最终你要满足哈希值的阈值。对应的难度是相匹配的,例如哈希值的前100位都是0,如果你算出来的哈希值满足这个条件,就说明你完成了工作量证明。

之后你就可以产生这样的一个结果:我们会得出你的ID,之所以要你的ID就是因为我们会根据你ID的最后几位,来决定你应该被分到哪一个分片上。这样的话,对于一个新的节点来说,是无法通过自己的意志去加入某一个分片的,只能通过工作量证明,而工作量证明难度较高,因此可以避免出现新节点自己选择分片的情况。因此工作量证明的最后几位,就可以从数学上保证你的随机性是足够的。

如果一个节点想要加入我们的系统,他加入的方法就是做工作量证明,然后被随机分配到一个分片里面。这样做的好处就是,我们可以保证一些恶意节点不能直接加入到某一个分片,因为所有的节点都是被随机分配到不同的分片里面的。

有了这些分片,每个分片里面都有很多的节点,我们要怎样进行交易处理呢?我们在这里也做了一个交易分片,就是用来处理不同的交易,不同交易会被分到不同的片里面。那么每笔交易是根据什么来分到不同片里面?我们做了一个简单的分片处理,就是根据发送者的地址分片。那样的话,如果A把钱发给B和C,那么这两个交易应该是在同一个分片里面处理的,这样保证没有双重支付问题。

如果A发给B和C,但是你把A发给C的交易分到另一个分片里面,这个分片里面的节点,会很容易检测出来,然后把这笔交易拒绝掉。通过这种很简单的方式,我们达到一个交易分片的效果。因此你在不同分片里可以处理不同的交易,之后可以在每个分片里面,验证你的交易是否是正确的。验证过程很简单,例如A发给B了10块钱,分片会检查A的余额是否是足够的,如果A发给B了10块钱然后A又发给C了10块钱,那么分片就检查有没有双重支付的问题。

在每个分片内,每个节点都会进行这样的一个对交易的处理,之后通过运行一个协议达成共识,最终附上自己的签名,生成一个叫做MicroBlock的微小区块,提交给目录委员会,目录委员会会运行另一个共识协议,从而形成了一个共识。最终生成一个区块,并向不同的分片进行广播。

在这个过程中,每一个节点都可以收到最终的区块,这个区块的内容是很小的。同时,不同区块之间也会进行交换数据,从而分享最终区块内的这些交易。整个系统有三层结构:

  • 第一层,是哈希的哈希;
  • 第二层,交易的哈希;
  • 第三层,真正的交易内容。

通过这种三层结构来保证整个系统在每一步进行广播的时候,内容量都是相对比较小的。因此过了一段时间之后,你的不同分片里面,大家都可以获得这一段时间以来交易处理之后的一个共同状态。

刚刚提到了,在每个分片里面,我们都会运行共识协议。那么我们是如何来保证每个分片里面,超过100个的节点能够很有效而且安全地运行共识协议。这里我们用到了在2000年之前学术界很出名的容错协议,叫做:实用拜占庭容错协议——PBFT。

这样一个容错协议可以保证在一个小范围内,例如几十个节点,或者上百个节点,大家同时运行这个协议,最终形成一个共识。共识就是A发给B了多少钱,C发给D了多少钱,大家有这样一个共识之后,就可以去完成刚刚提到的协议。

我们还用了一个叫做「集体签名」,或「多重签名」的方案,从而减少拜占庭协议里对不同节点签名的要求。因为如果有600或者800个节点,都对同一个信息进行签名的话,就会有600、800这么多的签名数据,这个数据是很大的。所以我们用多重签名来减少集体签名数据量的大小。

最终通过结合PBFT和集体签名,我们实现了所要求的安全、高效的共识协议。在共识协议部分,如果大家只是把它当做一个黑盒的话,其实我们还有很多种选择的。

第一种,像比特币或者以太坊里面的共识协议,学术界把它叫做Nakamoto Consensus,用中文讲就是「中本聪协议」。可能有时候大家会把这个协议理解为只能做工作量证明,这种理解其实是不完整的。比特币的共识协议其实分两部分:第一部分,大家都在做工作量证明,过了十分钟,会有一个成功获得结果的人,他会生成一个新的区块。

这样是不够达成一个共识的,因为你之后还要再继续做工作量证明,在后面,要生成超过6个的确认区块,才能保证你在第一个区块里面那些交易被整个网络接收。所以比特币的共识协议分两部分,第一部分是工作量证明,第二部分还要有超过6个确认区块,才能保证你的共识结果是有效的。

但问题是这样的共识协议消耗的时间是很大的,例如在比特币里面,一个共识中运行一轮工作量证明要花费10分钟,再加上6个确认的区块时间,超过1个小时。那么你整体算下来,有可能会超过一个半小时才能确认你的交易。这样就导致比特币的吞吐量低,同时时间消耗高。

我们是否有其他选择呢?在学术界,只要使用PBFT或者类似的共识协议就可以相对高效地去实现多个节点之间的共识。举个例子,在一个房间里,A要给B发10块钱,A要给C发20块钱,B要给D发50块钱,那么我们这个屋子要形成一个共识,最终有哪些交易要加入到区块链里面?可能初期的话,会有一个领导者把大家的建议都收集起来,然后再分发给每一个人,说我现在收集到这么多交易,大家就跟随我把这些交易收集起来加入到区块链里面。这样每个节点都会收到一个请求,对于节点该如何决策呢?我作为一个节点,我怎么确定其他人也收到同样一个请求,或者同样一个区块呢?

那我就全网广播我收到的信息,广播给所有人,其他人也会广播给我。这样通过预准备,达到了初步共识的效果,即每个人都确定我收到这样一个区块,或者对应一系列的交易。最终再通过这样一个广播,来保证我知道超过三分之二的人也收到同样一个区块,或者同样一系列的交易信息。这样才能保证整个网络里面,大家都在同一个状态下面,每个人都知道,所有人收到了同样一个区块,大家可以继续往下一步走了。

这个共识协议很高效,运行几十个节点达成一个共识,大概只需要几十秒的时间。同时也很节能,不用做工作量证明。你的电脑不用无时无刻都在做哈希运算才能获得最终性。我们都知道,在下一个区块里面,这些交易是会被加进去的。

但是有一个问题,这中间有好多轮的广播。我收到交易之后,要广播给大家,大家也要广播给我,这样的话,信息的交换量是很大的,导致整个网络的拥塞程度是很高的。如果我们只用一个简单的数字签名来做,比如你把你的信息发给我,其他人广播也把他们的信息发给我,同时附上他们的签名。这样的话,如果600个人用传统数字签名,可能就会产生600条数字签名信息。这会导致整个网络非常拥塞,网络会很慢。所以我们之后就采用了多重签名技术。这个技术不算是新的密码学技术。好处就是可以把600个签名压缩成一个签名,大家可以想象,如果之前广播600个签名,现在换成一个签名,整个网络的拥塞程度会减轻很多。通过使用多重签名,整个网络的消息规模会减少,同时沟通成本会降低。

做一个简要的总结,就是每一个分片首先收到了多条交易,接着会运行拜占庭容错协议,大家先达成一个共识,有哪些交易要被写到区块里面。之后因为要记录下来,我们整个屋子N个人都同意把N个交易写在区块链上,我们就会采用多重签名,从而减少签名的大小,使得整个协议消耗比较小。

智能合约

当我们知道了分片技术带来的好处,以及分片技术给整个系统带来的高吞吐量之后,相当于我们有了一条高速跑道,还应该有一个相对安全,同时可以支撑高速性能的一辆跑车。所以我们就要开发对应的智能合约。

对于已有的智能合约,大家如果作为开发者可能都知道以太坊上的Solidity,在过去的两年里,以太坊上面的智能合约遇到了很多的漏洞和攻击。例如两年前,其中的The DAO漏洞导致价值6000万美金的以太坊被盗,去年Parity多重签名钱包的漏洞,导致超过3亿美金的帐户被冻结。

究其原因的话,首先是因为智能合约是一个很年轻,同时也是很复杂的编程框架。很多程序员写的一些逻辑,复杂性是很难想象的。我们知道编程时很多时候我们都是随着逻辑写代码,但是问题是我们写出来的代码,可能会有很多的不可预知性,比如那些边边角角的漏洞。还有就是目前的智能合约,没有一个形式化证明。在学术界现在有很多语言,它们都是支持形式化证明。形式化证明的意思很简单,就是我写出来了一系列的代码,我可以保证我写的代码就是我想要的逻辑,没有越出我想要的逻辑的框架

基于这些原因,我们团队设计开发了一个基于自动机的智能合约语言,叫做SCILLA。

对于一个程序,例如开关灯的操作,你可以有不同的状态,例如关闭、暗光、明亮,同时你也有很多行为来去触发使一个状态跳到另一个状态。例如短按一下、按一秒、以及长按。如果你在关闭状态,简单地按一下,就会切换到暗光状态,再按一下,切换到明亮状态。在智能合约里面,你可以很清楚地把这些状态互相进行切换的行为定义清楚。

这样我们就可以提供一个形式化的证明。同时对于程序员来说,也可以很清晰地得出自己想要执行的逻辑。目前SCILLA是非图灵完备的。之所以我强调非图灵完备,是因为我们发现像以太坊的Solidity,虽然是图灵完备的,但有时候是不需要的。你如果写以太坊智能合约,应该知道它的燃料限制,因此很多时候智能合约是不需要做无限循环的,同时燃料的限制也支持不了无限循环。虽然支持图灵完备,但更多的时候对于程序来说,非图灵完备可以保证一个更加安全的逻辑执行,而且非图灵完备其实大多时候也可以实现很多你想要的功能。

上图是一个SCILLA提供的众筹智能合约。大家可以看到,类似于以太坊上智能合约的这些不可变参数,以及可变的状态。不同于智能合约里面,我们这里用的是一个状态转换来实现每个人要贡献多少钱,以及退款是如何进行的。

下图是模拟的一个两年前的攻击,大家可以看到,智能公约要进行一个退款行为。最开始智能合约会检查发起人当时有没有给我打钱。如果给我打钱了,我在退款的时候就会按同样的数目退款给你,最终把智能合约针对投资人部分,设置为0。但问题是在攻击的时候,不是最终直接把这个状态设置为0,而是在最终设置为0。中间的部分,进行了一个跨智能合约的调用。结果是,如果智能合约碰到一个恶意的程序可以退回重来,再执行一遍这部分逻辑。这部分逻辑就会导致这个投资人的钱数,可以循环地进行增加。例如你运行一次代码,可以使得投资人的钱数增加一倍,反过来恶意的程序再运行回来,进行一个回调,又可以使得把投资人的钱数再增加一倍。这样无限地运行下去,导致他损失了超过6000万美元。

那么我们如何去做安全补救?很简单,如果程序员小心一点的话,可以去遵循这样一个模式。先去检查这个投资人是否当初投资了我,之后进行执行:如果你投资了我,我先把你这部分的数目在我这里设置为0(反正我后面要转帐的),之后再进行交互。交互时把那部分钱转帐给之前的投资人。

说起来很简单,但很多时候,作为程序员,我们可能会忽略掉这些安全检查。在SCILLA这里,我们可以用自己的编译器,做一个自动的检查。就是你如果在写类似代码的时候,必须要符合安全规范。就像刚才说的,先去检查,然后再去进行交互。如果你不遵循这个规范的话,我们的编译器是不会通过的,或者会给你提供一些对应的提示。

去中心化应用的落地场景

未来的话,因为我们有了这样一个相对高吞吐量的区块链平台系统,共享经济,例如OfO、Uber,这样的共享经济公司都可以将主要的业务逻辑放在区块链上,运用智能合约来处理不同的用户请求。目前大家都是通过一个服务器来进行这种中心化交易,但之后如果用区块链进行去中心化的交易,就可以省去很多中间的费用,以及中间的一些可能比较灰色的花销。当然区块链也可以用作支付网络,支付网络目前的痛点就是手续费很高,但是如果能实现高吞吐量,大家可以用相对低廉的手续费去做一些支付。

另一个方面,因为有了分片技术,我们之后可以做一些分片的并行计算,即类似于MapReduce的一些计算。包括深度学习,在不同分片里面,可以放不同的神经元(neuron)来进行科学计算。我们目前还是在做更多的测试,以及其他功能例如智能合约的开发。在上个月,我们已经放出了我们的测试网络,以及数字钱包。

大家可以通过https://explorer.zilliqa.com,去访问Zilliqa的测试网络。目前我们在其中加入了很多自己的交易,对这个网络进行压力测试。钱包的话,你可以通过https://wallet.zilliqa.com去访问,来生成自己的帐户,之后我们还会将一些测试代币放到你钱包里,你可以在我们的测试网络中进行一些简单的测试,包括对交易的测试。

最后,Zilliqa团队也在大量地招工程师,总部在新加坡(目前还没有分部)。包括核心工程师和去中心化程序开发工程师,我们也需要一些商业开发、市场开发的人才。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-04-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 区块链大本营 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云区块链服务平台 TBaaS
腾讯云区块链服务平台(Tencent Blockchain as a Service,简称TBaaS)致力于打造全球领先的企业级区块链技术平台,帮助客户、开发者及合作伙伴轻松创建和管理可托管、可扩展的区块链网络,助力产业协同发展。TBaaS 支持长安链·ChainMaker、Hyperledger Fabric等区块链底层平台,简化部署、运维及开发流程,实现业务快速上链,提升链上治理效率。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档