V神:Rollups 不完全指南

来自 Vitalik 博客的文章:简析二层扩容方案状态通道 、 Plasma 、 Rollups 各自的技术优缺点,着重分析了 Optimistic rollup 和 ZK rollup 的可行性、安全性及应用前景?

原文链接: https://vitalik.ca/general/2021/01/05/rollup.html

Rollups解决方案在以太坊社区中正风靡一时,并有望在将来成为以太坊的关键扩容解决方案。但是这项技术究竟是怎样的呢?它能给我们带来什么?我们将如何使用这项技术呢?本文将尽量回答其中一些关键问题。

背景:什么是一层、二层扩容?

区块链扩容方式有两种。第一种,提高区块链本身的交易容量。这种技术的主要挑战就是:当区块容量越来越大时,区块链将越来越难验证,且中心化程度越来越高。为了避免此类风险,开发者可以提高客户端软件的效率。或者选择另一种更为可持续的方式:利用诸如分片技术,使得区块链上的构建区块和验证工作可以分散至许多节点 (Eth2升级正在尝试将此技术引入以太坊)。

第二种:改变使用区块链的方式。即用户不是将所有交易都直接在区块链上进行,而是通过二层协议在链下执行大部分交易。例如链上有一个智能合约,该合约只有两个任务:处理存款和提款、以及验证所有链下交易的有效性。对链下交易进行验证的方法有多种,但他们都具有同一个特性:在链上验证证明比在链下进行原始计算的成本要低得多。

状态通道 vs Plasma vs Rollups

二层扩容方案的三种主要类型是:状态通道Plasma 和 rollups。他们是三种不同的范式,具有不同的优劣势。我们可以把所有二层扩容解决方案大致地归为这三类 (尽管有的方案因分类模糊而存在命名争议,如 validium)

状态通道原理

假设 Alice 正给 Bob 提供互联网连接,作为交换,Bob 每兆字节向她支付 0.001 美元。他们不需要每一次支付都执行交易,而是使用下面的二层解决方案。

首先,Bob 向一个智能合约中存入 1 美元 (或等值的 ETH 或稳定币)。Bob 在一张写着 “0.001美元” 的票上进行签名 (一条链下信息),然后发给 Alice,这样就完成了对 Alice 的第一笔支付。而第二次支付时,Bob 在另一张写着 “0.002美元” 的票上进行签名,然后发给 Alice。以此类推,可以根据需要进行多次付款。当他们完成交易了,Alice 可以将面额最高的签名票单并加上自己的签名提交到链上。链上的智能合约将验证 Alice 和 Bob 的签名,然后向 Alice 支付 票据上的金额,并将剩余的钱退还给 Bob。如果 Alice 不愿意关闭他们之间的状态通道 (出于恶意行为或由于技术故障),则 Bob 可以启动提款期 (withdrawal period),如果 Alice 在这段期间内 (比如7天) 还是没有向 Bob 提供票据,那么 Bob 就可以在到期后拿回他的所有钱。

状态通道功能强大:可以对其进行调整,以进行双向支付、处理智能合约 (如,Alice 和 Bob 在通道中签订金融合约)、以及对通道进行组合 (比如,当 Alice 和 Bob、Bob 和 Charlie 之间有一条开放通道时,Alice 和 Charlie 也可以进行去信任交易)。

但状态通道的作用是有限的:无法在链外将资金发送给没有参与进来的用户;通道不能代表那些逻辑上没有明确所有者的对象 (如 Uniswap);并且如果要进行更为复杂的交易,需要在通道内锁定大量资金。

更多资料请参考:https://www.jeffcoleman.ca/state-channelsstatechannels.org

Plasma 原理

用户向某个 Plasma 链的智能合约中发送一笔资产以完成存款。Plasma 链给该资产分配一个唯一的 ID (如 537)。每条 Plasma 链都有一名运营者 “operator” (他可以是一个中心化的角色、一个多签名者、或诸如 PoS/DPoS 此类更为复杂的东西)。每隔一段时间 (可以是15秒至1小时),运营者便会生成一个“打包”交易 (由在链下收集到的所有 Plasma 交易组成)。

