以太坊Sharding FAQ

当前位置:首页 > 区块链 > 区块链知识 发布时间:2018-03-08编辑:来源:www.chgold.com阅读数: 手机阅读
简介目前,在所有的区块链协议中每个节点存储所有的状态(账户余额,合约代码和存储等等)并且处理所有的交易。这提供了大量的安全性,但极大的限制了可扩展性:区块链不能处理比一个单节点更多的交易。很大程度上因为这个原因,比特币被限制在每秒3-7笔交易,以太坊每秒7-15笔交易,等等。然后,这提出了一个问题:是否有方法创建一个新的机制,只让一个小集合的节点来验证每笔交易?只要有足够多的节点验证每笔交易那么系统依然是高度安全的,但又足够少使得系统系统可以并行处理很多的交易,我们是否可以使用这种技术来大大增加区块链的吞吐量?有哪些简单但有缺陷的方式来解决这个问题?”简单的解决方案“主要由三大类。第一个是直接放弃独立区块链缩放性,而是假设用户将使用许多不同的”altcoins"。这种方法极大提升了吞吐量,但是是以安全性为代价:使用这种方案在在吞吐量上N-factor的增加必然伴随在安全性上N-factor的下降。因此,对于大于N小值可以被论证是不可行的。第二个是简单增加区块大小限制。这种方式可以起作用,而且在某些情况下可能是正确的处理方法,因为区块链大小可能更多受到政治上的约束而不是现实的技术考量。但不管个人对于个别案例的信念如何,这个方案不可避免有它的局限性:如果区块链运行的足够长,那么运行在消费者硬件上的节点就会退出,网络将开始只能依赖于少数运行区块链的超级计算机,这可能导致极大的中心化风险。第三个是“合并挖矿”,这是一种多区块链共存的技术,但所有的区块链共享同一的挖矿激励(或者权益证明系统中的赌注)。目前,Namecoin通过这样的技术从比特币区块链中获取了很大一部分的安全性。如果所有的矿工参与进来,理论上可以将吞吐量提升N倍而不会影响安全性。然而,这也存在这样的问题:它将每个矿工的计算和存储负载增加了N倍。所以,实际上这个方法仅仅是一个隐藏的区块大小限制提升方式。即使这被认为可以接受的,依然存在这样的缺陷:这些区块链不是真正被“捆绑在一起"的;只需要少量的经济激励就能说服矿工放弃或妥协某个特定的区块链。这种可能性是非常真实的,并且有合并挖矿被攻击的[真实历史事件](actual historical incidents),以及明确提倡使用合并挖矿攻击作为一种“治理特性”的开发者,对于给定的联盟,破坏区块链并不是有利可图的。如果每条链只有少数矿工参与合并挖矿,则集中化风险得到缓解,但合并挖矿的安全效益也大大降低。这听起来像是有某种扩展性三难困境在起作用。这三难困境是什么呢,我们能突破它吗?这三难困境表明区块链系统最多只能拥有以下三个属性中的两个:去中心化(定义为系统可以在每个参与者只能访问O(c)资源的场景下运行,即普通笔记本电脑或小型VPS)扩展性(定义为可以处理O(n) > O(c)交易)安全性(定义为最多使用O(n)资源就可以抵御安全攻击)在这个文档的其余部分,我们继续使用c来指代每个节点的可用计算资源大小(包括计算,带宽和存储),以及用n指代抽象意义上生态系统的大小;我们假设交易负载,状态大小和加密货币市值都与n成正比。有人认为,由于梅特卡夫定律,一个加密货币的市值应该与n ^ 2成正比,而不是n。 他们是正确的吗?不。为什么不?梅特卡夫法则认为,网络的价值与用户数量的平方成正比(n ^ 2),因为如果网络有n个用户,那么网络对每个用户都有价值,但是每个用户的价值是与用户数量成正比,因为如果一个网络有n个用户通过网络有n-1个潜在的连接,每个用户都可以从中受益。在实践中,实证研究表明,拥有n个用户的网络的价值”对于小的n值是与n ^ 2成比例且对于大的n值是与n×log n成比例“。这很容易理解,因为对于小的n值,这个论点是成立的,但是一旦这个系统变得很大,两个影响就会减缓增长。首先,实践中的增长通常发生在社区中,因此在中等规模的网络中,网络通常已经提供了每个用户关心的大部分连接。其次,连接往往是可以互相替代的。你可以争论说人们从k个连接中只能获得~O(log(k))的价值-有23个品牌的除臭剂可以选择是好的,但并不不是说比有22个选择好多了,而一个选择和零个选择是非常重要的差异。另外,即使加密货币的价值与k个用户的O(k * log(k))成正比,如果我们接受上述解释作为这种情况的原因,那这也意味着交易量也是O(k * log(k)),因为每个用户的log(k)价值理论上来自于用户通过网络执行log(k)的连接,并且状态大小在许多情况下也应该随着O(k * log(k)) 一起增长,因为至少有某种类型的状态是特定关心而不是用户特定的。因此,假设n=O(k * log(k)) ,并且基于n(生态系统大小)和c(单节点的计算能力)是我们使用的完美模型。有哪些适度简单但只部分解决了可扩展性问题的方法许多分片建议(比如国大的Loi Luu等人提出的这个早期的BFT分片方案,以及为比特币提议的this Merklix tree方案 1 )都试图只分片交易或者只分片状态,而不考虑其他方面 2 。这些努力是令人钦佩的,可能会带来效率上的提升,但他们遇到根本性的问题,他们只能解决其中一个瓶颈。我们希望能够每秒处理超过10000个交易,而且不必强迫每个节点成为超级计算机也不强迫每个节点存储一兆字节的状态数据,而这需要一个全面的解决方案即状态存储工作量,交易处理甚至交易下载和广播都跨节点分散。特别要注意的是,这要求在P2P级别做出变更,因为广播模型是不可扩展的,因为它要求每个节点下载和重复广播O(n) 的数据(每个被发送的交易),而我们去中心化的标准假设是每个节点只能访问各种O(c)资源。有哪些不试图“分片”任何东西的方法?Bitcoin-NG 可以通过另外一种区块链设计来增加扩展性,即如果节点花费大量CPU时间验证区块来使得网络更安全。在简单的PoW区块链中,存在较高的中心化风险,并且如果阀值增长到节点的CPU时间超过5%用于验证块则共识安全就会被削弱;Bitcoin-NG的设计缓解了这个问题。然而,这仅仅使得交易扩展性提升了大约常量因子5-50x 3,4 ,但并没有提升状态扩展性。也就是说,Bitcoin-NG式的方法与分片并不互相排斥,两者当然可以同时实施。基于通道的策略(闪电网络,雷电网络等)可以通过常量因子扩展交易容量,但不能扩展状态存储,并且还会带来他们自己独特的折衷和限制,特别是涉及到拒绝服务攻击;通过分片实现链上扩展(加上其他的技术)和通过通道实现链下扩展可以说是必要和互补的。还有其他一些使用高级密码学的方法。如Mimblewimble 和基于ZK-SNARKs的策略来解决扩展性问题的特定部分。初始化全节点同步,而不是从创世块验证整个历史,节点可以验证一个密码学证明当前状态合法地遵循历史记录。这些方法确实解决了合法性问题,但是值得注意的是,可以依靠加密经济学用更简单的方式而不是纯粹密码学来解决同样的问题-参见以太坊当前快速同步和神同步的实现。这两种方法都没有缓解状态大小的增长或者在线交易处理的限制。状态大小,历史,加密经济学,哦,我的天!在我们继续之前,先定义一些这样的术语!状态:代表系统”当前状态“的一个信息集合;确定交易是否有效,以及交易的结果,在最简单的模型中应该仅仅依赖状态。例如比特币中UTXO的状态数据,以太坊中的balances+nonces+code+storage,Namecoin中的域名注册项。历史:自从创世块以来的所有交易的有序列表。在一个简单模型中,当前状态应该是创世状态和历史的确定性函数。交易:进入历史的一个对象。在实践中,一笔交易代表了某用户想要做的操作,并且是加密签名的。状态转换函数:一个获取状态,应用交易并输出新状态的函数。涉及的计算可能包含对交易指定的账户中增加或减少余额,验证数字签名和运行合约代码。默克尔树:可以存储大量数据的加密哈希树结构,其中验证每个单项数据项只需要O(log(n)) 的空间和时间。详情看这里。在以太坊中,每个块的交易集合已经状态都保存在默克尔树中,树的根被提交在块中。收据:代表交易执行结果的对象,它并不存储在状态中,但仍存储在一个默克尔树中并提交到块 以便节点在没有拥有所有数据的情况下可以高效验证证明。在以太坊中Logs就是收据。在分片模型中,收据是用来促进异步跨分片通信。轻客户端:与区块链交互的一种方式,它只需要非常少量的计算资源,默认情况下只需要跟踪链的区块头,并根据需要请求关于交易,状态和收据的相关信息,并验证相关数据的默克尔证明。状态根:代表状态的默克尔树根哈希 5 。

