Scroll:后 EIP4844 时代的数据可用性

以太坊社区引入了EIP4844,一种新的blob-carrying transactions交易格式,以提供数据可用性,降低rollup的运营成本,并降低用户的交易费用。Scroll协议的ZKRollup合约提供了将rollup链数据嵌入到L1上的calldata,Danksharding将采用纠删码对数据进行编码,以确保数据有效性,并引入blob-carrying transaction类型交易,每个blob-carrying transaction类型交易都可以携带一个blob列表。

摘要由 Mars AI 生成

本摘要由 Mars AI 模型生成,其生成内容的准确性、完整性还处于迭代更新阶段。

介绍

在过去的几年里,解决区块链的扩容难题一直是以太坊社区的重中之重,其目标是在不牺牲去中心化或安全性的情况下实现更高的可扩展性。经过大量的探索,以太坊社区一致决定采用以 rollup 为中心的方案来解决可扩展性问题,因此在以太坊路线图中始终优先考虑 rollup 的需求。

大多数 rollup 唯一的需求点是改进以太坊作为数据可用性层。EIP4844,也称为 Proto-Danksharding,是以太坊对这一需求的快速响应,当然改进的版本正在开发中。EIP4844 引入了一种新的交易格式,称为 blob-carrying transactions,它允许用户在交易中包含存储数据的二进制字段( 以下简称 blob ) ,保证这些数据在几周内是可用的。很快以太坊网络将经历一个名为坎昆升级( Cancun-Deneb)的硬分叉,其中就包括 EIP4844 等。

虽然区块链的叙事周期起起落落,围绕数据可用性的讨论一直在话题中心,然而,大家对数据可用性的理解仍然没有那么深入。所以在这篇文章中,我们将讨论什么是数据可用性层,以及为什么 rollup 需要使用数据可用性层。此外,我们还讨论了 EIP4844 以及它将如何提高以太坊作为数据可用性层的能力。最后,我们研究了如何在电路中打开 blob 承诺,并展示了一个简单的概念验证。

执行层的正确性

去中心化和无需许可的区块链为用户提供了许多保障,包括抗审查性、不可变性、活性,以及最重要的执行正确性。简单地说,状态转换是有效的,即智能合约的执行总是正确的。这一切都归功于去中心化网络中,每个节点都将检查区块的有效性。而 rollups 试图在更便宜的成本下提供相同的保障!

Rollup 的核心思路是将执行从 L1 转移到更便宜的环境中,同时采用一种机制简洁地(ZK) 或乐观地 (OP) 向 L1 rollup 合约证明这些执行是正确完成的,并且状态转换是有效的。需要注意的是,所谓的 rollup 合约通常接受的是对 rollup 链完整状态的承诺,例如其状态树的默克尔树的根。状态转换将不断更新此承诺。

如果你对这些机制不是很了解,以下是这两个分类的工作原理:

  • OP:乐观机制是建立在欺诈证明的基础上的。这里的想法是,如果 rollup 运营者向 L1 rollup 合约提交了无效的状态转换,人们就有激励向合约证明这种欺诈行为并获得奖励。因此,(尽管会有一些延迟)如果我们假设有人可以随时监控 rollup 链,就可以保证执行的正确性。只要没有无效的状态转换,L1 就不必执行任何 rollup 交易;这就是用户节省成本所在。相反,如果 rollup 运营者提交了无效的状态转换,就必须有人在指定的时间范围内构建并提交欺诈证明;否则,无效的状态转换将被最终确认且不可回滚。因此,rollup 链的完整状态必须对监测者可见(或可还原),否则他们甚至无法识别无效的状态转换。
  • ZK:从某种意义上说,简洁的有效性证明更有说服力,它们不依赖于受激励的参与者来监测链。但这些证明的内部工作更加复杂,并利用了加密魔法,不过它们在实现上很简单,可以在数学层面证明 rollup 链的新状态是正确执行的结果。这意味着即使 rollup 链的完整状态永远不可用,执行的正确性也始终可以得到保证。

本文将重点介绍具有简洁证明的 rollup。

不幸的是,仅仅确保执行的正确性是不够的。 为了提供抗审查性或活性等属性,rollup 仍然需要保证其完整状态是可还原的。如果 rollup 不能保证其完整状态是可还原的,则用户无法在 rollup 链中生成其账户余额的证明。这样的话,如果没有 rollup 运营者的合作,他们将无法将资金提取到 L1;显然,这是对 L1 保障安全性的严重偏离。

什么是数据可用性?

数据可用性 (DA) 指的是保证数据在网络内公开及时地发布。 换言之,我们这里指的数据可用,意味着假设发布者不会隐瞒数据。请注意,数据可用性与永久存储无关;数据会存在足够长的时间,在这段时间内任何利益相关的人都可以获取到它。数据可用性层 是用于发布数据的基础结构,可以保证数据可用。

有很多人会觉得 “数据可用性” 不是很好理解或者具有误导性。事后看来,像数据发布这样的替代术语可能是更好的选择。

详见:https://twitter.com/dankrad/status/1699598362851287459

数据可用性问题的起源

确保数据可用性的问题最初是在 Layer 1 扩容解决方案的背景下引入的。一个简单直接的扩容策略是增加每个区块的容量。许多扩容解决方案都或多或少通过不同方式来实现此目的。任何增加区块大小的扩容解决方案的主要问题是,网络中的每个人都必须下载并验证所有区块。因此,如果我们过多地增加区块大小,性能较差的节点就会落后并被淘汰。因此,我们逐渐将得到一个不那么去中心化的网络。如果我们能以某种方式在节点之间分配验证区块的任务,这样每个人都只需要下载和验证每个区块的一小部分,那么我们就可以拥有更大的区块。这一系列解决方案的一个挑战是确保整个区块确实被发布。