Plasma 会生成一个默克尔树,树中每个索引 X 处,如有存在交易的话,会显示某笔转移交易资产 ID X,如果没有交易,叶子值为零。随后他们将该默克尔树的默克尔根发送到链上,同时还会将每个索引 X 的默克尔分支发送给其资产的当前所有者。如果用户想要进行提款,那么就要把最近向其发送资产的交易的默克尔分支提交到链上。然后智能合约就将启动挑战期,在此期间,任何人都可以尝试使用其他默克尔分支来证明该提款无效。需要至少证明其中一项:(i) 发送方在发送资产时并不是该资产的所有者;(ii) 发送方在后来将资产发给了其他人。如果在某个时间段内 (如七天) 没有人证明该提款是欺诈性的,用户便可以取出他的资产。

Plasma 比状态通道拥有更加强大的性能:使用 Plasma,用户可以将资产发送给从未加入其系统的参与者;对资本的要求也低许多。但 Plasma 也是有缺点的:相比之下,在“正常操作”期间,通道不需要在链上进行任何数据传输,而 Plasma 要求每条链定期发布一个哈希。此外,在 Plasma 上转账不是即时确认的:用户需要等待周期结束并且等到区块被发布之后才能确认。

再者,Plasma 和状态通道都有一个关键弱点:它们背后的安全博弈是基于这样一个思想,即由两个系统控制的每个对象都有逻辑上的“所有者”。 如果该所有者不关心其资产,则可能涉及资产“无效”的结果。这对许多应用程序来说是可以接受的,但是对于许多其他应用来说 (如 Uniswap) 来说是破坏交易的因素。甚至在一些系统中对象的状态不经其所有者的同意就可以被改变 (如基于账户的系统,你可以不经某人的同意就可以提升其余额),这些系统也不适用 Plasma。这意味着,当部署任何实际 Plasma 或状态通道时,都需要大量的“针对某个特定应用程序的推理”,并且不可能创建一个完全模拟以太坊环境 (或“EVM”) 的 Plasma 或者状态通道系统。为了解决此问题,各种 rollup 方案出现了。

更多资料请参考:最初的 Plasma 论文,以及 Plasma Cash

Rollups

Plasma 和状态通道是“完全”的二层方案,因为其将数据和计算都移至链下。然而,围绕“数据可用性”的基本博弈论问题意味着这些方案不一定对于所有应用来说都是安全的。Plasma 和通道方案的解决方式是依靠所有者完全知晓状态,但这使得此类方案无法完全通用化。Rollups,则是一种“混合型”二层方案。Rollups 将计算 (以及状态存储) 移至链下,但将每笔交易的一些数据放在链上。为了提高效率,这类方案借助了许多复杂的压缩技巧以尽可能使用计算替代数据。结果是系统的扩容性仍然受到底层区块链的数据带宽限制,但比较来看仍十分有利:以太坊基础层 ERC20 代币的转移成本约为 45000 gas,而 rollup 中的 ERC20 代币仅转移占用 16 字节的链上空间,成本不到 300 gas。

数据在链上这一点很关键 (请注意:将数据“放在 IPFS 上”是行不通的,因为 IPFS 不能为任何给定的数据是否可用提供共识;数据必须被记录在链上)。将数据放在链上并对此达成共识,使得任何人都可以根据需要在本地处理 rollup 中的所有操作(如果他们想的话),从而允许其对欺诈进行监测、发起提款或亲自开始批量生成交易。缺乏数据可用性意味着一名恶意的或是离线的运营者能够产生的影响甚至会更小 (例如他们无法造成一周的延迟),从而为有权发布批量交易的人打开更大的设计空间,并使 rollup 更容易有理可循。更重要的是,缺乏数据可用性意味着不再需要映射资产到所有者,从而我们能得出以太坊社区相较之前的二层扩容方案对 rollups 更加期待的关键原因之一:rollups 是完全通用的,我们甚至还可以在 rollup 内部运行 EVM,使得既有的以太坊应用几乎不需要编写新代码就能迁移到 rollups 上。

其他资源参考:EthHub on optimistic rollupsZK rollups

