区块链分片的理念与挑战,Part-1

本文是 Blockchain Sharding(区块链分片技术)系列的第一篇。阅读完本文之后,您将了解为何 Sharding(分片)是通往区块链协议未来的大方向、当前分片方案的构建方式、所有分片协议面临的共同挑战、以及如何解决这些挑战等内容。本系列中的第二篇将探讨更为高级的主题,如数据可用性、数据有效性等内容

众所周知,本文写作之时,在以太坊这一最常用的通用区块链上,主链每秒所能处理的交易量不到 20 笔。由于这种局限性,再加上以太坊网络的受欢迎程度,带来的是高昂的 Gas 费用(即用户在网络中执行某笔交易所需付出的手续费)和很长的交易确认时间;根据 ETH Gas Station,尽管当前每 10~20 秒就能产生一个新的区块,但每笔交易被打包进入区块所需的时间却要 1分 12 秒。低吞吐量、高价格和高延迟是当前以太坊面临的主要问题。

以太坊网络低吞吐量的主要原因是什么?原因是网络中的每个节点都需要处理所有交易。开发者已经提出了很多在解决协议层吞吐量问题的方案,这些解决方案基本可以分为两类:一类是将所有计算委托给一小组强大的节点来完成,另一类是让网络中的每个节点都只需处理所有工作中的一部分

前一种方法的一个极端例子就是只通过一个节点来处理所有交易的 Thunder,该平台声称可以实现每秒处理1200笔交易,比以太坊网络提高了100倍(在此我并不是为 ThunderCore 背书,也不想证明其结论的有效性)。还有 Algorand、SpaceMesh、Solana 等都属于前一种解决方案,通过对共识协议和区块链自身的结构进行各种改进,以此来处理更多的交易,但这种方式存在限制,即单个机器能处理的交易量(尽管很大也总)是有限的。

后一种方式就是 Sharding(分片),即将网络中的工作分摊给所有参与的节点。这就是当前以太坊基金会(EF)计划扩展以太坊网络的方式。截至目前,有关分片的完整技术规范还没有公布。

我写了一份关于以太坊分片的详细概述(编者注:中译本见文末《ETH2.0 中的分叉选择规则》),也比较过以太坊信标链方案与 Near 的分片方案。

Near 协议 也在开发分片。Near 团队包括三位前 MemSQL 的工程师,负责开发分片、跨片区交易和分布式参与(distributed JOIN),还有五位前谷歌工程师,都具有丰富的分布式系统工程经验。

本文中我将总结区块链分片的核心理念,这是包括 Near 和其它大多数分片协议的基础。后续的文章将列举分片技术中更高阶的议题。

最简单的分片:Beanstalk

我们从实现分片的最简单的方式开始讲,本文将这种方式称为 Beanstalk。Vitalik 在他的文章中将之称为“scaling by a thousand altcoins(通过上千种山寨币来进行扩展)”。

在 Beanstalk 这种分片方式中,我们不会只运行一条区块链,而是运行很多条链,并将一条链称为一个“shard(片区)”。每个片区都会拥有独立的一组验证者(Validator),即通过 PoW 机制挖矿或者投票机制来验证交易和生成区块的网络参与者。我们暂时假设各个片区从不相互交流。

Beanstalk 的设计很简单,但已足以推理出分片技术面临的一些主要挑战。

参与的验证者&信标链

首当其冲的挑战就是,由于每个片区都有自己的验证者,单个片区的安全性就会比整条链更差。例如,如果一条有 X 个验证者且没有分片的区块链,决定硬分叉成一条有分片的链,并将 X 个验证者分摊到10个片区中,那单个片区中的验证者数量就是 X/10个,因此只需要控制总验证者数量的 5.1%(51%/10)就可能破坏一个分片。

这将我们带到了第二点:由谁来为每个分片选择验证者?要知道,只有当所有被控制的 5.1% 的验证者都在同一个片区中,才有可能破坏该片。如果验证者无法自主选择参与哪个片区,那某个控制 5.1% 验证者的参与者就很难让所有这些验证者都处于同一个片区,这就大大降低了该参与者破坏整个系统的能力。