Rollup 的数据可用性

在上一章节中,我们讨论了为什么 rollup 链完整状态的可恢复性对于继承 L1 的安全性是必要的。我们可以通过提供如下的任一可用数据来确保完整状态是可恢复的:(1) 交易数据或 (2) 状态差异数据。

Rollup 将继承其数据可用性层的所有安全假设。这就是为什么许多 rollup 使用它们所基于的 L1 作为数据可用性层的原因:以避免额外的安全假设。使用以太坊作为数据可用性层的一种方法是简单地将数据嵌入到交易中,并确保它包含在 L1 区块中。只要以太坊区块可用,交易中嵌入的数据也将可用。以太坊区块一直是可用的,因为区块生产者被激励及时广播他们的区块以获得其他验证者的证明;否则,他们的区块将被忽略。

目前,在包含 EIP4844 之前,在交易中嵌入数据的最便宜的方案是将数据作为 calldata 字段。 calldata 是一个只读内存空间,用于存储你调用智能合约函数时一起发送的参数。此内存空间只能在函数执行期间访问,并且比存储更省 gas 费。虽然函数调用后无法在 EVM 环境中访问 calldata 的内容 ,但任何可以访问以太坊交易历史记录的人仍然可以恢复它。

但是,calldata 仍然很昂贵, 因为它除了数据可用性还提供了其他功能;一般来说,智能合约中可以读取 calldata 数据。而 EIP4844 引入了 blob-carrying transactions 交易后,旨在单独服务于数据可用性,将仅提供对 blob 数据的承诺,并且无法在智能合约中直接读取此数据。因此,预计在 blob 中发布数据的成本会低得多。然而,blob 数据的 gas 费用将采用类似 EIP1559 的机制单独定价。稍后会做更详细的介绍。

需要注意的是,降低数据可用性成本可以直接降低 rollup 的运营成本,这也意味着 rollup 用户的交易费用会变得更低。如今,常见的 rollup 运营商支付的 gas 费用中,大约有 80% 用于将 rollup 链数据嵌入到 L1 上的 calldata ,而只有 20% 用于证明验证。

Scroll 协议中的数据可用性

ZKRollup 合约:提交和最终确认

Scroll 的 rollup 过程有很多阶段,但出于本文的目的,我们将只关注提交和最终确认,这两个阶段分别处理数据可用性和证明验证。

  • 提交: 每隔几分钟,排序器就会提交一批新的交易,作为 calldata 调用 rollup 合约的 commitBatch 的方法。该函数计算并存储批次(Batch)的哈希值,当我们验证证明时,该 Keccak 哈希值将作为对 snark 验证器的承诺和输入。请注意,L2 交易数据嵌入在 L1 交易中。虽然数据不作为以太坊状态存储,但它有效地充当了 Scroll 链的数据可用性解决方案。任何人都可以收集这些交易(从归档节点)并查看其有效负载。
  • 最终确认: 提交批次后,证明者开始为批次的执行创建简洁的状态转换证明。 finalizeBatchWithProof 将证明作为输入,并验证如下所示的声明:

给定 prevStateRoot , 在commitment(txBatch)中执行提交的交易批次,将更新状态根为 postStateRoot 。

请注意,最终确认步骤仅将所有已执行交易的承诺作为输入,而不是所有交易。

PI电路:解压缩公共输入

如我们之前所说,证明声明仅包括对已执行交易的承诺。这是为了节省链上验证器合约的开销,使其不必处理大量的公共输入多项式,从而有效地压缩公共输入。然而,证明者必须在电路中打开这个承诺,即它必须知道批次中的实际交易。在 Scroll 的 zkEVM 上,PI 电路就是打开此承诺并解压缩 zkEVM 其余部分的公共输入的子电路。

PI 电路将对交易批次的承诺作为公共输入,证明者必须提供原始交易批次数据作为见证。PI 电路的约束条件将检查,所提供的见证确实与公共输入中的承诺所对应。跳过该一致性检查会使得恶意证明者提交一批次交易却执行另一批次交易,从而使 rollup 链的完整状态无法恢复。

扩展以太坊作为数据可用性层的可用性

到目前为止,我们讨论了数据可用性的重要性,以及以太坊今天如何被用作DA层。现在让我们转变为协议设计者的身份,快速浏览一下增加以太坊作为 DA 层容量的不同思路。

  • 降低 calldata gas 成本: 这是一个非常直观的想法,可以直接增加在以太坊发布更多数据以实现数据可用性的容量。事实上,这在过去的 EIP-2028 中已经完成。但是,这种方法存在局限性。更低的 gas 成本 calldata 意味着更大的区块,这意味着区块传播的延迟更高。将区块传播延迟推得太高会破坏 L1 的一致性机制。
  • 降低 calldata gas 成本并对区块中的calldata设置上限: EIP4488 正是这样提出的。虽然这听起来很棒,但以太坊的核心开发者认为这个提议太复杂了,实施风险太大,所以最终被放弃了。值得注意的是,该 EIP 附有 EIP4444 的姊妹提案。EIP4444 的目标是降低节点运营者的数据存储要求,并建议执行客户端在一年后修剪历史区块数据。EIP4444 旨在通过减轻 EIP4488 引入的额外存储负担来实现 EIP4488。
  • 数据不可用证明: 假设我们有一种方法来分配验证网络中大区块的任务,这样每个人都只需要下载和验证每个区块的一小部分。如果当一个节点试图下载大区块的一部分,但他们无法访问它时,该怎么办?他们能否证明数据不可用并惩罚区块生产者?不幸的是,答案是否定的。不发布数据并不是唯一引发错误的原因。引用 Al-Bassam 等人的原话:

在任何方案中,如果节点能够对某些数据不可用“发出警报”,如果发布者随后发布剩余数据,则所有在当时没有关注该特定数据的节点都无法确定是发布者恶意隐瞒数据,还是 fisherman 恶意进行误报。

  • 数据可用性采样: 虽然我们无法证明数据不可用,但每个节点都可以测试数据的可用性。这里的主要挑战是如何设计一种高效和准确的测试,即在相对较少的样本下提供高水平的置信度。一个想法是用纠删码对数据进行编码。纠删码是一种方案,即使在编码数据的恒定部分被擦除的情况下,它为原始数据添加冗余,使得原始数据仍然可以还原。纠删码有许多结构,其中 Reed-Solomon 是最受欢迎的结构之一。假设我们用 Reed-Solomon 对区块数据进行编码,那么超过常数因子  (例如  )的编码数据可用,则整个原始数据是可还原的。我们将  表示可还原率(recoverability ratio)。现在,每个节点都必须决定编码数据的其中  部分是否确实可用。为此,每个节点都可以随机采样编码数据中的  个位置,并尝试获取所有数据。只要有一个位置不可用,则节点将认为整个数据是不可用。在可用数据的比例少于  的情况下,每个节点检测到不可用的概率至少为 ,随着我们增加 ,这个概率会迅速接近 1。请注意,与区块大小相比, 是一个相对较小的数字(从技术上讲,它是一个不随区块大小增长的常数)。让我们举一个具体例子,来更清楚的说明数据可用性采用。假设我们设置了可还原率   ,样本数量   ,并且我们在网络中有  个节点。现在,让我们关注一个区块不可还原的情况,这意味着只有不到  部分的编码数据可用。在这种情况下,网络中每个节点检测到不可用的概率大于 。虽然这个想法很好,但实现起来很复杂,而且它涉及很多其他组件,其中隐含了许多细节。例如,我们必须确保编码的数据是有效的 Reed-Solomon 编码字段,保证这一点的其中一种方法是使用多项式承诺方案,例如 KZG 承诺。此外,底层的去中心化 p2p 网络必须足够强大,即使在拜占庭环境中也能支持数据识别和采样,而设计这样的 p2p 网络是目前仍在探索研究的领域,也是 Danksharding 的核心。Danksharding 是以太坊未来的数据分片解决方案,将在 EIP4844 后实现,并进一步扩展以太坊作为数据可用性层的容量。

Proto-Danksharding:blob 存储数据

看待 EIP4844 的一种视角,是将 EIP4444 和 EIP4488 巧妙地结合在一起。除此之外,EIP4844 还实现了原始的 Danksharding 所需的许多组件,其中包含数据可用性抽样提案;因此,虽然它更容易实现,但它也同样为接下来的路线图铺平了道路。

EIP4844 引入了一种新的交易类型,称为 blob-carrying transaction。每个 blob-carrying transaction 类型交易都可以“携带”一个 blob 列表。blob 是格式化为  个 BLS12-381 椭圆曲线标量场(_Scalar field_)元素的数据包,大约 125 KB。采用此特定格式的原因是为了简化创建对 blob 内容的 KZG 承诺。

与 calldata 不同,blob 的内容在执行环境中不可用。事实上,blob-carrying transaction 交易只携带对 blob 数据的承诺,并且只有这些承诺在执行环境中可用。实际数据由共识层客户端共享、获取和验证。

blob 只存储很短的时间,即 4096 个 epoch,大约是 18 天多一点。在此期间,共识节点应将此数据提供给网络中的节点。之后,共识客户端可以修剪旧的 blob。此修剪机制旨在减轻 blob 数据存储的负担。请记住,数据可用性与永久数据存储无关;18 天已经足够任何利益相关方,在这段时间内获取数据。

blob-carrying transaction 看起来像一个普通的 EIP1559 交易,包含了两个附加字段 max_fee_per_blob_gas 和 blob_versioned_hashes 。我们将在下面章节中解释这两个新字段的功能。

Blobs 费用市场

Blob 的费用市场与正常的收费市场是分开的,这意味着在 EIP4844 之后,我们将有一个正常的(执行)gas 价格和一个 blob gas 价格。Blobs gas 的费用机制类似于 EIP1559 ,目标是每个区块包含 3 个 blob ,最多允许 6 个 blob。max_fee_per_blob_gas 字段表示用户愿意支付的 blob gas 价格;它必须大于或等于当前的 blob gas 价格才有效。

这样的设计选择意味着,Layer 2 的数据可用性成本不受 Layer 1 交易需求激增的影响。此外,这种二维的费用市场设计是向更远大的愿景迈出的一步,即通过采用多个维度的 EIP1559 来提高收费市场的效率。

Blob 的容量

每个区块的 blob 的目标容量并不高。它只有 380 KB,这意味着所有 rollup 加总起来大约能达到 100 TPS。在当前参数下,存储 blob 数据会给节点运营者带来近 50GB 的额外存储要求。对于一个常规的节点来说,50GB 不是太大的额外开销,那么为什么不在每个区块中包含更多的 blob 呢?原因是每个共识节点仍然需要下载和验证所有 blob。事实上, EIP4844 之后,直到区块的所有 blob 都被下载和验证,共识客户端不会认为区块是有效的。目前,我们仍然没有巧妙的数据可用性抽样机制。因此,必须严格限制 blob 引入后带来的额外开销,以避免因为区块通信延迟过高,而破坏共识机制的稳定。[注意:基本上,共识客户端的证明时间限制是 4 秒,因此每个区块必须在 4 秒之前充分广播]。这就是为什么 blob 的目标设置相对较低的原因。