Rollup 到底是怎么工作的?

Rollup在链上有一份智能合约用来维护状态根,即 rollup 状态的默克尔根 (也就是 rollup 内部的账户余额、合约代码等等)。

img

任何人都可以发布一个汇总交易 (batch),这是一个高度压缩的交易集合,其中包含之前的状态根和新状态根 (处理交易之后的新默克尔根)。该合约会检查汇总交易中的旧状态根是否匹配其当前的状态根,如果匹配的话,合约会对状态根进行更新。

img

为了支持存款和提款,我们增加了输入和输出在 rollup 状态“外部”的交易的功能。如果一个 batch 中包含来自外部的输入,则提交到该 batch 的交易也需要将资产转移到 rollup 合约。如果一个 batch 中包含来自外部的输出,则智能合约在处理该 batch 时会发起提款。

这就是 rollup 的工作原理了。但还有一个重要细节:如何得知 batches 里的后状态根 (post-state root) 是正确的呢?如果某人能够提交一个具备任意后状态根的 batch,而无需承担任何后果,他们完全可以将 rollup 中的所有代币都转移给自己。这个问题很关键,因为由此诞生了两种不同的解决方案,这两种解决方案又衍生出了两种不同的 rollups。

Optimistic rollups 与 ZK rollups

这两种 rollups 为:

  1. Optimistic rollups,其解决方案为欺诈证明 (fraud proofs):这类 rollup 会追踪所有历史状态根以及每个 batch 的哈希值。如果任何人发现某个 batch 的后状态根不正确,他可以向区块链发布一个证明,证明该 batch 计算错误。合约会对证明进行验证,并且对该 batch 及其之后的 batches 进行回滚。
  2. ZK rollups,其解决方案为有效性证明 (validity proofs):每个 batch 都包含一个称作 ZK-SNARK 的密码学证明 (例如使用 PLONK 协议),以证明后状态根是正确执行 batch 的结果。无论计算量有多大,该证明都能在链上得到极速验证。

这两种 rollup 之间存在复杂的权衡:

特性 Optimistic rollups ZK rollups
每 batch 的固定 gas 消耗 约 40,000 (轻量交易,主要只是改变状态根的值) 约 500,000 (验证 ZK-SNARK 所需计算量较大)
提款期 约一周 (提款存在延迟,需要留出时间提交欺诈证明,如果发生欺诈需要取消提款) 极快 (只需要等到下一个 batch)
技术复杂度 高 (ZK-SNARK 是一种非常新的技术,并且数理复杂)
通用性 易达成 (通用的 EVM rollups 即将登陆主网) 较难达成 (使用 ZK-SNARK 证明的通用 EVM 执行相较简单计算证明难度更大)
每笔链上交易的 gas 消耗 较高 较低 (如果一笔交易中的数据只用作验证,不引发状态改变,那么能够省去该数据,在 optimistic rollup 中则需要发布,因为有可能在欺诈证明中需要对其进行查验)
链下计算成本 较低 (尽管需要大量全节点重新进行计算) 较高 (专门针对通用计算的 ZK-SNARK 证明可能会很昂贵,比直接运行计算可能要贵数千倍)

总的来说,我个人的观点是,在短期内,optimistic rollup 的显著优势在于其通用的 EVM 计算,而 ZK rollup 更可能被用于支付、交易和其他特定用例。但中长期来看,随着 ZK-SNARK 技术的成熟,ZK rollup 会在所有用例中发挥出优势。

剖析欺诈证明

Optimistic rollup 的安全性保障主要来自于:如果有人在 rollup 中发布了一个无效的 batch,其他任何跟进该链的用户监测到欺诈行为都可以发布欺诈证明,向合约证明该 batch 的无效性,并进行回滚。

img

在上图中,声称某 batch 无效的欺诈证明会包含绿色的数据:如果要证明特定账户被该 batch 读取和/或被修改,则需要提供 batch 本身 (可以对照存储在链上的哈希值进行检查) 和 Merkle 树的各个部分。而图中黄色的节点,能够被绿色的节点重构,因此不需要提供。该数据已经足够执行 batch 并计算后状态根 (这与 无状态客户端 验证单个区块的方式几乎相同)。如果经计算的后状态根以及获得的 batch 中的后状态根不一致,那么该 batch 就是无效的。