当前,几乎所有的分片设计都依赖于某种随机性(randomness)源来为分配验证者。链上随机数本身就是一个非常具有挑战性的话题,我还是以后单独出一篇文章来讨论吧。现在,先假设我们可以实现这种随机性。

随机性和验证者分配都需要计算,这些计算并不是专为某个特定片区而运行的。为了实现这种计算,实际上所有现有的设计都包含一条单独的区块链,负责执行维护整个网络所需的操作:除了生成随机数和将验证者分配到各个片区,还包括接收分片的信息更新(并创建快照)、处理权益证明(PoS)系统中验证者质押的押金及其罚没,并(在支持该功能之后)不断重划片区(rebalancing shards)。这条链在以太坊和 Near 中就是信标链(Beacon Chain),在 Cosmos 中就是 Cosmos Hub,在 PolkaDot 中就是一条中继链(Relay chain)。

在本文中,我们将这种链称为信标链(Beacon Chain)。信标链的存在将我们带入了下一个有趣的话题,即二次方分片(quadratic sharding)。

二次方分片(Quadratic sharding)

Sharding(分片)通常被宣传为一种能够通过增加参与网络的节点数来实现网络无限扩展的解决方案。虽然理论上是可能设计出这样一种分片解决方案,但任何基于信标链(Beacon Chain)概念的解决方案都不可能无限地扩展。为什么这样说呢?因为信标链需要做一些记账计算工作,比如上文中提到的,信标链需要将验证者分配到各个分片链中,并对分片链区块做快照,这些计算量是与系统中分片的数量成正比的(即分片数量越多,计算的工作量就越多)。由于信标链本身也是一条区块链,其处理能力受到运行信标链的节点的计算能力的限制,因此分片的数量自然是有上限的

但是,分片网络的结构确实会使节点改进而产生倍乘效应。因为任何提高节点效率的提升都会使节点能更快地处理交易。如果运行网络的所有节点(包括信标链中的节点)处理交易的速度都变成 4 倍,那每个分片能够处理的交易量将是之前的4倍,且信标链能够维持的分片数量也将是之前的4倍。由此来看,整个系统的吞吐量将变成 4x4=16 倍——这就是为什么这种方案被称为“二次方分片(quadratic sharding)”。

当前还很难准确地衡量划分多少分片是可行的,但在可预见的未来,区块链用户的吞吐量需求不太可能超出二次分片所能提供的。若要安全地处理那么大的交易量,大量的分片所需的节点数量会比现在所有区块链的节点数总量还要大上几个数量级。

但是,如果我们想要开发可以迈向未来的协议,研究这一问题是非常有必要的。截至当前,最为完备的提议就是指数增长式分片(exponential sharding),其中片区会组成一棵树,每个母分片(parent shard)统筹一系列子分片(child shard),而母分片本身可以是其他分片的子分片。

众所周知,Vlad Zamfir 正在研究一种不涉及信标链的分片设计,我曾与他共同研究过相关的原型,具体细节请参阅此文。

状态分片

到目前为止,我们还没有很好地对此进行定义:当网络被分成多个分片时,什么东西被划分开来了,什么东西没有被划分开来。具体而言,区块链网络中的节点主要执行三个重要的任务:1)处理交易;2)将已被验证的交易和已完成的区块中继给其他节点;3)存储整个网络账本的状态和历史记录。这三项任务中的每一项都对运行网络的节点提出来越来越高的要求:

  1. 随着需要处理的交易的数量不断增长,节点处理交易时需要更多的计算能力;
  2. 随着需要中继的交易的数量不断增长,节点在中继交易和区块时需要更多的网络带宽;
  3. 随着状态的增多,节点在存储数据时需要更多的存储空间。重要的是,与前两者不同,即便交易率(即每秒处理的交易量)不变,节点的存储需求依旧会不断增加。