事实是,我们还没有对 blob 目标容量和区块传播延迟之间的关系有很深入的认知。以太坊的网络拓扑非常复杂,几乎不可能在测试网上模拟[注:最近的一项研究调查了主网上大区块的传播延迟,然而,区块和 blob 在传播方面表现非常不同。区块的来源单一,而 blob 来源多样化,它们可以从传播过程的并行化中受益。] 因此,参数设置需要非常谨慎,当然未来可能会调整至更高的参数。

KZG 承诺和版本化哈希

对每个 blob 的承诺采用版本化哈希的格式。它是一个 32 个字节的值,其中第一个字节是版本号,当前设置为 ,跟随 blob 的 KZG 承诺的 SHA256 哈希值的最后 31 个字节,即 version_byte + SHA256(KZG(blob))[1:] 。其基本原理是在不破坏格式的情况下保留将承诺方案从 KZG 更改为其他方案的可能性,以防万一 KZG 承诺不如我们所预期的那样安全,例如,如果量子计算机变得可行。

blob_versioned_hashes 字段表示对交易中包含的 blob 的承诺列表。请注意,一笔 blob-carrying transaction 交易可以携带多个 blob。

点求值预编译

EIP4844 引入了一种新的预编译,允许用户打开对 blob 的承诺,并有效地从智能合约访问 blob 数据。这在验证涉及 blob 数据的乐观或简洁证明时非常方便。

point_evaluation_precompile(versioned_hash, kzg_commitment, proof, z, y) 将接受版本化哈希、对 blob 的 KZG 承诺,以及在点  和值   的 KZG 打开证明作为输入。它将验证 kzg_commitment 是否与所提供的 versioned_hash 一致,以及 proof 打开是否有效,也就是说对于 blob 的拉格朗日插值多项式p(X) ,我们可以验证 p(z) = y 。

该预编译很好地满足了 rollup 的需要,并提供了简洁的有效性证明。无需在 EVM 中完全打开对 blob 的承诺,只需检查电路中作为见证提供的数据是否与 blob 一致即可,我们稍后会对其做详细介绍。

后 EIP4844 时代Scroll 协议的数据可用性

提交

EIP4844后,rollup 提交的交易将是一个携带 blob 的交易 tx 。Rollup 的交易批次将被编码进入 blob。那么 rollup 合约就无需再计算对交易批次数据的承诺了;我们只需将 tx.blob_versioned_hashes 复制到存储中,以便在最终确认阶段使用。

PI 电路中的 Blob 一致性检查

前面我们讨论过,PI 电路的功能是检查所提供的交易批次是否确实对应于提交阶段提供的交易批次的承诺。当我们将交易批次放入 blob 中时,我们仍然需要做一致性价检查,但实现的方式有所不同。

非原生域的挑战

以太坊只有一条适合配对的 BN254 椭圆曲线的预编译。Scroll 的 zkEVM 使用了此曲线进行算术运算,这意味着我们在曲线 BN254 的标量场上定义了电路的值和约束。然而,EIP4844 使用了另一条 BLS12-381 曲线用作 KZG 承诺。这让事情变得有些复杂。

选择 BLS12-381 曲线可能是出于安全性和效率的考虑。共识客户端已经使用了 BL12-381 曲线进行证明,因此它已经被所有客户端团队实现和审计。此外,BN254 曲线仅提供 100 位的安全性,而 BLS12-381 曲线提供大约 120 位的安全性。

如果两条曲线相同,我们可以在 zkEVM 电路中添加一个 advice 列,专门用于存储用零填充的 blob 数据。对所有电路列的 KZG 承诺是最终的 snark 证明的一部分(注意:为了简单起见,假设我们不在批次级别进行任何聚合),我们可以将 KZG 对 blob 列的承诺与从 blob-carrying transaction 获得的版本化哈希进行比较。

遗憾的是,事实并非如此,我们不能直接使用 blob 的版本化哈希交叉检验对 advice 列的承诺。幸运的是,我们还有另一种可行的方法。假设 p(X) 为 BLS12-381 标量场上 blob 的拉格朗日多项式。我们可以在合约和电路中,同时在随机点 z 上计算这个多项式,并检查计算结果是否相等。然后根据著名的 Schwartz-Zippel 引理,如果等式以极高的概率成立,那么两个多项式是相同的。这里有挑战性的部分是在电路中对 p(X) 求值,因为必须在 BLS12-381 曲线上完成,而不是 BN254 曲线,而非原生域的运算通常成本都较高。使用重心公式,我们可以通过   次非原生的乘除法来做到这一点,并且对证明者带来的额外成本相对较小。

概念验证

我们已实现用于电路中 blob 一致性检查的 PoC。该电路将对交易批次 batch_commit 、挑战点 z 和求值 y 的承诺作为公共输入。证明人必须提供 blob 作为见证。我们应用 Fiat-Shamir 来获得伪随机的挑战点 z ,随后电路约束 z = hash(batch_commit+blob) 。此外,电路还将约束 p(z)=y ,其中 p(X) 是 blob 的拉格朗日插值多项式。

实现中,该 gadget 使用了 28,083,027 个 advice 单元格和 3,393,116 个 lookup advice 单元格。在 M1 MacBook Pro(CPU 10 核,内存 16 GB)上,生成证明平均需要 138.97 秒。

结论

数据可用性是区块链扩容难题的核心部分。EIP4844 是提高以太坊作为数据可用性层容量的一大步。但是,按照目前的参数设置,它无法提供足够大的容量来满足 rollup 的所有需求。希望未来 Danksharding 凭借其出色的数据可用性抽样功能,可以显著改善这种情况。在此之前,rollup 需要依赖 calldata 和 blob 存储的组合,并开发更好的压缩方案;或者接受额外的安全假设,采用以太坊以外的数据可用性层。