可以保证如果某个 batch 不正确,但之前所有的 batches 都是正确的,那么就能够创建一个欺诈证明以表示该 batch 是不正确的。请注意对之前 batch 的声明:如果有超过一个无效的 batch 被发布到 rollup 中,那么最好尝试证明最早的无效 batch。也可以说,如果某个 batch 是正确的,那么永远都无法创建一个欺诈证明表示其无效。

数据压缩原理

一笔简单的以太坊交易 (发送 ETH) 大小约为 110 字节。而在 rollup 上进行 ETH 转账,大小仅为约 12 字节:

参数 以太坊 Rollup
Nonce ~3 0
Gasprice ~8 0-0.5
Gas 3 0-0.5
To 21 4
Value ~9 ~3
Signature ~68 (2 + 33 + 33) ~0.5
From 0 (从签名中恢复) 4
Total ~112 ~12

其中一部分只是简单的高级编码:以太坊的 RLP 编码方式在每个值上会浪费 1 字节。但是其中还包括一些机智的压缩技巧:

  • Nonce:这个参数的主要目的是预防重放攻击。如果帐户的当前Nonce为 5,则该帐户的下一个交易记录包含nonce 必须为 5,但是交易一经处理,该帐户中的nonce将增加为 6,因此无法再次处理该交易。在 rollup 中,我们可以完全省去nonce,因为我们可以直接从前状态中恢复nonce;如果有人尝试使用先前的nonce重放交易,签名将无法验证,因为会依据包含较高nonce的数据来对签名进行检查。
  • Gasprice:我们可以允许用户按固定 gas 价格范围进行支付,例如 2 的 16 次幂。或者我们可以在每个 batch 中收取固定的 gas 费用,甚至可以将支付 gas 费用完全移出 rollup 协议,让交易者使用状态通道向 batch 创建者支付相应费用。
  • Gas:同样地,我们可以将总 gas 设定为 2 的多次幂。或者在batch 级别设置 gas limit。
  • To:可以用 index 来替换 20 字节的地址 (例如,如果某地址是被添加到默克尔树中的第4527个地址,我们只需使用 index 4527 来表示即可。然后向状态添加一个“子树” (subtree) 来存储index和地址本身的映射关系)。
  • Value:我们可以用科学记数法储存值。在大多数情况下,交易只需要 1-3 个有效位。
  • Signature:我们可以使用 BLS 聚合签名将大量签名聚合成一个约为 32-96 字节 (取决于协议) 的签名。该聚合签名可以依据交易集和 batch 的发送者集一次性进行检检查。表中的 “~0.5” 表示一个聚合签名中可以包含的签名数量是有限制的,因为需要能够在一个欺诈证明中对聚合签名进行验证。

ZK rollups 特有的一个重要压缩技巧是:如果交易的一部分信息仅用于验证,并且不用于计算状态更新,那么该部分可以移至链下。Optimistic rollup 无法做到这一点,因为该数据仍然需要存在链上,以备需要在欺诈证明中进行检查的不时之需。而在 ZK rollup 中,SNARK 已经证明了 batch 的正确性,也就是说验证所需的数据已经齐全。具备隐私保护功能的 rollups 是一个重要例子:在 optimistic rollup 中,每笔交易中用于隐私保护的 ZK-SNARK 证明需要在链上,需要占据约 500 字节。而在 ZK rollup 中,包含整个 batch 的 ZK-SNARK 已经在“内部”证明了 ZK-SNARK 的有效性。

这些压缩技巧是 rollups 扩容性的关键,否则 rollups 扩容性相较底层链只能提高约 10 倍 (虽然对于某些特定的计算密集型应用来说,简单的 rollups 方案已经足够),而对数据进行压缩后,几乎对所有应用来说,扩容性都可以实现 100 倍以上的提升。

谁来提交batch?

