此前我发过一篇文章比较 Arbitrum Rollup 和其他 rollup 解决方案。但是没有细说 Arbitrum Rollup 的工作原理,所以本文将详细介绍 Arbitrum。
Arbitrum Rollup 是一个由以太坊链上合约管理的链下协议。一个 dApp 开发者用 Solidity 写了一组合约,将这些合约编写进 Arbitrum 虚拟机 (Virtual Machine, VM) 中,然后就可以在 Arbitrum Rollup 中运行合约了。这样运行速度能够快些。
Rollup的基础原理
让我们从基础说起。虚拟机的状态以默克尔树的形式组织,因此就可以计算出该虚拟机状态的加密哈希。在协议的任意时间点,都有一些虚拟机状态被完全确认和敲定。这些虚拟机状态的哈希是储存在链上的。
协议参与者可以提出一个“争议断言” (Disputable Assertion, DA)。该断言声称,虚拟机从某些状态哈希开始,基于一些技术前提可以执行特定数量的计算步骤,从而生成新的状态哈希。并在计算期间完成特定的支付以及生成特定的日志事件。该“争议断言”可能有效,可能无效。提出“争议断言”的一方需要基于断言的有效性质押一笔保证金。(更多关于质押及其运作原理将在下文介绍)
图:一个争议断言在协议中产生了一个决策点
如上图左侧所示,一个争议断言产生了一个协议最终必须解决的逻辑决策点。如果该断言有效,系统会进入一个新状态 (右上角),根据特定的断言产生新的状态哈希和其他诸如支付和日志的附带效果。否则就会进入另一个分支 (右下角),该断言就会被拒绝,状态保持不变。
旧版 Arbitrum 协议
最开始的 Arbitrum 协议每次处理一个“争议断言”。当某方提出一个断言时,挑战期便开始,在此期间任何人都可以对该断言发起挑战。如果没人发起挑战,该断言就会被确认;否则争议协议就会运行以取消争议断言 (以防提议者和挑战者串通起来炮制争议结果)。
这个设计很简单,但有两个缺点。首先,由于每次仅处理一个争议断言,导致虚拟机的处理速率有限。因此,每个挑战期期间,处理进程基本上停滞下来。第二,作恶者可以通过对某虚拟机所有的争议断言发起挑战来冻结该虚拟机。攻击者会为此付出一定的代价 (质押金),但是如果他们不介意这些损失,至少在一些场景下他们可以造成系统的处理进程延误很长一段时间。
改进版本
新版 Arbitrum Rollup 协议解决了上面两个问题。将多个争议断言按流水线式排布,这样设计下,虚拟机处理速度就可以和验证节点模拟虚拟机运算的速度一样快了。第二,正如下图所示,作恶者无法延缓进程,他们只能暂时延误对结果的链上确认,而对于诚实节点来说,这些结果已经是“无需信任地被敲定了”。
其工作原理是什么?我需要更进一步地介绍这个新的协议....
每个状态最多有一个争议断言跟在其后。如果某个状态后没有争议断言,那么任何人都可以在其后创建一个争议断言,作为一个新的分支点。从而产生一颗多种可能的未来之树。
图:一颗多种可能的未来之树
质押
Arbitrum 的另一个重要部分就是质押 (staking)。任何人都可以往那颗树中的方框里质押一定金额。通过质押,用户则押注了某个方框最终将被协议确认。换句话说,该用户认为其押注的方框是当前状态的正确分支。如果用户押错注了,其押金便会受到罚没。
质押行为不可以撤销。用户可以将押金向右移动 (在每个分支点选择向右上/右下移动),但是不可以向左移动,因为这相当于用户撤销其此前的质押操作。
提出争议断言的一方需要押注其提出的争议断言有效。通常情况下他们都能够满足这一要求 —— 将其现存的押金往右移动并押注在要求的方框上。(极少数情况下他们无法这样操作时,他们可以将额外的资金押注在要求的方框上。但是请注意,这样做很可能会在两个相冲突的分支上质押,这会导致损失至少一个分支上的质押金。因此做出自相矛盾的操作是不明智的。)
关于质押还有一个细节:如果用户押注的方框被确认且被记录在协议上了,用户可以选择取回押金。这意味着,用户如果押对注了,便可以选择不再移动押金,留在原处直到被系统追上,然后就可以取回其押金了。
图:更加典型的状态树 — 由一系列正确的断言组成
在这一点上大家可能会担心那颗充满各种可能的树会变得非常庞大、枝繁叶茂。这在实践中不太可能发生,因为这需要多方对不一致的结果押注。其中仅有一方是正确的,其他人则会损失押金。那么结果最有可能是这样的:这是一颗由“有效的争议断言”所组成的链,一个接一个,所有质押者都具有同样结果的分支上。
质押期限
我们需要系统尽可能快地对每个争议断言做出决定。所以当新的争议断言被添加上链且出现一个分支点时,就会产生一个与该争议断言相关联的期限。这个期限足够长以至于任何人都可以在期限内判断该争议断言是否有效,然后需要在期限之前选择是否押注。(期限过后,质押交易仍能在链上进行,但他们不能参与决定某争议断言是否正确。) 一旦期限满了,所有参与决定争议断言的押注都将可知。
争议
如果 Alice 和 Bob 在不同的方框上进行押注,会有两种情况发生:要么其中一位向右移动到另一个人的押注上 (即他们两个的押注结果相符合);要么找不到这样的路径。如果 Alice 和 Bob 之间没有一条可以连接他们的向右的路径,则他们必定相矛盾。那么在他们之间一定可以找到一个唯一的分叉点—— 这一点将他们两个分叉,各押注了相矛盾的分支方框。
图:Alice 和 Bob 之间存在争议
当两方之间出现争议时,系统会在他们之间启动一个交互式的争议解决协议。可惜在本文中我没有足够的篇幅来描述该争议解决协议 —— 这是一个二分法交互协议 (bisection-type interactive protocol),类似于我之前在其他 Arbitrum 文档中的描述。
该协议带来的结果是,其中一方会被证实错误的。其押金会被罚没,且押注会从方框中移除。而这些押注的部分会给争议的另一方,剩余的会被销毁。
多个争议可以同时存在,但每个质押者每次最多只能选择一个争议。因为错误的押注会被删除,每一次争议的出现都会减少系统中的分歧数量。损失押金的质押者可以选择再次押注,但是新的押注不能再影响期限已过的争议断言。如此带来的影响是,一个争议断言的质押期限过了之后,关于如何处理该争议断言的争议都会被消除。
结果确认
当某个争议断言的质押期限到期之后,并且所有在期限内存入的押注在该断言的同一个分支上,系统就可以确认该争议断言的结果。它会被确认或拒绝,当前状态会向右移动到正确的方框上。如果该断言被正式有效,其附带效果 (如支付) 也会被记录上链。虚拟机状态就是这样向前移动的。
一般情况下,为了不损失自己的押金,参与者都将诚实押注。只有有效的争议断言会被提出,没人将在争议断言的无效分支上押注,从而形成一条单一的链。在这种情况下,每个争议断言都能在质押期限过后立即被确认。
为何说其无需信任
Arbitrum Rollup 的一个重要性质就是无需信任 —— 单个诚实参与者就可以确保虚拟机状态正确推进。为什么?假设 Alice 总是对每个争议断言的正确分支进行押注,并且当树不再产生分支了,她就提议一个争议断言。
因为 Alice 在正确的分支上押注,所以每一次争议她都是胜利方。如果任何人与 Alice 相矛盾,他们将 (a) 在一个不相关的争议中损失他们的质押金,(b) 最终进入 Alice 所在的争议中,其押金将输给 Alice。不管哪个方式,任何反对 Alice 的一方最终都会被罚没。只有与 Alice 相符合的押注才会胜利到最后,所以 Alice 所在的分支会成为唯一一个及时收到押注的路径 —— 该路径会被确认。
图:只要 Alice 是诚实的,无论其他人怎么做,绿色方框最终都会被确认
由于在这种方式上系统是无需信任的,如果 Alice 在一个方框上押注并且她知道该方框的路径是正确的,那么她可以确认其所在的方框上将最终被确认。对于 Alice 来说,该路径就像被敲定了一样。
即使用户没有在某条路径上押注,但是如果用户看到其他一些用户押注该路径,并且相信该路径上至少一个人是诚实的,那么其就可以确认该路径将最终被确认 —— 对该用户来说,这条路径就像被敲定了一样。
最终确定性无需信任的好处
结果最终确定性的无需信任为什么如此重要?那篇对于其他 rollup 协议的讨论中举出了一个经典的例子。假设一个虚拟机打算向 Alice 支付一笔交易。该支付事件位于正确的路径上,但这笔交易还需等待一段时间,直到这笔交付交易所在的方框在链上被确认。
最终确定性无需信任让 Alice 能够即时收到汇款。如果 Bob 手上有闲钱,他可以立即给 Alice 钱,作为交换,Alice 把未来即将被确认的支付款项转给 Bob (额外给 Bob 一点手续费)。Bob 只有确定该支付交易一定会发生才会愿意这么做。Bob 可以通过押注诚实结果来确保这一点 —— 那么他就可以对这笔支付一定会发生抱有无需信任的信心。不仅 Bob 可以这样做,任何人都能够以这种方式把钱借给 Alice 或其他像她那样的人。这些人还可以通过提供更少的手续费以竞争。
关键是,这种市场机制的可行性取决于无需信任的最终确定性。如果“每个人”都已经知道该事件将最终被确认,那么链上确认的延迟就不会带来不便。
不仅支付这个案例,对于虚拟机所做的其他事情也是如此。如果虚拟机打算生成一个日志项来广播发生了的事件,无需信任的最终确定性意味着任何人都可以确信该日志将被链上承认。
延迟攻击
因为系统是无需信任的,作恶者无法强行生成一个错误的结果。他们可以做的只有延缓系统处理过程。但这样会牺牲他们的押金,如果质押数额很大的话成本将会非常高。
想象一下如果有人想要发起延迟攻击,且愿意牺牲他们的押金。他们可以带来最大的破坏是什么?
首先,作恶者不能阻止诚实验证者继续在树上构建他们的诚实分支。他们也不能妨碍诚实验证者相信诚实分支的最终确认具有无需信任性。
攻击者可以做的只有在错误分支上质押,以延缓对诚实路径的链上确认。他们的每笔押注都会给诚实质押者创造多一个争议,在这个过程中诚实验证者都会分走一大半攻击者的押金。当攻击者的押金都被分走时,链上工作便继续进行。
那如果攻击者在多个错误结果上质押呢?那么,那些押金就会在一次次的争议里被分走。如果有多人在诚实结果上质押,他们可以进入有攻击者的争议里,与攻击者并行工作,然后把质押者的押金分走。而当人们留意到这一点,大家都知道在发生什么事了,就会有很多人加入到在正确结果上做质押,这样他们就能分走制造争议的攻击者的押金。如果有 K 个人在诚实结果上做质押,攻击者就要花费 K 份押金来一次争议期的延迟。如果攻击者花费更多的押金,这可能会吸引更多的诚实质押者。对攻击者来说情况只会越来越坏。
优化
有很多优化方案可以实施,以减少运行协议必需的链上记账数据量、减少链上 gas 消耗、以及让延迟攻击所带来的分食狂欢更容易发生。笔者在这里就不对优化详细展开了,这篇文章已经够长了。
来源 | Offchain Labs
作者 | Ed Felten
原文链接:
https://medium.com/offchainlabs/how-arbitrum-rollup-works-39788e1ed73f