以太坊协议的未来可能性 - 第 5 部分:净化(The Purge)

进阶1/17/2025, 2:55:41 PM
本文探讨了以太坊面临的两大挑战:历史数据膨胀和协议复杂性增加。Vitalik 提出"The Purge"(净化)计划,旨在降低存储需求和简化协议,同时保持区块链永久性。计划聚焦于两个目标:历史记录和状态到期。历史记录到期通过分布式存储(如Torrent或Portal Network)解决节点存储压力,减轻单节点负担,同时维持数据可用性。状态到期则应对持续增长的状态问题,探讨自动过期机制,但面临效率和用户体验等挑战。文章展示了以太坊社区如何平衡永久性与可扩展性,确保长期发展。这些改进有望降低节点运行门槛,推动以太坊未来发展。

以太坊面临的挑战之一是,默认情况下,任何区块链协议的膨胀和复杂性都会随着时间的推移而增加。这发生在两个地方:

  • 历史数据:历史上任何时刻进行的任何交易和创建的任何帐户都需要由所有客户端永久存储,并由任何新客户端下载,从而完全同步到网络。这会导致客户端负载和同步时间随着时间的推移不断增加,即使链的容量保持不变。
  • 协议特点:添加新功能比删除旧功能容易得多,从而导致代码复杂性随着时间的推移而增加。

为了使以太坊能够长期维持下去,我们需要对这两种趋势施加强大的反压力, 随着时间的推移减少复杂性和膨胀。但与此同时,我们需要 保留使区块链变得伟大的关键属性之一:它们的持久性。你可以把一张 NFT、一张交易通话数据中的情书、或者一份包含 100 万美元的智能合约放在链上,进入一个洞穴十年,出来后发现它仍然在那里等待你阅读和交互。对于 DApp 而言,要想完全去中心化并删除升级密钥,它们需要确信其依赖项不会以破坏它们的方式升级——尤其是 Layer 1 本身。

The Purge (净化),2023 年路线图。

如果我们下定决心,在这两种需求之间取得平衡,并在保持连续性的同时最大限度地减少或扭转臃肿、复杂性和衰退,这是绝对可能的。生物体可以做到这一点:虽然大多数生物体会随着时间的流逝而衰老,但少数幸运儿却不会。即使是社会系统也可以拥有极长的寿命。在某些情况下,以太坊已经取得了成功:工作量证明消失了, SELFDESTRUCT(自毁)操作码基本消失了,信标链节点已经存储了最多六个月的旧数据。以更通用的方式为以太坊找出这条道路,并朝着长期稳定的最终结果前进,是以太坊长期可扩展性、技术可持续性甚至安全性的终极挑战。

The Purge(净化):主要目标

  • 通过减少或消除每个节点永久存储所有历史记录甚至最终状态的需要来降低客户端存储要求。
  • 通过消除不需要的功能,降低协议复杂性

在本文中

历史记录到期(History expiry)

它解决什么问题?

截至撰写本文时,完全同步的以太坊节点需要 大约 1.1 TB 的磁盘空间 执行客户端,再加上共识客户端的另外几百GB。其中绝大部分是历史记录:有关历史区块、交易和收据的数据,其中大部分是多年前的数据。这意味着即使 Gas 限制根本没有增加,节点的大小每年也会增加数百 GB。

它是什么,它是如何工作的?

历史存储问题的一个关键简化特证是,由于每个区块都通过哈希链接(和其他 结构)指向前一个区块,因此对当前达成共识就足以对历史达成共识。只要网络对最新区块达成共识,任何历史区块或交易或状态(账户余额、随机数、代码、存储)都可以由任何单个参与者提供以及 Merkle 证明,并且该证明允许其他任何人验证它的正确性。虽然共识是 N/2-of-N 信任模型,但历史是 N 中之 1(1-of-N) 的信任模型

这为我们如何存储历史记录提供了很多选择。一种自然的选择是每个节点仅存储一小部分数据的网络。这就是种子网络几十年来的运作方式:虽然网络总共存储和分发了数百万个文件,但每个参与者仅存储和分发其中的几个文件。也许与直觉相反,这种方法甚至不一定会降低数据的稳健性。 如果通过让节点运行更加经济实惠,我们可以建立一个拥有 100,000 个节点的网络,其中每个节点存储随机 10% 的历史记录,那么每条数据将被复制 10,000 次 - 与 10,000 个节点的复制因子完全相同-节点网络,每个节点存储所有内容。

如今,以太坊已经开始摆脱所有节点永久存储所有历史的模型。共识区块(即与权益证明共识相关的部分)仅存储约 6 个月。 Blob 仅存储约 18 天。 EIP-4444 旨在为历史区块和收据引入一年的存储期。长期目标是建立一个统一的时期(可能约为 18 天),在此期间每个节点负责存储所有内容,然后构建一个由以太坊节点组成的对等网络,以分布式方式存储旧数据。

纠删码(Erasure Codes)可用于提高鲁棒性,同时保持复制因子相同。事实上,Blob 已经进行了擦除编码,以支持数据可用性采样。最简单的解决方案很可能是重新使用这种纠删码,并将执行和共识块数据也放入 blob 中。

与现有研究有哪些联系?

还需要做什么,需要权衡什么?

剩下的主要工作包括构建和集成一个具体的分布式解决方案来存储历史记录——至少是执行历史记录,但最终还包括共识和 blob。最简单的解决方案是(i)简单地引入现有的 torrent 库,以及 (ii) 一个名为「Portal Network」的以太坊原生解决方案。一旦引入其中任何一个,我们就可以启用 EIP-4444。EIP-4444 本身不需要硬分叉,但它确实需要新的网络协议版本。因此,同时为所有客户端启用它是有价值的,否则将存在客户端连接到其他节点时出现故障的风险,这些节点期望下载完整的历史记录,但实际上却无法获取。

主要的权衡涉及我们如何努力提供“古老的”历史数据。最简单的解决方案是明天停止存储古代历史,并依赖现有的存档节点和各种集中式提供程序进行复制。这很容易,但这削弱了以太坊作为永久记录场所的地位。更困难但更安全的途径是首先构建并集成 torrent 网络,以分布式方式存储历史记录。在这里,“我们的努力程度”有两个维度:

  1. 我们如何努力确保最大的节点集确实存储了所有数据?
  2. 我们将历史记录存储深度集成到协议中?

对于(1),一种最偏执的方法是使用托管证明:实际上要求每个权益证明验证者存储一定比例的历史记录,并定期通过加密方式检查他们是否这样做。更温和的方法是为每个客户端存储的历史记录百分比设定一个自愿标准。

对于 (2),基本实现只涉及今天已经完成的工作:Portal 已经存储了包含整个以太坊历史的 ERA 文件。更彻底的实现将涉及实际将其连接到同步过程,这样,如果有人想要同步完整历史记录存储节点或存档节点,即使没有其他存档节点在线存在,他们也可以通过直接同步来实现来自门户网络。

它如何与路线图的其他部分交互?

如果我们想让节点运行或启动变得极其容易,那么减少历史存储需求可以说比无状态性更重要:在节点需要的 1.1 TB 中,约 300 GB 是状态,剩余的约 800 GB GB 已成为历史。只有在同时实现无状态性和 EIP-4444 的情况下,以太坊节点在智能手表上运行且只需几分钟即可设置的愿景才能实现。