对于 optimistic rollups 和 ZK rollups 中交易的打包权有许多说法。一般来说,任何想要参与打包交易并提交交易的用户,需要先锁定大量存款。如果用户提交了包含欺诈/无效交易的 batch (例如包含无效状态根),那么该用户的存款的一部分会被销毁,另一部分则作为欺诈证明者的奖励。不过,也存在其他可能方式:

  • 完全“无政府状态”:任何人都可以在任何时候批量打包交易并提交。这是最简单的方式,当然也存在缺陷。尤其是多个参与者同时尝试提交但最终只有一个 batch 能被成功打包。这会导致大量生成证明的工作和/或发布 batches 的 gas 被白白浪费。
  • 中心化处理:存在一个角色(排序者 (sequencer) )来提交 batches (但取款存在例外:通常来说一个用户可以先提交取款请求,如果排序者没有在下个 batch 中处理该提款,那么该用户能够自己提交一个 batch)。中心化处理是最“高效”的方式,但是依赖于一个中心化的角色。
  • 排序者拍卖:通过定期(如:每天)举行拍卖的形式来确定谁有权成为下一个周期的排序者。其优点在于它可以筹集资金,并通过例如由 rollup 控制的DAO 来进行分配资金(参见 MEV 拍卖)。
  • PoS 集随机选择:任何人都可以将 ETH (或是 rollup 协议的代币) 存入 rollup 合约,然后在存款人中随机选择每个 batch 的排序者,被选中的可能性与锁定资产成比例。这个方式的主要缺点在于会有大量资本被锁定,而这是不必要的。
  • DPoS 投票:通过拍卖确定一个排序者,如果该行为人表现不佳,那么代币持有者可以通过投票将其驱逐,并发起新的拍卖。

分离批量打包和状态根处理

目前正在开发的一些 rollup 项目采用了“分离-打包”的方式,也就是将提交二层交易的 batch 和提交状态根的过程是分离的。这种做法的优势在于:

  1. 使得多个排序者能够同时发布 batches,以提高扛审查性,不同担心 batches 被首先打包而导致其他 batches 无效的问题。
  2. 如果某个状态根是无效的,我们不需要回滚整个 batch,可以只回滚状态根,并等待他人提供该 batch 的新状态根。这保障了交易发送方的交易不会被回滚。

总之,在效率、简洁性和抗审查性等方面的权衡十分复杂,许多方案也在进行探索。目前要判断哪些概念是最佳组合还为时尚早,时间会证明一切。

rollup 扩容效果如何?

在现有的以太坊链上,gas上限是1250万,一笔交易里,每个字节的数据消耗16 gas。这意味着如果一个区块只包含一个batch (假设使用 zk rollup,在证明验证上花费50万gas),那一个batch可以包含 (1200 万 / 16) =750,000 字节的数据。如上文所示,对于一个以太坊转账的rollup,每一次用户操作只需 12 个字节,也就是说该批交易可以包含高达6.25万笔交易。现在平均出块时间为13秒,即相当于大约每秒4807笔交易 (相比之下,现在直接在以太坊上转账是每秒 1250万/21000/13~=45笔交易 )

其他用例的扩容表现表格如下:

场景 rollup 所占的字节 一层的gas消耗 扩容的最高水平
ETH 转账 12 21,000 105x
ERC20转账 16 (需要额外 4 个字节来指定代币) ~50,000 187x
Uniswap 上的交易 ~14 ( 发送者 4 个字节+接收者 4 个字节+交易值 3 个字节+最高价格 1 个字节+其他杂项 1 字节) ~100,000 428x
保护隐私的取款 (Optimistic rollup) 296 (根索引 4 个字节+nullifier 32 个 字节+接收者 4 个字节+ZK-SNARK 证明 256 个字节) ~380,000 77x
保护隐私的取款 (ZK rollup) 40 ( 根索引 4 个字节+nullifier 32 个字节+接收者 4 个字节) ~380,000 570x

扩容的效果上限是这样计算的:(一层的 gas消耗)/(rollup所占的字节 *16)* 1200万 / 1250千万