由此可见,存储需求看起来似乎是最为紧迫的,因为它是唯一一个即便每秒处理的交易量不变,照样会随着时间的推移而增加的要求。但实际上,当前最为紧迫的是对计算能力的需求。目前,整个以太坊状态为 100G,对于大多数节点来说都不是什么难事。但当前以太坊可以处理的交易量约为每秒 20 笔,比许多实际用例中所需要的 TPS 少了好几个数量级。

当前最著名的对交易分片(而非对存储分片)的项目是 Zilliqa 。对交易处理进行分片是一个很容易解决的问题,因为每个节点都存储网络的完整状态,这意味着每个合约可以自由地调用其他合约,并从区块链中读取所有数据。为此仅需要一些谨慎的工程,保证来自多个分片的状态更新不会相互冲突。由此来看,Zilliqa 采取了一种非常简单的方法,详细的分析可参阅我的这篇文章。

虽然很多人提议对存储进行分片,而不是对交易处理进行分片,但我还没有看到有任何项目在这么做。在实践中,对存储进行分片,或者说状态分片(State Sharding)几乎也就意味着同时对交易处理和网络进行分片。

实际上,在状态分片中,每个片区中的节点就是在搭建自己的一条分片链,这条链中包含的交易只会影响这条分片链本地的状态。因此,分片中的验证者只需要存储本地的状态,并且只需执行和中继那些影响本地状态的交易。这种拆分减少了节点对计算能力、存储和网络带宽的需求。但也引入了新的问题,如数据可用性和跨分片交易。我们会在下文中探讨这些问题。

跨分片交易

Beanstalk 并不是一种非常有用的分片模式,因为如果各片区之间不能相互交流,那这些分片也就和多条彼此独立的区块链没有区别。即便是分片技术还未开发出来的现在,人们对区块链间互操作性的需求也是非常巨大的。

我们现在只考虑简单的支付交易,其中每个参与者只在一个片区中有一个账户。如果某人希望将一笔资金发送给同一个片区中的另一个账户,这笔交易完全可以由该片区的验证者来处理。但是,如果 Alice 的账户在分片 #1 中,她想把资金发送给 Bob,而 Bob 的账户在分片 #2 中,则不管是分片 #1 中的验证者(他们无法将资金记入 Bob 的账户中),还是分片 #2 中的验证者(他们无法将资金从 Alice 的账户中扣除),都无法完整地处理这笔交易。