限制历史存储还使较新的以太坊节点实现能更容易地仅支持协议的最新版本,从而简化它们的结构。例如,由于 2016 年 DoS 攻击期间创建的空存储槽已全部清除,现在可以安全地删除大量相关代码。同样,随着以太坊转向权益证明成为历史,客户端可以安全地移除所有与工作量证明相关的代码。

状态到期(State expiry)

它解决什么问题?

即使我们消除了客户端存储历史记录的需求,客户端的存储需求仍将继续增长,每年约 50 GB,因为状态持续增长:账户余额和随机数、合约代码和合约存储。用户可以支付一次性费用,永远给现在和未来的以太坊客户端带来负担。

状态比历史更难“过期”,因为 EVM 从根本上是围绕这样的假设设计的:一旦创建了状态对象,它就会始终存在,并且可以随时被任何事务读取。如果我们引入无状态性,有一种观点认为这个问题也许并没有那么糟糕:只有一类专门的区块构建器需要实际存储状态,而所有其他节点(甚至 包含列表 生产!)可以无状态运行。然而,有一种观点认为,我们不想过分依赖无状态性最终我们可能希望让状态过期以保持以太坊的去中心化。

它是什么,它是如何工作的?

今天,当您创建一个新的状态对象时(可以通过以下三种方式之一发生:(i)将 ETH 发送到新帐户,(ii)使用代码创建新帐户,(iii)设置以前未触及的存储槽) ,该状态对象永远处于该状态。相反,我们想要的是对象随着时间的推移自动过期。关键的挑战是以实现三个目标的方式做到这一点:

  1. 效率:不需要大量的额外计算来运行到期过程
  2. 用户友好性:如果有人进入洞穴五年然后回来,他们不应该失去对 ETH、ERC20、NFT、CDP 头寸的访问权……
  3. 开发者友好性:开发人员不必切换到完全陌生的思维模型。此外,目前已经僵化且不更新的应用程序应该可以继续正常运行。

在不满足这些目标的情况下,解决问题反而变得简单。例如,我们可以让每个状态对象存储一个表示其到期日期的计数器(通过销毁 ETH 可以延长过期日期,这可以在读取或写入时自动进行),并设置一个循环来「遍历状态」并删除过期的状态对象。然而,这种方法会引入额外的计算开销(甚至增加存储需求),而且显然无法满足用户友好性的要求。对于开发人员来说,处理存储值偶尔重置为零的边缘情况也会变得困难。如果在整个合约范围内设置到期计时器,虽然在技术上简化了开发人员的工作,但在经济上却变得更加棘手:开发人员必须考虑如何将持续的存储成本「转嫁」给用户。

这些都是以太坊核心开发社区多年来一直在努力解决的问题,包括 “区块链租金” 和 “再生(Regenesis)” 等提案。最终,我们结合了提案中最好的部分,并集中在两类“已知最不糟糕的解决方案”上:

  • 部分状态过期解决方案
  • 基于地址周期的状态到期建议。

部分状态到期

部分状态到期提案都遵循相同的原则。我们将状态分成块。每个人都永久存储“顶层映射”,其中块为空或非空。数据 之内 仅当最近访问过该数据时才存储每个块。有一种“复活”机制,如果不再存储某个块,任何人都可以通过提供数据内容的证明来恢复该数据。

这些提案的主要区别在于:(i)如何定义”最近”,以及(ii)如何定义”大数据块”。一个具体的提案是EIP-7736,它基于为 Verkle 树引入的“茎叶”设计(尽管与任何形式的无状态树兼容,如二叉树)。在这种设计中,相邻的头部、代码和存储槽存储在同一个”茎”下。”茎”下存储的数据最多为 7936 字节(256 * 31)。通常,一个账户的整个头部、代码以及多个关键存储槽都会存储在同一个”茎”下。如果某个”茎”下的数据在 6 个月内未被读取或写入,该数据将不再存储,而只保留一个 32 字节的承诺(”存根”)。未来访问这些数据的交易需要”复活”数据,并提供基于”存根”验证的证明。

还有其他实现类似想法的方法。例如,如果账户级别的粒度不够精细,我们可以设计一个方案,将”树”的每个”2^-32”部分都用类似的”茎和叶”机制来管理。

由于激励因素,这变得更加棘手:攻击者可以通过将大量数据放入单个子树并每年发送单个交易来“更新树”,从而迫使客户端永久存储大量状态。如果您使更新成本与树大小成正比(或更新持续时间成反比),那么有人可能会通过将大量数据放入与他们相同的子树中来伤害其他用户。人们可以尝试通过根据子树大小动态调整粒度来限制这两个问题:例如,每个连续的 216 = 65536 个状态对象可以被视为一个“组”。然而,这些想法更为复杂;基于“茎”的方法很简单,并且可以调整激励措施,因为通常“茎”下的所有数据都与同一应用程序或用户相关。

基于地址周期的状态到期建议

如果我们想完全避免任何永久性的状态增长,甚至是 32 字节的「存根」,该怎么办?这是一个棘手的问题,主要是因为复活冲突(Resurrection Conflicts)。设想这样一个场景:一个状态对象被删除后,EVM 执行将另一个状态对象放在相同位置。然而,之后有人想恢复原始状态对象,我们该如何处理?在部分状态到期的情况下,「存根」可以阻止创建新数据。但在完全状态到期时,我们连「存根」都无法存储。

基于地址周期的设计是解决此问题的最佳方法。我们不再使用单一状态树存储整个状态,而是维护一个不断增长的状态树列表。任何读取或写入的状态都会保存在最新的状态树中。每个周期(比如:1 年)都会添加一个新的空状态树。旧状态树保持不变。完整节点只需存储最近的两棵状态树。如果一个状态对象在两个周期内未被访问,从而落入过期状态树,它仍然可以被读取或写入。但这时交易需要提供该对象的 Merkle 证明。一旦证明有效,该对象的副本将再次保存在最新的状态树中。

地址周期的概念是使这一切对用户和开发人员都友好的关键思想。地址周期是地址中的一个数字部分。核心规则是:地址周期为 N 的地址只能在周期 N 或之后(即当状态树列表达到长度 N 时)被读取或写入。当用户需要保存新的状态对象(如新合约或新的 ERC20 余额)时,只要确保将状态对象放入地址周期为 N 或 N-1 的合约中,就可以立即保存,无需提供证明之前不存在任何内容。然而,对旧地址周期中的状态进行任何添加或编辑都需要提供证明。

这种设计保留了以太坊当前的大部分属性,不需要额外的计算,允许几乎像现在一样编写应用程序(ERC20 需要重写,以确保地址周期为 N 的地址余额存储在本身具有地址周期为 N 的子合约中),解决了“用户进山洞五年”的问题。然而,它有一个大问题: 地址需要扩展到 20 个字节以上才能适应地址周期。

地址空间扩展

一项建议是引入一种新的 32 字节地址格式,其中包括版本号、地址周期号和扩展散列。

0x01000000000157aE408398dF7E5f4552091A69125d5dFcb7B8C2659029395bdF

红色的是版本号。这里橙色的四个零旨在作为空白空间,将来可以容纳分片编号。绿色是地址周期数。蓝色是 26 字节的哈希值。