转载声明:本文 由CoinON抓取收录,观点仅代表作者本人,不代表CoinON资讯立场,CoinON不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。若以此作为投资依据,请自行承担全部责任。

声明:图文来源于网络,如有侵权请联系删除

风险提示:投资有风险,入市需谨慎。本资讯不作为投资理财建议。

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 2023年12月7日 下午12:45
下一篇 2023年12月7日 下午6:44

相关推荐

Scroll:后 EIP4844 时代的数据可用性

星期四 2023-12-07 18:44:40

介绍

在过去的几年里,解决区块链的扩容难题一直是以太坊社区的重中之重,其目标是在不牺牲去中心化或安全性的情况下实现更高的可扩展性。经过大量的探索,以太坊社区一致决定采用以 rollup 为中心的方案来解决可扩展性问题,因此在以太坊路线图中始终优先考虑 rollup 的需求。

大多数 rollup 唯一的需求点是改进以太坊作为数据可用性层。EIP4844,也称为 Proto-Danksharding,是以太坊对这一需求的快速响应,当然改进的版本正在开发中。EIP4844 引入了一种新的交易格式,称为 blob-carrying transactions,它允许用户在交易中包含存储数据的二进制字段( 以下简称 blob ) ,保证这些数据在几周内是可用的。很快以太坊网络将经历一个名为坎昆升级( Cancun-Deneb)的硬分叉,其中就包括 EIP4844 等。

虽然区块链的叙事周期起起落落,围绕数据可用性的讨论一直在话题中心,然而,大家对数据可用性的理解仍然没有那么深入。所以在这篇文章中,我们将讨论什么是数据可用性层,以及为什么 rollup 需要使用数据可用性层。此外,我们还讨论了 EIP4844 以及它将如何提高以太坊作为数据可用性层的能力。最后,我们研究了如何在电路中打开 blob 承诺,并展示了一个简单的概念验证。

执行层的正确性

去中心化和无需许可的区块链为用户提供了许多保障,包括抗审查性、不可变性、活性,以及最重要的执行正确性。简单地说,状态转换是有效的,即智能合约的执行总是正确的。这一切都归功于去中心化网络中,每个节点都将检查区块的有效性。而 rollups 试图在更便宜的成本下提供相同的保障!

Rollup 的核心思路是将执行从 L1 转移到更便宜的环境中,同时采用一种机制简洁地(ZK) 或乐观地 (OP) 向 L1 rollup 合约证明这些执行是正确完成的,并且状态转换是有效的。需要注意的是,所谓的 rollup 合约通常接受的是对 rollup 链完整状态的承诺,例如其状态树的默克尔树的根。状态转换将不断更新此承诺。

如果你对这些机制不是很了解,以下是这两个分类的工作原理:

  • OP:乐观机制是建立在欺诈证明的基础上的。这里的想法是,如果 rollup 运营者向 L1 rollup 合约提交了无效的状态转换,人们就有激励向合约证明这种欺诈行为并获得奖励。因此,(尽管会有一些延迟)如果我们假设有人可以随时监控 rollup 链,就可以保证执行的正确性。只要没有无效的状态转换,L1 就不必执行任何 rollup 交易;这就是用户节省成本所在。相反,如果 rollup 运营者提交了无效的状态转换,就必须有人在指定的时间范围内构建并提交欺诈证明;否则,无效的状态转换将被最终确认且不可回滚。因此,rollup 链的完整状态必须对监测者可见(或可还原),否则他们甚至无法识别无效的状态转换。
  • ZK:从某种意义上说,简洁的有效性证明更有说服力,它们不依赖于受激励的参与者来监测链。但这些证明的内部工作更加复杂,并利用了加密魔法,不过它们在实现上很简单,可以在数学层面证明 rollup 链的新状态是正确执行的结果。这意味着即使 rollup 链的完整状态永远不可用,执行的正确性也始终可以得到保证。

本文将重点介绍具有简洁证明的 rollup。

不幸的是,仅仅确保执行的正确性是不够的。 为了提供抗审查性或活性等属性,rollup 仍然需要保证其完整状态是可还原的。如果 rollup 不能保证其完整状态是可还原的,则用户无法在 rollup 链中生成其账户余额的证明。这样的话,如果没有 rollup 运营者的合作,他们将无法将资金提取到 L1;显然,这是对 L1 保障安全性的严重偏离。

什么是数据可用性?

数据可用性 (DA) 指的是保证数据在网络内公开及时地发布。 换言之,我们这里指的数据可用,意味着假设发布者不会隐瞒数据。请注意,数据可用性与永久存储无关;数据会存在足够长的时间,在这段时间内任何利益相关的人都可以获取到它。数据可用性层 是用于发布数据的基础结构,可以保证数据可用。

有很多人会觉得 “数据可用性” 不是很好理解或者具有误导性。事后看来,像数据发布这样的替代术语可能是更好的选择。

详见:https://twitter.com/dankrad/status/1699598362851287459

数据可用性问题的起源

确保数据可用性的问题最初是在 Layer 1 扩容解决方案的背景下引入的。一个简单直接的扩容策略是增加每个区块的容量。许多扩容解决方案都或多或少通过不同方式来实现此目的。任何增加区块大小的扩容解决方案的主要问题是,网络中的每个人都必须下载并验证所有区块。因此,如果我们过多地增加区块大小,性能较差的节点就会落后并被淘汰。因此,我们逐渐将得到一个不那么去中心化的网络。如果我们能以某种方式在节点之间分配验证区块的任务,这样每个人都只需要下载和验证每个区块的一小部分,那么我们就可以拥有更大的区块。这一系列解决方案的一个挑战是确保整个区块确实被发布。