在跨片区交易方面,存在两种方式:

  1. 同步:每当需要执行跨分片交易时,在包含相关交易所涉状态的多个片区中同时产生区块,并且这些片区的验证者们会协同执行这笔跨片交易。在这个方向上,我知道的最为详细的提议就是 Vitalik 提出的 Merge Blocks(合并区块),见 ethereum research 上的相关帖子。
  2. 异步:即一笔影响多个片区的跨片交易在这些片区中异步执行,“记入资金”的片区(即上文例子中的片区 #2)一旦获取了足够的证据证明“扣除资金”的片区(即上文例子中的片区 #1)已经完成了自己的那部分工作(即已经将资金从 Alice 账户中扣除了),则“记入资金”的片区就会完成自己的工作(即将资金记入 Bob 的账户中)。这种方式更为普遍,因为更简单且片区之间更易于协作。当前,Cosmos、以太坊 Serenity、Near、Kadena 等都提议这种系统。但这种方式的问题在于,如果与这笔跨分片交易相关的那些区块是独立生成的,那么这些区块有概率会变成孤块,使得这笔交易只完成了一部分。我们来看看下方的图片,图片中 Shard#1 和 Shard#2 这两个片区都产生了分叉,其中区块 A (属于 Shard#1)和区块 X'(属于 Shard#2)记录了一笔跨片区交易。如果 A-B 和 V'-X'-Y'-Z' 都在各自的片区中变成了主链,那么该笔交易就最终确定了。如果 A'-B'-C'-D' 和 V-X 变成了主链,该笔交易就会被完全抛弃掉,从交易处理的角度来说这也是可以接受的。然而,如果 A-B 和 V-X 变成了主链,那么交易的一部分达成了确定性,另一部分又被抛弃掉,这就产生了原子性故障(atomicity failure,即让观察者无法清晰地判别某事务到底是处理成功了还是失败了)。我们将在本系列的 Part-2 讨论分叉选择规则和分片协议共识算法时讨论如何解决这个问题。

需要注意的是,除了分片链之间的交流外,未进行分片的链与链之间的交流也是非常有用的。区块链之间的互操作性是一个很多项目都在试图解决的复杂问题。在进行了分片的区块链中,解决互操作性问题要稍微容易一些,因为所有分片之间的区块结构和共识协议都是一样的,而且还有一条信标链用于充当协调功能。在分了片的区块链中,所有的分片链都是一样的。而全球所有的区块链生态系统中,有很多条不同的区块链(如以太坊、比特币、EOS等),这些区块链有着不同的目标用例、去中心化程度和隐私保障,因此,解决这些链之间的互操作性问题要难得多。

若一个系统中的所有链都具有不同的属性,但使用非常类似的共识协议,有着类似的区块结构且共享同一条信标链,那么这样的系统可以成为一个异构区块链生态系统,包含有可运作的互操作性子系统。但这样的系统不太可能实现验证者轮换的功能,因此需要采取一些额外的措施来保证安全。Cosmos 和 PolkaDot 本质上就是想做这样的系统。Cosmos 团队的 Zaki Manian 写的这篇文章对这两个项目之间的一些关键方面进行了概述了对比。

恶意行为

你现在已经知道了分片是如何实现的了,包括信标链的概念,验证者轮换和跨分片交易。

在掌握这些信息的同时,还要考虑一件重要的事情。具体来说,就是恶意验证者将可能采取什么对抗性的恶意行为。

恶意分叉

一组恶意验证者可能会企图创建一个分叉。请注意,不管底层的共识协议是否是拜占庭容错的(BFT),这都不重要,只要腐化足够数量的验证者,就完全有可能创建一个分叉。

对单个分片进行 51% 攻击,比对整个网络进行 51% 攻击要容易得多(我们会在之后的文章中详细讨论这种概率)。如上所述,跨片交易涉及到多个分片的某些状态改变;而在这些分片中记载状态变化的相应区块,要么必须完全被敲定,要么必须被完全放弃(否则就无法保证原子性,跨片交易也就变得不安全)。由于一般来说,分片被破坏的概率不能被忽略,我们不能假定分叉是绝不可能发生的,即便分片验证者之间可以实现拜占庭容错共识,或者在状态改变了的区块之上已经生成了很多区块。

这个问题有多种解决方案,其中最常见的解决方案是,不定期地将分片链上的最新区块与信标链进行交联(cross-link)。分片链上的分叉选择规则会变为永远倾向于选择那条已经进行了交联的链,且仅仅将分片的分叉选择规则应用于上一次交联之后发布的新区块。我们将在本系列的 Part-2 进一步探讨什么是分叉选择规则,并对分片区块链的分叉选择规则提议进行深入分析。

许可无效的区块上链

在进行了分片的区块链中,一组验证者可能企图生成一个使用非法状态转换函数的区块。例如,交易前的状态是 Alice 有10个代币,Bob 没有代币,区块中包含的交易实际应该是 Alice 发给 Bob 10个代币,但交易后的状态却是 Alice 没有代币而 Bob 有1000个代币。

在一条传统的、没有进行分片的区块链中,上述这种攻击是不可能出现的,因为所有网络中的参与者都会验证所有区块,这使得那个存在这种无效状态转变的区块会被其他区块生产者和网络中没有创建区块的其他参与者拒绝。即便怀有恶意的验证者继续在这个无效区块上创建更多的区块,且速度要比搭建正确链的诚实验证者更快,使得这条包含无效区块的链要更长,这都不要紧,因为使用该条区块链的每个参与者,无论出于何种目的,都会验证所有的区块,并且会抛弃所有那些搭建在无效区块之上的区块。

在上图中,一共有五名验证者,其中三名是恶意验证者。这是那么恶意验证者创建了一个无效区块 A’,并继续在这个区块之上创建新的区块。两名诚实验证者将 A’ 认证为无效区块并将之丢弃,并在已知的最后一个有效区块上创建一个分叉。因为在诚实的分叉链中验证者更少,因此该条链会更短。在传统的、没有进行分片的区块链中,使用该区块链的参与者们,无论出于何种目的,都有责任验证所有他们接收到的区块,并对区块状态进行重新验算(recompute the state)。因此,所有与该链利益相关的人都会观察到区块 A’ 是无效的,因而也会立即丢弃区块 B’、C’ 和 D’,并将 A-B 链当做当前最长的有效链。

然而,在进行了分片的区块链中,没有任何一个验证者可以验证所有分片中的交易,因此验证者们必须通过某种方式来确保,该区块链的任何片区的历史记录中都不存在无效区块。

注意,这与传统区块链中的分叉不同(校对注:传统区块链协议运行中出现的分叉区块都是合法的,只不过是在某个时间段内存在同一高度的两个区块而已),即使信标链交联的方案也无法完全解决这个问题,因为信标链没有验证区块的能力,它只能验证某片区中有多少验证者给某区块签过名(并据此认可片内区块有效性)。

对于这个问题,我只能想到两种解决方案,然而目前这两种方式都没有真正令我满意:

  1. 设定某个合理的机制,当有人企图添加采用了错误状态转换函数的区块时,该机制能向系统发出警报。假设每个分片都在运行某种拜占庭容错(BFT)共识,如果某个特定分片中的恶意验证者的数量少于三分之二,则至少需要有一个诚实的验证者来验证区块,并验证该区块是否采用了正确的状态转换函数。如果恶意节点的数量超过三分之二,则他们可以在没有诚实节点的参与下敲定一个区块。假设某个分片上至少有一个节点是非恶意的,则需要某种机制使得这个(些)诚实的节点能对正在生成的区块进行监控,并给予他们充分的时间来对使用无效状态函数的节点发起挑战。
  2. 在区块中设置一些足以证明使用了正确状态转换函数的信息,但比直接使用状态装换函数进行验证要更具更便宜。最接近这种想法的机制是 zk-SNARKs(虽然我们并不是真的需要“zk”,也即零知识证明的功能,非零知识 SNARKs 就足矣),但 zk-SNARKs 的计算速度非常慢。

当前,很多协议都认为,只要搭载了适当的验证者混洗机制或拜占庭容错共识,是不可能会出现分叉或者无效状态转换的。我们将在本系列 Part-2 讨论为什么这种假设并不合理。

结尾

看完上面的信息,您现在对分片的大部分重要内容都有所了解了,例如信标链的概念、计算与状态分片、跨片区交易。敬请关注第二部分,我们将更深入地探讨预防攻击的措施。

请加入我们的 Discord 频道,我们会在那里讨论 Near 协议的技术和非技术细节,比如共识机制、经济模型和治理模型:https://discord.gg/nqAXT7h。

最近我们也将开源我们的代码,请在这个帖子里查看详情,或在 GitHub 上研究我们的代码。

此外,在 Twitter 上关注 Near 协议吧,这样就不会错过我们以后发布的博客:

http://twitter.com/nearprotocol 以及 http://twitter.com/AlexSkidanov。

最后,请订阅我们的新闻。我们会每两周发布一次更新,这也是了解我们进度的最佳渠道。

非常感谢 Kadena 团队的 Monica Quaintance 以及 Cosmos 团队的 Zaki Manian,感谢他们为本文提供了大量宝贵的反馈。

原文链接: https://medium.com/nearprotocol/the-authoritative-guide-to-blockchain-sharding-part-1-1b53ed31e060
作者: Alexander Skidanov
翻译&校对: Jhonny@Unitime, Echo@Unitime & 阿剑

本文由作者授权 EthFans 翻译及再出版。感谢 Unitime 授权 EthFans 使用他们的初始译稿。再出版时阿剑对译本做了校对。

你可能还会喜欢:

干货 | 探究以太坊 2.0 的分叉选择规则
干货 | 分片设计哲学
观点 | 以太坊的愿景(下):是是非非

评论