这里的关键挑战是向后兼容性。现有合约是围绕 20 字节地址设计的,并且通常使用严格的字节打包技术,明确假设地址正好是 20 字节长。 解决这个问题的一个想法是使用一个转换映射,其中与新式地址交互的旧式合约将看到新式地址的 20 字节哈希。然而,要确保这一点的安全性,存在着很大的复杂性。

地址空间收缩

另一种方法则相反:我们立即禁止某些 2128- 大小的地址子范围(例如,以 0xffffffff 0xffffffff),然后使用该范围引入带有地址周期和 14 字节哈希值的地址。

0xfffffff000169125d5dFcb7B8C2659029395bdF

这种方法做出的主要牺牲是,它为反事实地址引入了安全风险:持有资产或权限,但代码尚未发布到链上的地址。风险涉及有人创建一个地址,该地址声称拥有一段(尚未发布)代码,但也有另一段有效的代码散列到同一地址。计算这样的碰撞目前需要280个哈希值;地址空间收缩会将这个数字减少到易于访问的 256 个哈希值。

关键风险领域是反事实地址,这些地址不由单个所有者持有。虽然这种情况在当前相对罕见,但随着我们进入多 L2 世界,它可能变得更加普遍。解决这个问题的唯一方法是接受这种风险,同时识别所有可能出现问题的常见用例,并为它们制定有效的缓解策略。

与现有研究有哪些联系?

还需要做什么,需要权衡什么?

我认为未来有四种可行的道路:

  • 我们实行无状态,并且不引入状态到期。状态在不断增长(尽管增长缓慢:几十年内我们可能不会看到它超过 8 TB),但只需要由相对专业的用户类别持有:甚至 PoS 验证器也不需要状态。

包含列表生成是需要访问部分状态的一项功能,但我们可以通过去中心化的方式实现:每个用户负责维护状态树中包含自己账户的部分。用户广播交易时,会同时广播验证步骤中所访问状态对象的证明(适用于 EOA 和 ERC-4337 账户)。无状态验证器随后可以将这些证明组合,生成完整的包含列表证明。

  • 我们实施部分状态到期,并接受一个低得多但仍然非零的永久状态规模增长率。这一结果可以说类似于涉及对等网络的历史到期提案——如何接受一个低得多但仍然非零的永久历史存储增长率,因为每个客户端必须存储一个较低但固定百分比的历史数据。
  • 我们使用地址空间扩展来进行状态到期。这将涉及一个多年的过程,以确保地址格式转换方法有效且安全,包括现有应用程序。
  • 我们使用地址空间收缩来进行状态到期。这将涉及一个多年的过程,以确保所有涉及地址冲突的安全风险(包括跨链情况)都得到处理。

重要的一点是,无论是否实施依赖于地址格式更改的状态到期方案,最终都必须解决有关地址空间扩展和收缩的难题。今天,大约需要 280 哈希值来生成地址冲突,对于资源极其丰富的参与者来说,这种计算负载已经是可行的:GPU 可以进行大约 227 哈希值运算,因此运行一年可以计算 252 次,因此世界上所有约“2 的 30 次方”个 GPU 都可以在 约 1/4 年的时间内计算一次碰撞,而 FPGA 和 ASIC 可以进一步加速这一过程。在未来,此类攻击将会向越来越多的人开放。因此,实现完全状态到期的实际成本可能没有看起来那么高,因为无论如何我们都必须解决这个非常具有挑战性的地址问题。

它如何与路线图的其他部分交互?

进行状态过期可能会使从一种状态树格式到另一种状态树格式的转换变得更容易,因为不需要转换过程:您可以简单地开始使用新格式创建新树,然后执行硬分叉来转换旧树。因此,虽然状态到期很复杂,但它确实有利于简化路线图的其他方面。

功能清理(Feature cleanup)

它解决什么问题?

安全性、可访问性和可用性的关键先决条件之一 可信的中立性 是简单。如果协议美观且简单,就会减少出现错误的可能性。它增加了新开发人员能够参与其中的任何部分的机会。它更有可能是公平的,也更容易抵御特殊利益。不幸的是,协议就像任何社交系统一样,默认情况下会随着时间的推移而变得更加复杂。如果我们不希望以太坊陷入日益复杂的黑洞,我们需要做以下两件事之一:(i)停止进行更改并使协议僵化, (ii) 能够实际删除功能并降低复杂性。一种中间路线,即对协议进行较少的更改,并且随着时间的推移至少消除一点复杂性,这也是可能的做到的。本节将讨论如何减少或消除复杂性。

它是什么,它是如何工作的?

没有任何重大的单一修复可以降低协议的复杂性;这个问题的本质是有许多小的解决办法。

一个基本已经完成的示例是删除 SELFDESTRUCT 操作码。 SELFDESTRUCT 操作码是唯一可以修改单个块内无限数量存储槽的操作码,要求客户端实现显着更高的复杂性以避免 DoS 攻击。该操作码的最初目的是实现自愿状态清算,从而允许状态大小随着时间的推移而减小。实际上,很少有人最终使用它。在 Dencun 硬分叉中,该操作码被削弱为仅允许在同一交易中创建的自毁账户。这解决了 DoS 问题,并允许显著简化客户端代码。 未来,最终完全删除该操作码可能是有意义的。

迄今为止,已确定了一些关键的协议简化机会。首先,让我们看看 EVM 之外的例子。这些变更相对非侵入性,因此更容易达成共识并在短期内实施。

  • RLP → SSZ 转变:最初,以太坊使用一种称为 RLP的编码进行序列化。 RLP 是无类型的,而且没有必要那么复杂。如今,信标链使用 SSZ, 它在很多方面都明显更好,包括不仅支持序列化,还支持哈希。最终,我们希望完全摆脱 RLP,并将所有数据类型转移到 SSZ 结构中,这反过来会使升级变得更加容易。为此提出的当前 EIP 包括 [1] [2] [3]
  • 删除旧的交易类型:当今的交易类型太多,其中许多可能会被删除。完全删除的一个更温和的替代方案是帐户抽象功能,智能帐户可以通过该功能包含处理和验证旧式交易的代码(如果他们愿意的话)。
  • 日志(LOG)改革:日志创建了 Bloom 过滤器和其他逻辑,增加了协议的复杂性,但实际上并没有被客户端使用,因为它太慢了。我们可以 删除这些功能,而是将精力投入替代方案,例如使用 SNARK 等现代技术的协议外去中心化日志读取工具。
  • 最终取消信标链同步委员会机制:同步委员会机制最初是为了实现以太坊的轻客户端验证而引入的。然而,它增加了协议的复杂性。最终,我们将能够使用 SNARK 直接验证以太坊共识层,这将消除对专用轻客户端验证协议的需求。通过创建更「原生」的轻客户端协议(涉及验证来自以太坊共识验证器随机子集的签名),或许共识的改变可以使我们更早地取消同步委员会。
  • 数据格式统一:目前,执行状态存储在 Merkle Patricia 树中,共识状态存储在 SSZ 树中,而 Blob 则通过 KZG 承诺进行承诺。未来,为区块数据和状态创建单一的统一格式是有意义的。这些格式将满足所有重要需求:(i)无状态客户端的简单证明,(ii)数据的序列化和擦除编码,(iii)标准化数据结构。
  • 取消信标链委员会:该机制最初是为了支持特定版本的执行分片而引入的。相反,我们最终通过 L2 和 blob 进行分片。因此,委员会是不必要的,我们正在进行取消委员会的行动
  • 删除混合字节序:EVM 是大字节序,而共识层是小字节序。重新协调并使所有内容都采用大字节序或小字节序可能是有意义的(可能是大字节序,因为 EVM 更难更改)。