现在,值得注意的是这些数据都过于乐观了,原因有几个。最重要的是,一个区块几乎不可能只包含一批交易,因为最起码会有多个rollup。第二,存款和取款行为会一直存在。第三,在短期,使用率会比较低,所以固定消耗会占主导。但即使这些因素都考虑到了,超过100倍的扩容水平也有望成为常态。

如果我们想每秒交易量达到 1000-4000 呢 (取决于特定的用例)?这就是eth2 数据分片发挥作用的时候了。分片协议为每 12 秒提供 16MB 的空间来容纳任何数据,且系统确保数据可用性的共识。数据空间可以被rollup使用。这大约每秒 1398kb 的空间比现在以太坊链上每秒大约 60kb 提高了23倍,且在更长期来看,数据容量有望继续增加。因此,使用 eth2 分片数据的rollup可以以每秒约 10 万笔交易的吞吐量批量处理,在未来可能更多。

rollup上还有哪些挑战?

尽管 rollup 的基本概念现在你已经有所了解,我们十分确信它们是可行且安全的,现在多种 rollup 已经部署到主网上,但 rollup 设计还有很多领域未被充分探索,以及在如何把以太坊生态上的大部分活动引入到 rollup 上,以利用它们的可扩容性这件事上,还存在不少困难。一些关键的困难包括:

  • 用户和生态的入驻——使用 rollup 的应用不多,用户也不熟悉 rollup,只有少数钱包开始集成 rollup。商家与慈善机构也还不支持这种支付方式。
  • 跨 rollup 交易—— 高效地从一个 rollup 移动资产与数据 (例如:预言机输出) 到另一个rollup方案,而无须产生经由基础层(layer1)的费用。
  • 审计激励——如何最大程度提高至少有一个诚实节点完整验证一个optimistic rollup的机率,使得出现问题时他们会广播欺诈证明?对于小规模 rollup (高至每秒几百笔交易),这个问题不大,因为对矿工来说只是举手之劳,但对于大规模的 rollup 来说,还需要更充分的理由以说服矿工去做验证。
  • 探索plasma和 rollup 之间的设计空间——是否有技术可以放一些 状态更新相关数据到链上而不是全部的数据,且这些数据会产生有用的东西?
  • 最大程度提高提前确认的安全性——很多rollup都会为了更快的用户体验 (UX) 提供“提前确认 (pre-confirmation)”,这里排序者会马上承诺某笔交易会被打包到下一批交易里,而如果此承诺没有被兑现,该排序者将损失其保证金。但这个方案的经济安全性是有限的,因为排序者可以同时对非常多的人作出非常多的承诺。这个机制可以改善吗?
  • 提高离线排序者的反应速度——如果一个rollup的排序者突然离线了,在最短的时间内以最低的消耗从这种情况恢复过来是很重要的,方法要么是快速且低消耗地大规模切换到另一个rollup,要么是换一个排序者。
  • 有效ZK-VM——生成一个ZK-SNARK证明,证明通用的EVM代码 (或一些现有的智能合约可以编译的不同 VM) 已被正确执行和有一个给定结果的。

结论

Rollup是一个强大、新颖的二层扩容范式,并有望成为以太坊在中短期未来 (也可能是长期) 扩容的基石。以太坊社区已经表现出对 rollup 的强烈兴趣,因为不像之前在二层扩容的尝试,它们可以支持通用的EVM代码,使得现有的应用可以轻易迁移。Rollup 有一个重要的妥协:交易处理不是完全在链下进行,而是每笔交易留下一小部分数据在链上。

rollup 有很多种,在设计空间上有很多选择:可以是使用欺诈证明的Optimistic Rollup,也可以是使用有效性证明 (即 ZK-SNARKs) 的 ZK Rollup。排序者 (可以发布汇总交易到链上的用户)可以是中心化的角色、自由个体、或两者间的很多其他可能性。rollup还是早期的技术,其开发在不断快速地进行中,但它们是可行的,且其中有些 (比较有名的是路印ZKSync、和DeversiFi) 已经运行数月了。期待今年 rollup 会有更多令人振奋的成果。

点赞 4
收藏 1
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Vitalik Buterin
Vitalik Buterin
https://vitalik.ca/