Rollup 的数据可用性

在上一章节中,我们讨论了为什么 rollup 链完整状态的可恢复性对于继承 L1 的安全性是必要的。我们可以通过提供如下的任一可用数据来确保完整状态是可恢复的:(1) 交易数据或 (2) 状态差异数据。

Rollup 将继承其数据可用性层的所有安全假设。这就是为什么许多 rollup 使用它们所基于的 L1 作为数据可用性层的原因:以避免额外的安全假设。使用以太坊作为数据可用性层的一种方法是简单地将数据嵌入到交易中,并确保它包含在 L1 区块中。只要以太坊区块可用,交易中嵌入的数据也将可用。以太坊区块一直是可用的,因为区块生产者被激励及时广播他们的区块以获得其他验证者的证明;否则,他们的区块将被忽略。

目前,在包含 EIP4844 之前,在交易中嵌入数据的最便宜的方案是将数据作为 calldata 字段。 calldata 是一个只读内存空间,用于存储你调用智能合约函数时一起发送的参数。此内存空间只能在函数执行期间访问,并且比存储更省 gas 费。虽然函数调用后无法在 EVM 环境中访问 calldata 的内容 ,但任何可以访问以太坊交易历史记录的人仍然可以恢复它。

但是,calldata 仍然很昂贵, 因为它除了数据可用性还提供了其他功能;一般来说,智能合约中可以读取 calldata 数据。而 EIP4844 引入了 blob-carrying transactions 交易后,旨在单独服务于数据可用性,将仅提供对 blob 数据的承诺,并且无法在智能合约中直接读取此数据。因此,预计在 blob 中发布数据的成本会低得多。然而,blob 数据的 gas 费用将采用类似 EIP1559 的机制单独定价。稍后会做更详细的介绍。

需要注意的是,降低数据可用性成本可以直接降低 rollup 的运营成本,这也意味着 rollup 用户的交易费用会变得更低。如今,常见的 rollup 运营商支付的 gas 费用中,大约有 80% 用于将 rollup 链数据嵌入到 L1 上的 calldata ,而只有 20% 用于证明验证。

Scroll 协议中的数据可用性

ZKRollup 合约:提交和最终确认

Scroll 的 rollup 过程有很多阶段,但出于本文的目的,我们将只关注提交和最终确认,这两个阶段分别处理数据可用性和证明验证。

  • 提交: 每隔几分钟,排序器就会提交一批新的交易,作为 calldata 调用 rollup 合约的 commitBatch 的方法。该函数计算并存储批次(Batch)的哈希值,当我们验证证明时,该 Keccak 哈希值将作为对 snark 验证器的承诺和输入。请注意,L2 交易数据嵌入在 L1 交易中。虽然数据不作为以太坊状态存储,但它有效地充当了 Scroll 链的数据可用性解决方案。任何人都可以收集这些交易(从归档节点)并查看其有效负载。
  • 最终确认: 提交批次后,证明者开始为批次的执行创建简洁的状态转换证明。 finalizeBatchWithProof 将证明作为输入,并验证如下所示的声明:

给定 prevStateRoot , 在commitment(txBatch)中执行提交的交易批次,将更新状态根为 postStateRoot 。

请注意,最终确认步骤仅将所有已执行交易的承诺作为输入,而不是所有交易。

PI电路:解压缩公共输入

如我们之前所说,证明声明仅包括对已执行交易的承诺。这是为了节省链上验证器合约的开销,使其不必处理大量的公共输入多项式,从而有效地压缩公共输入。然而,证明者必须在电路中打开这个承诺,即它必须知道批次中的实际交易。在 Scroll 的 zkEVM 上,PI 电路就是打开此承诺并解压缩 zkEVM 其余部分的公共输入的子电路。

PI 电路将对交易批次的承诺作为公共输入,证明者必须提供原始交易批次数据作为见证。PI 电路的约束条件将检查,所提供的见证确实与公共输入中的承诺所对应。跳过该一致性检查会使得恶意证明者提交一批次交易却执行另一批次交易,从而使 rollup 链的完整状态无法恢复。

扩展以太坊作为数据可用性层的可用性

到目前为止,我们讨论了数据可用性的重要性,以及以太坊今天如何被用作DA层。现在让我们转变为协议设计者的身份,快速浏览一下增加以太坊作为 DA 层容量的不同思路。

  • 降低 calldata gas 成本: 这是一个非常直观的想法,可以直接增加在以太坊发布更多数据以实现数据可用性的容量。事实上,这在过去的 EIP-2028 中已经完成。但是,这种方法存在局限性。更低的 gas 成本 calldata 意味着更大的区块,这意味着区块传播的延迟更高。将区块传播延迟推得太高会破坏 L1 的一致性机制。
  • 降低 calldata gas 成本并对区块中的calldata设置上限: EIP4488 正是这样提出的。虽然这听起来很棒,但以太坊的核心开发者认为这个提议太复杂了,实施风险太大,所以最终被放弃了。值得注意的是,该 EIP 附有 EIP4444 的姊妹提案。EIP4444 的目标是降低节点运营者的数据存储要求,并建议执行客户端在一年后修剪历史区块数据。EIP4444 旨在通过减轻 EIP4488 引入的额外存储负担来实现 EIP4488。
  • 数据不可用证明: 假设我们有一种方法来分配验证网络中大区块的任务,这样每个人都只需要下载和验证每个区块的一小部分。如果当一个节点试图下载大区块的一部分,但他们无法访问它时,该怎么办?他们能否证明数据不可用并惩罚区块生产者?不幸的是,答案是否定的。不发布数据并不是唯一引发错误的原因。引用 Al-Bassam 等人的原话:

在任何方案中,如果节点能够对某些数据不可用“发出警报”,如果发布者随后发布剩余数据,则所有在当时没有关注该特定数据的节点都无法确定是发布者恶意隐瞒数据,还是 fisherman 恶意进行误报。

  • 数据可用性采样: 虽然我们无法证明数据不可用,但每个节点都可以测试数据的可用性。这里的主要挑战是如何设计一种高效和准确的测试,即在相对较少的样本下提供高水平的置信度。一个想法是用纠删码对数据进行编码。纠删码是一种方案,即使在编码数据的恒定部分被擦除的情况下,它为原始数据添加冗余,使得原始数据仍然可以还原。纠删码有许多结构,其中 Reed-Solomon 是最受欢迎的结构之一。假设我们用 Reed-Solomon 对区块数据进行编码,那么超过常数因子  (例如  )的编码数据可用,则整个原始数据是可还原的。我们将  表示可还原率(recoverability ratio)。现在,每个节点都必须决定编码数据的其中  部分是否确实可用。为此,每个节点都可以随机采样编码数据中的  个位置,并尝试获取所有数据。只要有一个位置不可用,则节点将认为整个数据是不可用。在可用数据的比例少于  的情况下,每个节点检测到不可用的概率至少为 ,随着我们增加 ,这个概率会迅速接近 1。请注意,与区块大小相比, 是一个相对较小的数字(从技术上讲,它是一个不随区块大小增长的常数)。让我们举一个具体例子,来更清楚的说明数据可用性采用。假设我们设置了可还原率   ,样本数量   ,并且我们在网络中有  个节点。现在,让我们关注一个区块不可还原的情况,这意味着只有不到  部分的编码数据可用。在这种情况下,网络中每个节点检测到不可用的概率大于 。虽然这个想法很好,但实现起来很复杂,而且它涉及很多其他组件,其中隐含了许多细节。例如,我们必须确保编码的数据是有效的 Reed-Solomon 编码字段,保证这一点的其中一种方法是使用多项式承诺方案,例如 KZG 承诺。此外,底层的去中心化 p2p 网络必须足够强大,即使在拜占庭环境中也能支持数据识别和采样,而设计这样的 p2p 网络是目前仍在探索研究的领域,也是 Danksharding 的核心。Danksharding 是以太坊未来的数据分片解决方案,将在 EIP4844 后实现,并进一步扩展以太坊作为数据可用性层的容量。

Proto-Danksharding:blob 存储数据

看待 EIP4844 的一种视角,是将 EIP4444 和 EIP4488 巧妙地结合在一起。除此之外,EIP4844 还实现了原始的 Danksharding 所需的许多组件,其中包含数据可用性抽样提案;因此,虽然它更容易实现,但它也同样为接下来的路线图铺平了道路。

EIP4844 引入了一种新的交易类型,称为 blob-carrying transaction。每个 blob-carrying transaction 类型交易都可以“携带”一个 blob 列表。blob 是格式化为  个 BLS12-381 椭圆曲线标量场(_Scalar field_)元素的数据包,大约 125 KB。采用此特定格式的原因是为了简化创建对 blob 内容的 KZG 承诺。

与 calldata 不同,blob 的内容在执行环境中不可用。事实上,blob-carrying transaction 交易只携带对 blob 数据的承诺,并且只有这些承诺在执行环境中可用。实际数据由共识层客户端共享、获取和验证。

blob 只存储很短的时间,即 4096 个 epoch,大约是 18 天多一点。在此期间,共识节点应将此数据提供给网络中的节点。之后,共识客户端可以修剪旧的 blob。此修剪机制旨在减轻 blob 数据存储的负担。请记住,数据可用性与永久数据存储无关;18 天已经足够任何利益相关方,在这段时间内获取数据。

blob-carrying transaction 看起来像一个普通的 EIP1559 交易,包含了两个附加字段 max_fee_per_blob_gas 和 blob_versioned_hashes 。我们将在下面章节中解释这两个新字段的功能。

Blobs 费用市场

Blob 的费用市场与正常的收费市场是分开的,这意味着在 EIP4844 之后,我们将有一个正常的(执行)gas 价格和一个 blob gas 价格。Blobs gas 的费用机制类似于 EIP1559 ,目标是每个区块包含 3 个 blob ,最多允许 6 个 blob。max_fee_per_blob_gas 字段表示用户愿意支付的 blob gas 价格;它必须大于或等于当前的 blob gas 价格才有效。

这样的设计选择意味着,Layer 2 的数据可用性成本不受 Layer 1 交易需求激增的影响。此外,这种二维的费用市场设计是向更远大的愿景迈出的一步,即通过采用多个维度的 EIP1559 来提高收费市场的效率。

Blob 的容量

每个区块的 blob 的目标容量并不高。它只有 380 KB,这意味着所有 rollup 加总起来大约能达到 100 TPS。在当前参数下,存储 blob 数据会给节点运营者带来近 50GB 的额外存储要求。对于一个常规的节点来说,50GB 不是太大的额外开销,那么为什么不在每个区块中包含更多的 blob 呢?原因是每个共识节点仍然需要下载和验证所有 blob。事实上, EIP4844 之后,直到区块的所有 blob 都被下载和验证,共识客户端不会认为区块是有效的。目前,我们仍然没有巧妙的数据可用性抽样机制。因此,必须严格限制 blob 引入后带来的额外开销,以避免因为区块通信延迟过高,而破坏共识机制的稳定。[注意:基本上,共识客户端的证明时间限制是 4 秒,因此每个区块必须在 4 秒之前充分广播]。这就是为什么 blob 的目标设置相对较低的原因。