以下是 目前 EVM 中的一些示例:

  • 简化 Gas 机制:当前的 Gas 规则未能充分优化,无法准确限制验证区块所需的资源量。主要问题包括:(i)存储读/写成本,虽然旨在限制区块中的读/写次数,但目前设定较为随意;(ii)内存填充规则,使 EVM 的最大内存消耗难以估算。为解决这些问题,建议采取以下措施:实施无状态 Gas 成本变化,将所有存储相关成本统一为一个简单公式;同时引入新的内存定价提案
  • 删除预编译:以太坊今天拥有的许多预编译都不必要地复杂且相对未使用,并且在几乎没有被任何应用程序使用的情况下构成了共识失败的很大一部分。处理这个问题的两种方法是(i)仅删除预编译,以及(ii)用实现相同逻辑的(不可避免地更昂贵的)EVM 代码片段替换它。此 EIP 草案提议首先对身份预编译执行此操作;随后,RIPEMD160、MODEXP 和 BLAKE 可能会被移除。
  • 取消 Gas 可观察性:使 EVM 执行不再能够看到剩余的 Gas 量。这将破坏一些应用程序(最明显的是赞助交易),但将使未来升级更加容易(例如,升级到更高级的多维 Gas 版本)。EOF 规范 已经使 Gas 变得不可观察,但为了简化协议,EOF 需要成为强制性的。
  • 静态分析的改进:如今 EVM 代码很难进行静态分析,特别是因为跳转可能是动态的。这也使得优化 EVM 实现(将 EVM 代码预编译为其他语言)变得更加困难。我们可以通过删除动态跳转(或使其更加昂贵,例如,Gas 成本与合约中 JUMPDEST 的总数成线性关系)来解决这个问题。EOF 可以做到这一点,但要从中获得协议简化的好处,则需要强制执行 EOF。

与现有研究有哪些联系?

还需要做什么,需要权衡什么?

进行此类功能简化的主要权衡在于(i)我们简化的程度和速度与(ii)向后兼容性之间的平衡。以太坊作为一条链的价值源于它是一个平台,用户可以在其中部署应用程序,并确信这些应用在多年后仍能正常运行。然而,这种理想也可能被过分强调。借用William Jennings Bryan 的话,我们不应”将以太坊钉在向后兼容性的十字架上”。设想一个场景:如果整个以太坊生态系统中只有两个应用程序在使用某个特定功能,其中一个多年来没有用户,几乎完全闲置,而且这两个应用的总价值仅为 57 美元。在这种情况下,我们应该考虑删除该功能,必要时甚至可以自掏腰包向受影响的用户补偿这 57 美元。

更广泛的社会问题在于创建一个标准化的管道来进行非紧急的向后兼容性破坏的更改。解决这个问题的一种方法是检查和扩展现有的先例,例如自毁过程。该流程看起来如下:

  • 步骤一: 开始讨论删除功能 X
  • 步骤2: 进行分析以确定移除 X 对应用程序造成的影响,根据结果:(i) 放弃这个想法,(ii)按计划进行,或(iii)找到一种修改后的「破坏性最小」的方法来移除 X,并继续进行
  • 步骤3: 制定正式的EIP来弃用 X。确保流行的高级基础设施(例如编程语言、钱包)尊重这一点并停止使用该功能。
  • 第四步:最后, 实际删除 X

在第 1 步和第 4 步之间应该有一个持续数年的流程,并明确标识每个项目所处的步骤。此时,我们需要权衡”功能移除流程的力度和速度”与”采取更保守的方法并将更多资源投入协议开发的其他领域”。尽管如此,我们距离”帕累托前沿(Pareto frontier)”还有相当长的距离。

EOF

对 EVM 提出的一系列主要更改是 EVM 对象格式 (EOF)。 EOF引入了大量的改变,例如禁止gas可观察性、代码可观察性(即无CODECOPY)、仅允许静态跳转。目标是允许 EVM 以具有更强属性的方式进行更多升级,同时保持向后兼容性(因为 EOF 之前的 EVM 仍然存在)。

这样做的优点是,它创建了一条添加新 EVM 功能的自然路径,并鼓励迁移到具有更强保证的更严格的 EVM。它的缺点是它显着 增加 协议复杂性,除非我们能找到一种方法最终弃用并删除旧的 EVM。一个主要问题是: EOF 在 EVM 简化提案中发挥什么作用,特别是如果目标是降低整个 EVM 的复杂性?

它如何与路线图的其他部分交互?

路线图其余部分中的许多“改进”建议也是对旧功能进行简化的机会。重复上面的一些例子:

  • 切换到单槽最终性使我们有机会取消委员会、重新设计经济学并进行其他与权益证明相关的简化。
  • 完全实现账户抽象可以让我们删除大量现有的交易处理逻辑,将其移至所有 EOA 都可以替换的“默认账户 EVM 代码”中。
  • 如果我们将以太坊状态转移到二进制哈希树,这可以与新版本的 SSZ 协调一致,以便所有以太坊数据结构都可以以相同的方式进行哈希处理。

更激进的方法:将协议的大部分内容转化为合约代码

一个更激进的以太坊简化策略是保持协议不变,但将其大部分从协议功能转移到合约代码。

最激进的方案是将以太坊 L1 “技术上”简化为信标链,并引入一个精简的虚拟机(VM)。这可以是RISC-VCairo,或专为证明系统设计的更简单 VM。这种设计将允许开发者创建自己的 Rollup,而 EVM 将成为这些 Rollups 中的首个实例。有趣的是,这一方案与2019-20 年提出的执行环境方案殊途同归,尽管 SNARK 技术的进步使得这一设想更易实现。

一种更温和的方法是,保持信标链和当前以太坊执行环境之间的关系不变,但对 EVM 进行就地交换。我们可以选择 RISC-V、Cairo 或其他 VM 作为新的“官方以太坊 VM”,然后将所有 EVM 合约强制转换为解释原始代码逻辑的新 VM 代码(通过编译或解释)。理论上来说,甚至可以将这个”目标 VM”作为 EOF 的一个版本来实现。

免责声明:

  1. 本文转载自【Vitalik Buterin】,所有版权归原作者所有【Vitalik Buterin】。若对本次转载有异议,请联系 Gate Learn 团队,他们会及时处理。
  2. 免责声明:本文所表达的观点和意见仅代表作者个人观点,不构成任何投资建议。
  3. Gate Learn 团队将文章翻译成其他语言。除非另有说明,否则禁止复制、分发或抄袭翻译文章。

以太坊协议的未来可能性 - 第 5 部分:净化(The Purge)