(以太坊的状态树,以及状态根(state root)是如何嵌入到区块结构上的)

分片背后的基本思想?

把状态分成K = O(n / c) 分区,我们称之为”分片“。例如,以太坊的分片方案可能会将所有0x00开头的所有地址放入一个分片,所有以0x01开头的地方hi放入另外一个分片等等。在最简单的分片形式中,每个分片都有自己的交易历史,且在某个分片k中的交易影响仅限于分片k的状态。一个简单的例子是多资产区块链,其中有k个分片,每个分片存储余额和处理一个特定资产相关的交易。在更高级的分片形式中,包括了某些形式的跨分片通信能力,其中一个分片上的交易可以触发其他分片上的事件。

分片区块链的基本设计是怎么样的?

一个简单的方法如下。存在一些称为协调者的节点,其接受在分片k上的交易(取决于协议,协调者可以选择哪个k分片或者随机分配k)并创建排序规则。一个排序规则有一个排序头,一个形式为”这是在分片k上的交易排序“的短消息。它期望分片k的前状态根是0x12bc57,在当前排序的交易默克尔树根是0x3f98ea,并且交易被处理之后的状态根应当是0x5d0cc1。且协调者#1,2,4,5,8,11,13...98,99对其签名。

一个区块必须包括每个分片的排序头,在以下情况下区块是有效的:

    在每个排序规则中给出的前状态根必须与相关联的分片当前的状态根相匹配

    在排序规则中所有的交易是有效的

    在排序规则中给出的后状态根必须与上面给定的状态执行排序规则中的交易结果想匹配

    排序规则必须被该分片的至少三分之二已注册的协调者所签名