事实是,我们还没有对 blob 目标容量和区块传播延迟之间的关系有很深入的认知。以太坊的网络拓扑非常复杂,几乎不可能在测试网上模拟[注:最近的一项研究调查了主网上大区块的传播延迟,然而,区块和 blob 在传播方面表现非常不同。区块的来源单一,而 blob 来源多样化,它们可以从传播过程的并行化中受益。] 因此,参数设置需要非常谨慎,当然未来可能会调整至更高的参数。

KZG 承诺和版本化哈希

对每个 blob 的承诺采用版本化哈希的格式。它是一个 32 个字节的值,其中第一个字节是版本号,当前设置为 ,跟随 blob 的 KZG 承诺的 SHA256 哈希值的最后 31 个字节,即 version_byte + SHA256(KZG(blob))[1:] 。其基本原理是在不破坏格式的情况下保留将承诺方案从 KZG 更改为其他方案的可能性,以防万一 KZG 承诺不如我们所预期的那样安全,例如,如果量子计算机变得可行。

blob_versioned_hashes 字段表示对交易中包含的 blob 的承诺列表。请注意,一笔 blob-carrying transaction 交易可以携带多个 blob。

点求值预编译

EIP4844 引入了一种新的预编译,允许用户打开对 blob 的承诺,并有效地从智能合约访问 blob 数据。这在验证涉及 blob 数据的乐观或简洁证明时非常方便。

point_evaluation_precompile(versioned_hash, kzg_commitment, proof, z, y) 将接受版本化哈希、对 blob 的 KZG 承诺,以及在点  和值   的 KZG 打开证明作为输入。它将验证 kzg_commitment 是否与所提供的 versioned_hash 一致,以及 proof 打开是否有效,也就是说对于 blob 的拉格朗日插值多项式p(X) ,我们可以验证 p(z) = y 。

该预编译很好地满足了 rollup 的需要,并提供了简洁的有效性证明。无需在 EVM 中完全打开对 blob 的承诺,只需检查电路中作为见证提供的数据是否与 blob 一致即可,我们稍后会对其做详细介绍。

后 EIP4844 时代Scroll 协议的数据可用性

提交

EIP4844后,rollup 提交的交易将是一个携带 blob 的交易 tx 。Rollup 的交易批次将被编码进入 blob。那么 rollup 合约就无需再计算对交易批次数据的承诺了;我们只需将 tx.blob_versioned_hashes 复制到存储中,以便在最终确认阶段使用。

PI 电路中的 Blob 一致性检查

前面我们讨论过,PI 电路的功能是检查所提供的交易批次是否确实对应于提交阶段提供的交易批次的承诺。当我们将交易批次放入 blob 中时,我们仍然需要做一致性价检查,但实现的方式有所不同。

非原生域的挑战

以太坊只有一条适合配对的 BN254 椭圆曲线的预编译。Scroll 的 zkEVM 使用了此曲线进行算术运算,这意味着我们在曲线 BN254 的标量场上定义了电路的值和约束。然而,EIP4844 使用了另一条 BLS12-381 曲线用作 KZG 承诺。这让事情变得有些复杂。

选择 BLS12-381 曲线可能是出于安全性和效率的考虑。共识客户端已经使用了 BL12-381 曲线进行证明,因此它已经被所有客户端团队实现和审计。此外,BN254 曲线仅提供 100 位的安全性,而 BLS12-381 曲线提供大约 120 位的安全性。

如果两条曲线相同,我们可以在 zkEVM 电路中添加一个 advice 列,专门用于存储用零填充的 blob 数据。对所有电路列的 KZG 承诺是最终的 snark 证明的一部分(注意:为了简单起见,假设我们不在批次级别进行任何聚合),我们可以将 KZG 对 blob 列的承诺与从 blob-carrying transaction 获得的版本化哈希进行比较。

遗憾的是,事实并非如此,我们不能直接使用 blob 的版本化哈希交叉检验对 advice 列的承诺。幸运的是,我们还有另一种可行的方法。假设 p(X) 为 BLS12-381 标量场上 blob 的拉格朗日多项式。我们可以在合约和电路中,同时在随机点 z 上计算这个多项式,并检查计算结果是否相等。然后根据著名的 Schwartz-Zippel 引理,如果等式以极高的概率成立,那么两个多项式是相同的。这里有挑战性的部分是在电路中对 p(X) 求值,因为必须在 BLS12-381 曲线上完成,而不是 BN254 曲线,而非原生域的运算通常成本都较高。使用重心公式,我们可以通过   次非原生的乘除法来做到这一点,并且对证明者带来的额外成本相对较小。

概念验证

我们已实现用于电路中 blob 一致性检查的 PoC。该电路将对交易批次 batch_commit 、挑战点 z 和求值 y 的承诺作为公共输入。证明人必须提供 blob 作为见证。我们应用 Fiat-Shamir 来获得伪随机的挑战点 z ,随后电路约束 z = hash(batch_commit+blob) 。此外,电路还将约束 p(z)=y ,其中 p(X) 是 blob 的拉格朗日插值多项式。

实现中,该 gadget 使用了 28,083,027 个 advice 单元格和 3,393,116 个 lookup advice 单元格。在 M1 MacBook Pro(CPU 10 核,内存 16 GB)上,生成证明平均需要 138.97 秒。

结论

数据可用性是区块链扩容难题的核心部分。EIP4844 是提高以太坊作为数据可用性层容量的一大步。但是,按照目前的参数设置,它无法提供足够大的容量来满足 rollup 的所有需求。希望未来 Danksharding 凭借其出色的数据可用性抽样功能,可以显著改善这种情况。在此之前,rollup 需要依赖 calldata 和 blob 存储的组合,并开发更好的压缩方案;或者接受额外的安全假设,采用以太坊以外的数据可用性层。