进阶1/17/2025, 2:55:41 PM
本文探讨了以太坊面临的两大挑战:历史数据膨胀和协议复杂性增加。Vitalik 提出"The Purge"(净化)计划,旨在降低存储需求和简化协议,同时保持区块链永久性。计划聚焦于两个目标:历史记录和状态到期。历史记录到期通过分布式存储(如Torrent或Portal Network)解决节点存储压力,减轻单节点负担,同时维持数据可用性。状态到期则应对持续增长的状态问题,探讨自动过期机制,但面临效率和用户体验等挑战。文章展示了以太坊社区如何平衡永久性与可扩展性,确保长期发展。这些改进有望降低节点运行门槛,推动以太坊未来发展。

以太坊面临的挑战之一是,默认情况下,任何区块链协议的膨胀和复杂性都会随着时间的推移而增加。这发生在两个地方:

  • 历史数据:历史上任何时刻进行的任何交易和创建的任何帐户都需要由所有客户端永久存储,并由任何新客户端下载,从而完全同步到网络。这会导致客户端负载和同步时间随着时间的推移不断增加,即使链的容量保持不变。
  • 协议特点:添加新功能比删除旧功能容易得多,从而导致代码复杂性随着时间的推移而增加。

为了使以太坊能够长期维持下去,我们需要对这两种趋势施加强大的反压力, 随着时间的推移减少复杂性和膨胀。但与此同时,我们需要 保留使区块链变得伟大的关键属性之一:它们的持久性。你可以把一张 NFT、一张交易通话数据中的情书、或者一份包含 100 万美元的智能合约放在链上,进入一个洞穴十年,出来后发现它仍然在那里等待你阅读和交互。对于 DApp 而言,要想完全去中心化并删除升级密钥,它们需要确信其依赖项不会以破坏它们的方式升级——尤其是 Layer 1 本身。

The Purge (净化),2023 年路线图。

如果我们下定决心,在这两种需求之间取得平衡,并在保持连续性的同时最大限度地减少或扭转臃肿、复杂性和衰退,这是绝对可能的。生物体可以做到这一点:虽然大多数生物体会随着时间的流逝而衰老,但少数幸运儿却不会。即使是社会系统也可以拥有极长的寿命。在某些情况下,以太坊已经取得了成功:工作量证明消失了, SELFDESTRUCT(自毁)操作码基本消失了,信标链节点已经存储了最多六个月的旧数据。以更通用的方式为以太坊找出这条道路,并朝着长期稳定的最终结果前进,是以太坊长期可扩展性、技术可持续性甚至安全性的终极挑战。

The Purge(净化):主要目标

  • 通过减少或消除每个节点永久存储所有历史记录甚至最终状态的需要来降低客户端存储要求。
  • 通过消除不需要的功能,降低协议复杂性

在本文中

历史记录到期(History expiry)

它解决什么问题?

截至撰写本文时,完全同步的以太坊节点需要 大约 1.1 TB 的磁盘空间 执行客户端,再加上共识客户端的另外几百GB。其中绝大部分是历史记录:有关历史区块、交易和收据的数据,其中大部分是多年前的数据。这意味着即使 Gas 限制根本没有增加,节点的大小每年也会增加数百 GB。

它是什么,它是如何工作的?

历史存储问题的一个关键简化特证是,由于每个区块都通过哈希链接(和其他 结构)指向前一个区块,因此对当前达成共识就足以对历史达成共识。只要网络对最新区块达成共识,任何历史区块或交易或状态(账户余额、随机数、代码、存储)都可以由任何单个参与者提供以及 Merkle 证明,并且该证明允许其他任何人验证它的正确性。虽然共识是 N/2-of-N 信任模型,但历史是 N 中之 1(1-of-N) 的信任模型

这为我们如何存储历史记录提供了很多选择。一种自然的选择是每个节点仅存储一小部分数据的网络。这就是种子网络几十年来的运作方式:虽然网络总共存储和分发了数百万个文件,但每个参与者仅存储和分发其中的几个文件。也许与直觉相反,这种方法甚至不一定会降低数据的稳健性。 如果通过让节点运行更加经济实惠,我们可以建立一个拥有 100,000 个节点的网络,其中每个节点存储随机 10% 的历史记录,那么每条数据将被复制 10,000 次 - 与 10,000 个节点的复制因子完全相同-节点网络,每个节点存储所有内容。

如今,以太坊已经开始摆脱所有节点永久存储所有历史的模型。共识区块(即与权益证明共识相关的部分)仅存储约 6 个月。 Blob 仅存储约 18 天。 EIP-4444 旨在为历史区块和收据引入一年的存储期。长期目标是建立一个统一的时期(可能约为 18 天),在此期间每个节点负责存储所有内容,然后构建一个由以太坊节点组成的对等网络,以分布式方式存储旧数据。

纠删码(Erasure Codes)可用于提高鲁棒性,同时保持复制因子相同。事实上,Blob 已经进行了擦除编码,以支持数据可用性采样。最简单的解决方案很可能是重新使用这种纠删码,并将执行和共识块数据也放入 blob 中。

与现有研究有哪些联系?

还需要做什么,需要权衡什么?

剩下的主要工作包括构建和集成一个具体的分布式解决方案来存储历史记录——至少是执行历史记录,但最终还包括共识和 blob。最简单的解决方案是(i)简单地引入现有的 torrent 库,以及 (ii) 一个名为「Portal Network」的以太坊原生解决方案。一旦引入其中任何一个,我们就可以启用 EIP-4444。EIP-4444 本身不需要硬分叉,但它确实需要新的网络协议版本。因此,同时为所有客户端启用它是有价值的,否则将存在客户端连接到其他节点时出现故障的风险,这些节点期望下载完整的历史记录,但实际上却无法获取。

主要的权衡涉及我们如何努力提供“古老的”历史数据。最简单的解决方案是明天停止存储古代历史,并依赖现有的存档节点和各种集中式提供程序进行复制。这很容易,但这削弱了以太坊作为永久记录场所的地位。更困难但更安全的途径是首先构建并集成 torrent 网络,以分布式方式存储历史记录。在这里,“我们的努力程度”有两个维度:

  1. 我们如何努力确保最大的节点集确实存储了所有数据?
  2. 我们将历史记录存储深度集成到协议中?

对于(1),一种最偏执的方法是使用托管证明:实际上要求每个权益证明验证者存储一定比例的历史记录,并定期通过加密方式检查他们是否这样做。更温和的方法是为每个客户端存储的历史记录百分比设定一个自愿标准。

对于 (2),基本实现只涉及今天已经完成的工作:Portal 已经存储了包含整个以太坊历史的 ERA 文件。更彻底的实现将涉及实际将其连接到同步过程,这样,如果有人想要同步完整历史记录存储节点或存档节点,即使没有其他存档节点在线存在,他们也可以通过直接同步来实现来自门户网络。

它如何与路线图的其他部分交互?

如果我们想让节点运行或启动变得极其容易,那么减少历史存储需求可以说比无状态性更重要:在节点需要的 1.1 TB 中,约 300 GB 是状态,剩余的约 800 GB GB 已成为历史。只有在同时实现无状态性和 EIP-4444 的情况下,以太坊节点在智能手表上运行且只需几分钟即可设置的愿景才能实现。