需要注意的是,在这样的系统中现在存在几个”层次“的节点:

    超级全节点 - 处理在所有排序规则中的所有交易,并且维护所有分片的全状态

    顶级节点 - 处理所有顶级(top-level)区块,但不处理或试图下载在每个排序规则的交易。相反,如果在某个分片中有三分之二协调者认为一个排序规则是有效的,那么这个排序规则就是有效的。

    单分片节点 - 充当顶级节点,但同时也处理某个分片的所有交易和维护全状态。

    轻节点 - 仅下载和验证顶级区块的区块头;不处理任何排序头或交易,除非它需要读取某个特定分片的状态的某些特定信息,在这种情况下,它下载该分片最近的排序头的默克尔分支并且下载在该状态下的默克尔证明期望值。

    这里面临的挑战是什么?

      跨分片通信 - 上述设计不支持跨分片通信。我们如何安全地增加跨分片通信。

      单分片接管攻击 - 如果在一个分片中攻击者接管了大多数协调者,要么获取足够的签名来阻止任何排序规则,要么更糟糕的,提交无效的排序?

      欺诈检测 - 如果得到一个无效的排序规则,节点(包括轻节点)如何能够可靠的得知,以便它们可以验证欺诈行为并且确认是欺诈行为之后拒绝这个排序规则?

      数据可用性问题 - 作为欺诈检测的子集,排序规则中缺失数据这种特殊情况会怎么样?

      超二次分片 - 在n > c^2的特殊情况下,在上面给出的简单设计里面,将会有超过O(c)的排序头,因此普通节点将不能处理它们,只能处理顶级区块。因此,在交易和顶级区块头直接超过两级的间接寻址是需要的(即我们需要”分片的分片“)。达到这个目标的最简单和最好的方式是什么呢?

      然后,交易的结果取决于之前发生在其他分片中的事件;一个典型的例子是货币转账,货币可以从分片 i 转移到分片 j ,首先在分片 i 中创建一个”借记“交易来销毁代币,然后在分片j中创建一个”贷记“交易来创建代币,并将借记交易的收据作为贷记证明是合法的。

      但是CAP定理意味着完全安全的分布式系统是不可能的,因此分片是无法实现的?

      CAP定理是于分布式共识有关的结果。一个简单的描述是:”在网络发生分区的情况下,你必须选择一致性或可用性,你不能同时拥有两者“。直观的论点很简单:如果网络分为两半,在一半网络中发送交易”发送10个代币给A",而在另一半发送交易”发送10个代币给B“,然后系统是不可用的,因为其中一个或者两个交易将不被处理,或者变得不一致,因为一半的网络将看到第一个交易完成,另一半将看到第二个交易完成。注意CAP定理与扩展性无关;它适用于多节点需要对某个值导致一致的任何情况,而不管它们所达成一致的数据量大小。所有现有的去中心化系统已在可用性和一致性之间找到一些折衷方法,在这方面分片并没有从根本上造成困难。

      我们如何促进跨分片通信?

      最容易满足的一个场景是,有许多的应用程序没有太多独立用户,而且这些应用程序只是偶尔或者很少与彼此交互;在这种情况下,应用程序可以在单独的分片上生存,并通过使用收据来与其他分片进行通信。

      这通常涉及将每笔交易分解为”借记“和”贷记“。例如,假设我们有一个交易,其中账户A在分片M上,期望发送100个代币到分片N上的账户B。这些步骤如下所示:

        在分片M上发送一个交易(i)扣除账户A的100个代币(ii) 创建一个收据。收据对象并不直接保存在状态中,但收据的生成能通过默克尔证明来验证。

        等待第一个交易被包含进来(有时候需要等待终止化,这取决于系统)

        在分片N上发送一个交易,包含来自(1)收据的默克尔证明。这个交易也检查分片N上的状态以确保收据是”未花费“;如果是的话,那么它将账户B增加100个代币,并且保存在状态中代表收据已花费。

      可选地,(3)中的交易也保存收据,然后可以在分片M中用来执行进一步的操作,这取决与原操作是否成功。

      在更复杂的分片形式中,交易在某些场景下可能具有分散在不同分片上的效果,并且可以从多个分片状态中同时请求数据。

      不同类型的应用程序如何与分片区块链融合?

      有些应用程序完全不需要跨分片交互;多资产区块链和不需要互操作性的完全异构应用程序的区块链是最简单的案例。如果应用程序不需要彼此交互,如果可以异步交互,面临的挑战会更容易应对。也就是说,如果交互可以以分片A上的应用程序的形式完成,则生成收据,在分片B上的交易“消费”该收据并基于它执行一些操作,并且可能向分片A发送包含某些响应的“回调”。总的来说这个模式是很简单的,并且不难将其整合入高级程序语言中。

      需要注意的是,与可用于分片内通信的机制相比,用于异步跨分片通信的协议内置机制可能会有所不同并且功能较弱。在不可扩展的区块链中的当前可用的一些功能在可扩展区块链中只能用于分区内通信7。

      什么是火车旅馆问题

      下面的例子是Andrew Miller提供的。 假设用户想要购买一张火车票并预订一家旅馆,并且想要确保这个操作是原子的 - 无论是保留成功还是两者都不成立。 如果火车票和酒店预订应用程序在同一个分片上,这很容易:创建一个交易,试图进行两个预订,除非两个预订都成功,否则引发异常,并且回滚所有。 但是,如果两者在不同的分片上,这并不是那么容易; 即使没有加密经济/去中心化的问题,这实质上也是数据库原子事务的问题。

      只有异步消息,最简单的解决方法是先预订火车,然后再预订旅馆,然后一旦两个预订都成功就都确认;预订机制将阻止其他人预留(或者至少会确保有足够的空间开放让所有的预订被确认)一段时间。然而,这意味着该机制依赖于额外安全假设:来自于跨分片的消息可以在固定的周期内被包含在另外的分片中。

      使用跨分片同步交易,问题更容易,但创建可以跨分片原子同步交易的分片解决方案的挑战本身绝对是重要的。

      如果单个应用程序的使用量超过 O(c),则该应用程序需要存在多个区块链中。这样做的可行性取决于应用程序自身的具体情况。一些应用程序(如货币)很容易并行化,而另外一些应用程序(例如某些类型的市场设计)则不能并行化智能串行处理。

上一篇区块链技术之间的框架与层级

下一篇区块链架构1.0、2.0与3.0梳理

区块链知识本月排行

区块链知识精选