本文档是 Optimism 项目的术语表,详细定义了 L1/L2、区块、交易、排序器、存款、提款、批处理提交、L2 链推导等核心概念。解释了这些概念在 Optimism rollup 中的作用,以及它们与以太坊主链的交互方式,例如排序器如何工作、存款和提款的流程、以及如何从 L1 数据推导出 L2 链。
<!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> 目录
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
指以太坊区块链,与 layer 2 形成对比,后者指的是 Optimism。
指 Optimism 区块链(在本仓库中指定),与 layer 1 形成对比,后者指的是以太坊区块链。
一个区块是交易的顺序列表,以及存储在区块头部中的一些属性。这里的代码注释或 以太坊黄皮书(pdf) 第 4.3 节中可以找到这些属性的描述。
区分输入区块属性(在执行区块中的交易之前已知)和输出区块属性(在执行区块的交易之后派生)是有用的。这些包括各种 Merkle Patricia Trie 根,它们特别提交到 L2 状态和执行期间发出的 log 事件。
"Externally Owned Account"(外部拥有账户),一个以太坊术语,用于指用户操作的地址,与合约地址相对。
Merkle Patricia Trie (MPT) 是一种稀疏 trie,它是一种将键映射到值的树状结构。MPT 的根哈希是对树内容的承诺,它允许为树中编码的任何键值映射构造一个证明。这种证明称为 Merkle 证明,并且可以针对 Merkle 根进行验证。
重组,或简称 re-org,是指区块链的头部(它的最后一个区块)发生变化(由分叉选择规则决定)为不是先前头部的子区块的情况。
由于网络状况或攻击,L1 重组可能会发生。L2 重组是 L1 重组的结果,通过 L2 链推导 进行调解。
放置在 L2 genesis 状态(即链的开始)中的合约。
所有预部署合约都在 [预部署规范][./predeploys.md] 中指定。
收据是由交易生成的输出,包括状态码、使用的 gas 量、log 条目的列表和一个索引这些条目的 bloom filter。Log 条目最常用于编码 [Solidity 事件]。
收据不存储在区块中,但区块存储一个 Merkle Patricia Trie 根,用于包含区块中每个交易的收据的树。
收据在 黄皮书(pdf) 第 4.3.1 节中指定。
以太坊提供了一种机制(如 EIP-2718 中所述)用于定义不同的交易类型。不同的交易类型可以包含不同的 payload,并由协议以不同的方式处理。
分叉选择规则是用于确定哪个区块应被视为区块链头部的规则。在 L1 上,这由权益证明规则确定。
L2 也有一个分叉选择规则,尽管规则因我们想要 安全 L2 head、不安全 L2 head 还是 已最终确定的 L2 head 而异。
以太坊中的交易按交易支付给矿工的价格排序。当多个参与者竞争成为区块中的第一个交易时,会发生优先级 Gas 拍卖 (PGA)。每个参与者不断更新其交易的 gas 价格。当在其他参与者之前提交交易有价值时(例如作为第一个存款或在没有更多剩余的保证 gas 之前提交存款),就会发生 PGA。由于在很短的时间内提交了大量交易,PGA 往往对网络产生负面的外部影响。
rollup 中的交易可以通过两种方式包含:
提交交易以包含在批次中可以通过减少开销来节省成本,并使排序器能够在 L1 确认数据之前预先确认交易。
排序器是在排序器模式下运行的 rollup 节点,或者是此 rollup 节点的运营商。
排序器是一个特权参与者,它从 L2 用户接收 L2 交易,使用它们创建 L2 区块,然后将其提交给 数据可用性提供者(通过 batcher)。它还将 输出根 提交给 L1。
排序窗口是 L1 区块的范围,可以从中推导出排序周期。
第一个 L1 区块编号为 N
的排序窗口包含周期 N
的 batcher 交易。窗口包含区块 [N, N + SWS)
,其中 SWS
是排序器窗口大小。
TODO 指定排序器窗口大小
此外,窗口中的第一个区块定义了 存款交易,这些交易确定要包含在周期中第一个 L2 区块中的 [存款]。
排序周期是从 L1 区块的排序窗口派生的 L2 区块的顺序范围。
每个周期都由一个周期号标识,该周期号等于排序窗口中第一个 L1 区块的区块号。
周期的大小可以变化,但要受到一些约束。有关更多详细信息,请参见 L2 链推导规范。
L2 区块的 L1 来源是与其 排序周期 对应的 L1 区块。
通常,存款是从 L1 区块派生的 L2 交易(由 [rollup 驱动])。
虽然交易存款最常用于(但不仅限于)将 ETH 和 token“存入”(桥接)到 L2,但 deposit 一词应理解为“从 L1 存入到 L2 的交易”。
术语 deposit 有些含糊,因为这些“交易”存在于多个层级。本节消除了所有与存款相关的术语的歧义。
值得注意的是,deposit 可以指:
我们有时还会谈论 用户存款,这是一个类似的术语,明确排除了 L1 属性已存入的交易。
存款在 存款规范 中指定。
已存入的交易 是一笔从 L1 派生并包含在 L2 区块中的 L2 交易。
有两种类型的已存入的交易:
L1 属性已存入的交易 是一笔 已存入的交易,用于通过调用 L1 属性预部署合约 在 L2 上注册 L1 区块属性(编号、时间戳等)。然后,该合约可用于读取与当前 L2 区块对应的 L1 区块的属性。
L1 属性已存入的交易 在存款规范的 L1 属性存款 部分中指定。
用户存入的交易 是从对 存款合约 的 L1 调用派生的 已存入的交易(存款调用)。
用户存入的交易 在存款规范的 交易存款 部分中指定。
存款调用 是对 存款合约 的 L1 调用,它将被 [rollup 驱动] 派生为 用户存入的交易。
此调用指定已存入的交易的所有数据(目标地址、值、calldata 等)。
存款交易 是一笔进行一个或多个 存款调用 的 L1 交易。
存款人 是进行(是 存款调用 的 msg.sender
)的 L1 账户(合约或 EOA)。存款人 不是 存款交易的发起者(即 tx.origin
)。
已存入的交易类型 是一个 [EIP-2718] 交易类型,它指定 已存入的交易 的输入字段和正确的处理方式。
有关更多信息,请参见存款规范的 相应部分。
存款合约 是一个 L1 合约,EOA 和合约可以向其发送 [存款]。存款作为 log 记录(在 Solidity 中,这些被称为 事件)发出,供 rollup 节点 使用。
高级说明:存款不存储在 calldata 中,因为它们可以由合约发送,在这种情况下,calldata 是合约之间内部执行的一部分,并且此中间 calldata 未捕获在包含在 L1 区块中的 Merkle Patricia Trie 根 中。
参见存款规范
TODO 扩展整个部分以使其更清晰
通常,提款是从 L2 发送到 L1 的交易,该交易可以传输数据和/或价值。
术语 提款 有些含糊,因为这些“交易”存在于多个层级。为了区分提款的 L1 和 L2 组件,我们引入了以下术语:
L1 上的 EOA,它通过提交验证其包含在 L2 上所需的数据来最终确定提款。
最终确定期(有时也称为 提款延迟)是在 [提款][withrawals] 可以最终确定之前必须经过的最短时间(以秒为单位)。
最终确定期是必要的,以便为 验证者 提供足够的时间来做出 故障证明。
TODO 指定最终确定期的当前值
数据可用性保证某些数据在合理的时间窗口内将“可用”(即可检索)。在 Optimism 的情况下,所讨论的数据是 排序器批次,验证者 需要这些批次来验证排序器的工作并验证 L2 链。
最终确定期 应被视为可用性窗口的下限,因为那是数据可用性最关键的时候,因为它需要执行 故障证明。
“可用性”并不意味着保证数据的长期存储。
数据可用性提供者是一种可用于使数据可用的服务。有关其含义的更多信息,请参见 数据可用性。
理想情况下,一个好的数据可用性提供者提供强大的可验证的数据可用性保证。
目前,唯一支持的数据可用性提供者是以太坊调用数据。以太坊数据 blobs 将在部署在以太坊上时得到支持。
排序器批次是 L2 交易的列表(已提交给排序器),并标记有 周期编号 和 L2 区块时间戳(鉴于我们的区块时间是恒定的,可以很容易地转换为区块编号)。
排序器批次是 L2 推导输入 的一部分。每个批次代表构建一个 L2 区块所需的输入(给定现有的 L2 链状态)— 除了每个周期的第一个区块,它还需要有关存款的信息(参见有关 L2 推导输入 的部分)。
通道是将 排序器批次(用于顺序区块)压缩在一起的序列。将多个批次组合在一起的原因很简单,是为了获得更好的压缩率,从而降低数据可用性成本。
可以将通道拆分为 帧,以便通过 batcher 交易 传输。将通道拆分为帧的原因是,通道可能太大而无法包含在单个 batcher 交易中。
通道通过其时间戳(创建通道时的 UNIX 时间)和一个随机值来唯一标识。有关更多信息,请参见 L2 链推导规范的 帧格式 部分。
在 rollup 节点(它是通道的消费者)方面,如果其最终帧(显式标记为最终帧)尚未被读取,则通道被认为是打开的,否则被认为是关闭的。
通道帧是属于 [通道] 的数据块。Batcher 交易 携带一个或多个帧。将通道拆分为帧的原因是,通道可能太大而无法包含在单个 batcher 交易中。
Batcher 是一个软件组件(独立的程序),负责使通道在数据可用性提供者上可用。Batcher 与 rollup 节点通信以检索通道。然后使用 batcher 交易 使通道可用。
TODO 未来,我们可能希望使 batcher 负责构造通道,仅允许它查询 rollup 节点以获取 L2 区块输入。
Batcher 交易是 batcher batcher 提交给数据可用性提供者的交易,以便使通道可用。这些交易携带一个或多个完整帧,这些帧可能属于不同的通道。通道的帧可以在多个 batcher 交易之间拆分。
当提交给以太坊 calldata 时,batcher 交易的接收者必须是排序器收件箱地址。该交易还必须由公认的批次提交者帐户签名。
TODO 指定这些公认的批次提交者帐户存储在何处
通道超时是一个持续时间(以 L1 区块为单位),在此期间 通道帧 可能会在 batcher 交易 中落在 L1 上。
通道 的帧的可接受时间范围是 [channel_id.timestamp, channel_id.timestamp + CHANNEL_TIMEOUT]
。这些帧的可接受 L1 区块范围是其时间戳落在此时间范围内的任何 L1 区块。(请注意,channel_id.timetamp
必须低于在其中看到通道帧的任何 L1 区块的 L1 区块时间戳,否则这些帧将被忽略。)
通道超时的目的是双重的:
TODO 指定
CHANNEL_TIMEOUT
L2 链推导是一个从 L1 读取 L2 推导输入 以推导 L2 链的过程。
有关更多详细信息,请参见 L2 链推导规范。
此术语指的是 L1 区块中找到的数据,并且由 rollup 节点 读取以构造 payload 属性。
L2 推导输入包括:
此术语指的是由 L1 上的 SystemConfig
合约维护并由 L2 [推导] 过程读取的动态可配置 rollup 参数集合。
这些参数使密钥能够定期轮换,并调整外部成本参数,而无需硬分叉的网络升级开销。
此术语指的是一个可以从 L1 上找到的 L2 链推导输入 派生的对象,然后将其传递给 执行引擎 以构造 L2 区块。
payload 属性对象本质上编码没有输出属性的区块。
payload 属性最初在 以太坊引擎 API 规范 中指定,我们在 执行引擎规范 中对其进行了扩展。
另请参见 rollup 节点规范的 构建 Payload 属性 部分。
L2 genesis 区块是当前版本中 L2 链的第一个区块。
L2 genesis 区块的状态包括:
L2 genesis 区块的时间戳必须是 区块时间 的倍数(即,block 时间是 2 秒,因此是偶数)。
在将 rollup 协议更新到新版本时,我们可以执行squash fork,这是一个需要创建新的 L2 genesis 区块的过程。这个新的 L2 genesis 区块将具有区块编号 X + 1
,其中 X
是更新之前最后一个 L2 区块的区块编号。
squash fork 不应与 re-genesis 混淆,re-genesis 是我们过去采用的类似过程,它也会重置 L2 区块编号,以便新的 L2 genesis 区块的编号为 0。我们将来不会采用 re-genesis。
squash fork 优于 re-genesis,因为它们避免了复制 L2 区块编号,这会破坏许多外部工具。
在 输出 oracle 合约上提出 genesis 区块 的输出根的 L1 区块编号。
在当前实现中,这是部署或升级输出 oracle 合约的 L1 区块编号。
安全 L2 区块是可以完全由 rollup 节点 从 L1 推导的 L2 区块。这可能会因不同的节点而异,具体取决于它们对 L1 链的看法。
安全 L2 head 是 rollup 节点 知道的最高的 安全 L2 区块。
不安全 L2 区块是 rollup 节点 知道的,但不是从 L1 链派生的 L2 区块。在排序器模式下,这将是排序器本身排序的区块。在验证器模式下,这将是从排序器通过 不安全同步 获取的区块。
不安全 L2 head 是 rollup 节点 知道的最高的 不安全 L2 区块。
不安全区块合并是 rollup 节点 尝试向前移动 [安全 L2 head] 一个区块的过程,以便最旧的 不安全 L2 区块 成为新的安全 L2 head。
为了执行合并,节点验证从 L1 链派生的 payload 属性 是否与最旧的不安全 L2 区块完全匹配。
有关更多信息,请参见 L2 链推导规范的 引擎队列部分。
已最终确定的 L2 head 是可以从 [已最终确定的][finality] L1 区块(即,比两个 L1 周期(64 个 L1 时间槽)旧的 L1 区块)派生的最高 L2 区块。
[finality]: <https://hackmd.io/@prysmaticlabs/finality> 已最终确定的 L1 数据。
当合约从 L1 向 L2 提交 存款 时,其地址(由 ORIGIN
和 CALLER
返回)将使用合约地址的修改表示形式进行别名化。
rollup 节点负责从 L1 链 推导 L2 链(L1 区块 及其相关的 收据)。
rollup 节点可以以验证器或排序器模式运行。
在排序器模式下,rollup 节点从用户接收 L2 交易,并使用它们来创建 L2 区块。然后,这些区块通过 批量提交 提交给 数据可用性提供者。然后,L2 链推导充当完整性检查,并作为检测 L1 链 重组 的一种方式。
在验证器模式下,rollup 节点按照上述指示执行推导,但也能够通过直接从排序器获取区块来“提抢跑”L1 链,在这种情况下,推导用于验证排序器的行为。
以验证器模式运行的 rollup 节点有时称为副本。
TODO 展开此内容以包括输出根提交
有关更多信息,请参见 rollup 节点规范。
rollup 驱动是负责从 L1 链 推导 L2 链 的 rollup 节点 组件(L1 区块 及其相关的 收据)。
TODO 删除此条目及其引用 — 可以用“推导过程”或“推导逻辑”代替,根据需要
L2 上的 预部署合约,可用于检索具有给定区块编号或给定区块哈希的 L1 区块的 L1 区块属性。
参见 L1 属性预部署合约规范
一个 32 字节的值,用作对 L2 链当前状态的承诺。
参见 提出 L2 输出承诺
一个 L1 合约,[排序器] 将 L2 输出根 发布到该合约。
TODO 扩展
验证者是在验证器模式下运行 rollup 节点 的实体(个人或组织)。
这样做可以带来许多类似于运行以太坊节点的好处,例如能够在本地模拟 L2 交易,而无需速率限制。
它还允许验证者通过重新推导 输出根 并将其与排序器提交的输出根进行比较来验证 [排序器] 的工作。如果存在不匹配,验证者可以执行 故障证明。
由 验证者 执行的链上交互式证明,证明 [排序器] 提供了错误的 输出根。
尚未指定故障证明。目前,查找有关故障证明的最佳位置是 Cannon 存储库。
TODO 扩展
在 L2 上,每 2 秒有一个区块(此持续时间称为 区块时间)。
我们说在 L2 genesis 区块 的时间戳之后,每 2 秒的倍数就有一个“时间槽”。
在 L1 上,在 [合并] 之后,时间槽为每 12 秒。但是,在出现甚至良性共识问题的情况下,可能不会为每个时间槽产生 L1 区块。
L2 区块时间为 2 秒,这意味着在每个 2 秒 时间槽 处都有一个 L2 区块。
在 [合并] 之后,可以说 L1 区块时间为 12 秒,因为那是 L1 时间槽。但是,实际上,区块时间是可变的,因为某些时间槽可能会被跳过。
在合并之前,L1 区块时间是可变的,尽管平均为 13 秒。
不安全同步是 验证者 从 排序器 了解 不安全 L2 区块 的过程。
这些不安全区块稍后需要由 L1 链确认(通过 不安全区块合并)。
执行引擎负责执行区块中的交易并计算生成的状态根、收据根和区块哈希。
L1([合并] 后)和 L2 都有执行引擎。
在 L1 上,执行的区块可以来自 L1 区块同步;或者来自执行引擎新铸造的区块(使用来自 L1 mempool 的交易),应 L1 共识层的请求。
在 L2 上,执行的区块是执行引擎应 rollup 节点 的请求新铸造的,使用 从 L1 区块派生的 交易。
在这些规范中,“执行引擎”始终指 L2 执行引擎,除非另有说明。
<!-- 外部链接 -->
>- 原文链接: [github.com/ethereum-opti...](https://github.com/ethereum-optimism/optimism/blob/546fb2c7a5796b7fe50b0b7edc7666d3bd281d6f/specs/glossary.md)
>- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!