限制历史存储还使较新的以太坊节点实现能更容易地仅支持协议的最新版本,从而简化它们的结构。例如,由于 2016 年 DoS 攻击期间创建的空存储槽已全部清除,现在可以安全地删除大量相关代码。同样,随着以太坊转向权益证明成为历史,客户端可以安全地移除所有与工作量证明相关的代码。

状态到期(State expiry)

它解决什么问题?

即使我们消除了客户端存储历史记录的需求,客户端的存储需求仍将继续增长,每年约 50 GB,因为状态持续增长:账户余额和随机数、合约代码和合约存储。用户可以支付一次性费用,永远给现在和未来的以太坊客户端带来负担。

状态比历史更难“过期”,因为 EVM 从根本上是围绕这样的假设设计的:一旦创建了状态对象,它就会始终存在,并且可以随时被任何事务读取。如果我们引入无状态性,有一种观点认为这个问题也许并没有那么糟糕:只有一类专门的区块构建器需要实际存储状态,而所有其他节点(甚至 包含列表 生产!)可以无状态运行。然而,有一种观点认为,我们不想过分依赖无状态性最终我们可能希望让状态过期以保持以太坊的去中心化。

它是什么,它是如何工作的?

今天,当您创建一个新的状态对象时(可以通过以下三种方式之一发生:(i)将 ETH 发送到新帐户,(ii)使用代码创建新帐户,(iii)设置以前未触及的存储槽) ,该状态对象永远处于该状态。相反,我们想要的是对象随着时间的推移自动过期。关键的挑战是以实现三个目标的方式做到这一点:

  1. 效率:不需要大量的额外计算来运行到期过程
  2. 用户友好性:如果有人进入洞穴五年然后回来,他们不应该失去对 ETH、ERC20、NFT、CDP 头寸的访问权……
  3. 开发者友好性:开发人员不必切换到完全陌生的思维模型。此外,目前已经僵化且不更新的应用程序应该可以继续正常运行。

在不满足这些目标的情况下,解决问题反而变得简单。例如,我们可以让每个状态对象存储一个表示其到期日期的计数器(通过销毁 ETH 可以延长过期日期,这可以在读取或写入时自动进行),并设置一个循环来「遍历状态」并删除过期的状态对象。然而,这种方法会引入额外的计算开销(甚至增加存储需求),而且显然无法满足用户友好性的要求。对于开发人员来说,处理存储值偶尔重置为零的边缘情况也会变得困难。如果在整个合约范围内设置到期计时器,虽然在技术上简化了开发人员的工作,但在经济上却变得更加棘手:开发人员必须考虑如何将持续的存储成本「转嫁」给用户。

这些都是以太坊核心开发社区多年来一直在努力解决的问题,包括 “区块链租金” 和 “再生(Regenesis)” 等提案。最终,我们结合了提案中最好的部分,并集中在两类“已知最不糟糕的解决方案”上:

  • 部分状态过期解决方案
  • 基于地址周期的状态到期建议。

部分状态到期

部分状态到期提案都遵循相同的原则。我们将状态分成块。每个人都永久存储“顶层映射”,其中块为空或非空。数据 之内 仅当最近访问过该数据时才存储每个块。有一种“复活”机制,如果不再存储某个块,任何人都可以通过提供数据内容的证明来恢复该数据。

这些提案的主要区别在于:(i)如何定义”最近”,以及(ii)如何定义”大数据块”。一个具体的提案是EIP-7736,它基于为 Verkle 树引入的“茎叶”设计(尽管与任何形式的无状态树兼容,如二叉树)。在这种设计中,相邻的头部、代码和存储槽存储在同一个”茎”下。”茎”下存储的数据最多为 7936 字节(256 * 31)。通常,一个账户的整个头部、代码以及多个关键存储槽都会存储在同一个”茎”下。如果某个”茎”下的数据在 6 个月内未被读取或写入,该数据将不再存储,而只保留一个 32 字节的承诺(”存根”)。未来访问这些数据的交易需要”复活”数据,并提供基于”存根”验证的证明。

还有其他实现类似想法的方法。例如,如果账户级别的粒度不够精细,我们可以设计一个方案,将”树”的每个”2^-32”部分都用类似的”茎和叶”机制来管理。

由于激励因素,这变得更加棘手:攻击者可以通过将大量数据放入单个子树并每年发送单个交易来“更新树”,从而迫使客户端永久存储大量状态。如果您使更新成本与树大小成正比(或更新持续时间成反比),那么有人可能会通过将大量数据放入与他们相同的子树中来伤害其他用户。人们可以尝试通过根据子树大小动态调整粒度来限制这两个问题:例如,每个连续的 216 = 65536 个状态对象可以被视为一个“组”。然而,这些想法更为复杂;基于“茎”的方法很简单,并且可以调整激励措施,因为通常“茎”下的所有数据都与同一应用程序或用户相关。

基于地址周期的状态到期建议

如果我们想完全避免任何永久性的状态增长,甚至是 32 字节的「存根」,该怎么办?这是一个棘手的问题,主要是因为复活冲突(Resurrection Conflicts)。设想这样一个场景:一个状态对象被删除后,EVM 执行将另一个状态对象放在相同位置。然而,之后有人想恢复原始状态对象,我们该如何处理?在部分状态到期的情况下,「存根」可以阻止创建新数据。但在完全状态到期时,我们连「存根」都无法存储。

基于地址周期的设计是解决此问题的最佳方法。我们不再使用单一状态树存储整个状态,而是维护一个不断增长的状态树列表。任何读取或写入的状态都会保存在最新的状态树中。每个周期(比如:1 年)都会添加一个新的空状态树。旧状态树保持不变。完整节点只需存储最近的两棵状态树。如果一个状态对象在两个周期内未被访问,从而落入过期状态树,它仍然可以被读取或写入。但这时交易需要提供该对象的 Merkle 证明。一旦证明有效,该对象的副本将再次保存在最新的状态树中。

地址周期的概念是使这一切对用户和开发人员都友好的关键思想。地址周期是地址中的一个数字部分。核心规则是:地址周期为 N 的地址只能在周期 N 或之后(即当状态树列表达到长度 N 时)被读取或写入。当用户需要保存新的状态对象(如新合约或新的 ERC20 余额)时,只要确保将状态对象放入地址周期为 N 或 N-1 的合约中,就可以立即保存,无需提供证明之前不存在任何内容。然而,对旧地址周期中的状态进行任何添加或编辑都需要提供证明。

这种设计保留了以太坊当前的大部分属性,不需要额外的计算,允许几乎像现在一样编写应用程序(ERC20 需要重写,以确保地址周期为 N 的地址余额存储在本身具有地址周期为 N 的子合约中),解决了“用户进山洞五年”的问题。然而,它有一个大问题: 地址需要扩展到 20 个字节以上才能适应地址周期。

地址空间扩展

一项建议是引入一种新的 32 字节地址格式,其中包括版本号、地址周期号和扩展散列。

0x01000000000157aE408398dF7E5f4552091A69125d5dFcb7B8C2659029395bdF

红色的是版本号。这里橙色的四个零旨在作为空白空间,将来可以容纳分片编号。绿色是地址周期数。蓝色是 26 字节的哈希值。

这里的关键挑战是向后兼容性。现有合约是围绕 20 字节地址设计的,并且通常使用严格的字节打包技术,明确假设地址正好是 20 字节长。 解决这个问题的一个想法是使用一个转换映射,其中与新式地址交互的旧式合约将看到新式地址的 20 字节哈希。然而,要确保这一点的安全性,存在着很大的复杂性。

地址空间收缩

另一种方法则相反:我们立即禁止某些 2128- 大小的地址子范围(例如,以 0xffffffff 0xffffffff),然后使用该范围引入带有地址周期和 14 字节哈希值的地址。

0xfffffff000169125d5dFcb7B8C2659029395bdF

这种方法做出的主要牺牲是,它为反事实地址引入了安全风险:持有资产或权限,但代码尚未发布到链上的地址。风险涉及有人创建一个地址,该地址声称拥有一段(尚未发布)代码,但也有另一段有效的代码散列到同一地址。计算这样的碰撞目前需要280个哈希值;地址空间收缩会将这个数字减少到易于访问的 256 个哈希值。

关键风险领域是反事实地址,这些地址不由单个所有者持有。虽然这种情况在当前相对罕见,但随着我们进入多 L2 世界,它可能变得更加普遍。解决这个问题的唯一方法是接受这种风险,同时识别所有可能出现问题的常见用例,并为它们制定有效的缓解策略。

与现有研究有哪些联系?

还需要做什么,需要权衡什么?

我认为未来有四种可行的道路:

  • 我们实行无状态,并且不引入状态到期。状态在不断增长(尽管增长缓慢:几十年内我们可能不会看到它超过 8 TB),但只需要由相对专业的用户类别持有:甚至 PoS 验证器也不需要状态。

包含列表生成是需要访问部分状态的一项功能,但我们可以通过去中心化的方式实现:每个用户负责维护状态树中包含自己账户的部分。用户广播交易时,会同时广播验证步骤中所访问状态对象的证明(适用于 EOA 和 ERC-4337 账户)。无状态验证器随后可以将这些证明组合,生成完整的包含列表证明。

  • 我们实施部分状态到期,并接受一个低得多但仍然非零的永久状态规模增长率。这一结果可以说类似于涉及对等网络的历史到期提案——如何接受一个低得多但仍然非零的永久历史存储增长率,因为每个客户端必须存储一个较低但固定百分比的历史数据。
  • 我们使用地址空间扩展来进行状态到期。这将涉及一个多年的过程,以确保地址格式转换方法有效且安全,包括现有应用程序。
  • 我们使用地址空间收缩来进行状态到期。这将涉及一个多年的过程,以确保所有涉及地址冲突的安全风险(包括跨链情况)都得到处理。

重要的一点是,无论是否实施依赖于地址格式更改的状态到期方案,最终都必须解决有关地址空间扩展和收缩的难题。今天,大约需要 280 哈希值来生成地址冲突,对于资源极其丰富的参与者来说,这种计算负载已经是可行的:GPU 可以进行大约 227 哈希值运算,因此运行一年可以计算 252 次,因此世界上所有约“2 的 30 次方”个 GPU 都可以在 约 1/4 年的时间内计算一次碰撞,而 FPGA 和 ASIC 可以进一步加速这一过程。在未来,此类攻击将会向越来越多的人开放。因此,实现完全状态到期的实际成本可能没有看起来那么高,因为无论如何我们都必须解决这个非常具有挑战性的地址问题。

它如何与路线图的其他部分交互?

进行状态过期可能会使从一种状态树格式到另一种状态树格式的转换变得更容易,因为不需要转换过程:您可以简单地开始使用新格式创建新树,然后执行硬分叉来转换旧树。因此,虽然状态到期很复杂,但它确实有利于简化路线图的其他方面。

功能清理(Feature cleanup)

它解决什么问题?

安全性、可访问性和可用性的关键先决条件之一 可信的中立性 是简单。如果协议美观且简单,就会减少出现错误的可能性。它增加了新开发人员能够参与其中的任何部分的机会。它更有可能是公平的,也更容易抵御特殊利益。不幸的是,协议就像任何社交系统一样,默认情况下会随着时间的推移而变得更加复杂。如果我们不希望以太坊陷入日益复杂的黑洞,我们需要做以下两件事之一:(i)停止进行更改并使协议僵化, (ii) 能够实际删除功能并降低复杂性。一种中间路线,即对协议进行较少的更改,并且随着时间的推移至少消除一点复杂性,这也是可能的做到的。本节将讨论如何减少或消除复杂性。

它是什么,它是如何工作的?

没有任何重大的单一修复可以降低协议的复杂性;这个问题的本质是有许多小的解决办法。

一个基本已经完成的示例是删除 SELFDESTRUCT 操作码。 SELFDESTRUCT 操作码是唯一可以修改单个块内无限数量存储槽的操作码,要求客户端实现显着更高的复杂性以避免 DoS 攻击。该操作码的最初目的是实现自愿状态清算,从而允许状态大小随着时间的推移而减小。实际上,很少有人最终使用它。在 Dencun 硬分叉中,该操作码被削弱为仅允许在同一交易中创建的自毁账户。这解决了 DoS 问题,并允许显著简化客户端代码。 未来,最终完全删除该操作码可能是有意义的。

迄今为止,已确定了一些关键的协议简化机会。首先,让我们看看 EVM 之外的例子。这些变更相对非侵入性,因此更容易达成共识并在短期内实施。

  • RLP → SSZ 转变:最初,以太坊使用一种称为 RLP的编码进行序列化。 RLP 是无类型的,而且没有必要那么复杂。如今,信标链使用 SSZ, 它在很多方面都明显更好,包括不仅支持序列化,还支持哈希。最终,我们希望完全摆脱 RLP,并将所有数据类型转移到 SSZ 结构中,这反过来会使升级变得更加容易。为此提出的当前 EIP 包括 [1] [2] [3]
  • 删除旧的交易类型:当今的交易类型太多,其中许多可能会被删除。完全删除的一个更温和的替代方案是帐户抽象功能,智能帐户可以通过该功能包含处理和验证旧式交易的代码(如果他们愿意的话)。
  • 日志(LOG)改革:日志创建了 Bloom 过滤器和其他逻辑,增加了协议的复杂性,但实际上并没有被客户端使用,因为它太慢了。我们可以 删除这些功能,而是将精力投入替代方案,例如使用 SNARK 等现代技术的协议外去中心化日志读取工具。
  • 最终取消信标链同步委员会机制:同步委员会机制最初是为了实现以太坊的轻客户端验证而引入的。然而,它增加了协议的复杂性。最终,我们将能够使用 SNARK 直接验证以太坊共识层,这将消除对专用轻客户端验证协议的需求。通过创建更「原生」的轻客户端协议(涉及验证来自以太坊共识验证器随机子集的签名),或许共识的改变可以使我们更早地取消同步委员会。
  • 数据格式统一:目前,执行状态存储在 Merkle Patricia 树中,共识状态存储在 SSZ 树中,而 Blob 则通过 KZG 承诺进行承诺。未来,为区块数据和状态创建单一的统一格式是有意义的。这些格式将满足所有重要需求:(i)无状态客户端的简单证明,(ii)数据的序列化和擦除编码,(iii)标准化数据结构。
  • 取消信标链委员会:该机制最初是为了支持特定版本的执行分片而引入的。相反,我们最终通过 L2 和 blob 进行分片。因此,委员会是不必要的,我们正在进行取消委员会的行动
  • 删除混合字节序:EVM 是大字节序,而共识层是小字节序。重新协调并使所有内容都采用大字节序或小字节序可能是有意义的(可能是大字节序,因为 EVM 更难更改)。

以下是 目前 EVM 中的一些示例:

  • 简化 Gas 机制:当前的 Gas 规则未能充分优化,无法准确限制验证区块所需的资源量。主要问题包括:(i)存储读/写成本,虽然旨在限制区块中的读/写次数,但目前设定较为随意;(ii)内存填充规则,使 EVM 的最大内存消耗难以估算。为解决这些问题,建议采取以下措施:实施无状态 Gas 成本变化,将所有存储相关成本统一为一个简单公式;同时引入新的内存定价提案
  • 删除预编译:以太坊今天拥有的许多预编译都不必要地复杂且相对未使用,并且在几乎没有被任何应用程序使用的情况下构成了共识失败的很大一部分。处理这个问题的两种方法是(i)仅删除预编译,以及(ii)用实现相同逻辑的(不可避免地更昂贵的)EVM 代码片段替换它。此 EIP 草案提议首先对身份预编译执行此操作;随后,RIPEMD160、MODEXP 和 BLAKE 可能会被移除。
  • 取消 Gas 可观察性:使 EVM 执行不再能够看到剩余的 Gas 量。这将破坏一些应用程序(最明显的是赞助交易),但将使未来升级更加容易(例如,升级到更高级的多维 Gas 版本)。EOF 规范 已经使 Gas 变得不可观察,但为了简化协议,EOF 需要成为强制性的。
  • 静态分析的改进:如今 EVM 代码很难进行静态分析,特别是因为跳转可能是动态的。这也使得优化 EVM 实现(将 EVM 代码预编译为其他语言)变得更加困难。我们可以通过删除动态跳转(或使其更加昂贵,例如,Gas 成本与合约中 JUMPDEST 的总数成线性关系)来解决这个问题。EOF 可以做到这一点,但要从中获得协议简化的好处,则需要强制执行 EOF。

与现有研究有哪些联系?

还需要做什么,需要权衡什么?

进行此类功能简化的主要权衡在于(i)我们简化的程度和速度与(ii)向后兼容性之间的平衡。以太坊作为一条链的价值源于它是一个平台,用户可以在其中部署应用程序,并确信这些应用在多年后仍能正常运行。然而,这种理想也可能被过分强调。借用William Jennings Bryan 的话,我们不应”将以太坊钉在向后兼容性的十字架上”。设想一个场景:如果整个以太坊生态系统中只有两个应用程序在使用某个特定功能,其中一个多年来没有用户,几乎完全闲置,而且这两个应用的总价值仅为 57 美元。在这种情况下,我们应该考虑删除该功能,必要时甚至可以自掏腰包向受影响的用户补偿这 57 美元。

更广泛的社会问题在于创建一个标准化的管道来进行非紧急的向后兼容性破坏的更改。解决这个问题的一种方法是检查和扩展现有的先例,例如自毁过程。该流程看起来如下:

  • 步骤一: 开始讨论删除功能 X
  • 步骤2: 进行分析以确定移除 X 对应用程序造成的影响,根据结果:(i) 放弃这个想法,(ii)按计划进行,或(iii)找到一种修改后的「破坏性最小」的方法来移除 X,并继续进行
  • 步骤3: 制定正式的EIP来弃用 X。确保流行的高级基础设施(例如编程语言、钱包)尊重这一点并停止使用该功能。
  • 第四步:最后, 实际删除 X

在第 1 步和第 4 步之间应该有一个持续数年的流程,并明确标识每个项目所处的步骤。此时,我们需要权衡”功能移除流程的力度和速度”与”采取更保守的方法并将更多资源投入协议开发的其他领域”。尽管如此,我们距离”帕累托前沿(Pareto frontier)”还有相当长的距离。

EOF

对 EVM 提出的一系列主要更改是 EVM 对象格式 (EOF)。 EOF引入了大量的改变,例如禁止gas可观察性、代码可观察性(即无CODECOPY)、仅允许静态跳转。目标是允许 EVM 以具有更强属性的方式进行更多升级,同时保持向后兼容性(因为 EOF 之前的 EVM 仍然存在)。

这样做的优点是,它创建了一条添加新 EVM 功能的自然路径,并鼓励迁移到具有更强保证的更严格的 EVM。它的缺点是它显着 增加 协议复杂性,除非我们能找到一种方法最终弃用并删除旧的 EVM。一个主要问题是: EOF 在 EVM 简化提案中发挥什么作用,特别是如果目标是降低整个 EVM 的复杂性?

它如何与路线图的其他部分交互?

路线图其余部分中的许多“改进”建议也是对旧功能进行简化的机会。重复上面的一些例子:

  • 切换到单槽最终性使我们有机会取消委员会、重新设计经济学并进行其他与权益证明相关的简化。
  • 完全实现账户抽象可以让我们删除大量现有的交易处理逻辑,将其移至所有 EOA 都可以替换的“默认账户 EVM 代码”中。
  • 如果我们将以太坊状态转移到二进制哈希树,这可以与新版本的 SSZ 协调一致,以便所有以太坊数据结构都可以以相同的方式进行哈希处理。

更激进的方法:将协议的大部分内容转化为合约代码

一个更激进的以太坊简化策略是保持协议不变,但将其大部分从协议功能转移到合约代码。

最激进的方案是将以太坊 L1 “技术上”简化为信标链,并引入一个精简的虚拟机(VM)。这可以是RISC-VCairo,或专为证明系统设计的更简单 VM。这种设计将允许开发者创建自己的 Rollup,而 EVM 将成为这些 Rollups 中的首个实例。有趣的是,这一方案与2019-20 年提出的执行环境方案殊途同归,尽管 SNARK 技术的进步使得这一设想更易实现。

一种更温和的方法是,保持信标链和当前以太坊执行环境之间的关系不变,但对 EVM 进行就地交换。我们可以选择 RISC-V、Cairo 或其他 VM 作为新的“官方以太坊 VM”,然后将所有 EVM 合约强制转换为解释原始代码逻辑的新 VM 代码(通过编译或解释)。理论上来说,甚至可以将这个”目标 VM”作为 EOF 的一个版本来实现。

免责声明:

  1. 本文转载自【Vitalik Buterin】,所有版权归原作者所有【Vitalik Buterin】。若对本次转载有异议,请联系 Gate Learn 团队,他们会及时处理。
  2. 免责声明:本文所表达的观点和意见仅代表作者个人观点,不构成任何投资建议。
  3. Gate Learn 团队将文章翻译成其他语言。除非另有说明,否则禁止复制、分发或抄袭翻译文章。
เริ่มตอนนี้
สมัครและรับรางวัล
$100
It seems that you are attempting to access our services from a Restricted Location where Gate.io is unable to provide services. We apologize for any inconvenience this may cause. Currently, the Restricted Locations include but not limited to: the United States of America, Canada, Cambodia, Cuba, Iran, North Korea and so on. For more information regarding the Restricted Locations, please refer to the User Agreement. Should you have any other questions, please contact our Customer Support Team.