撰文:Vitalik Buterin
编译:Glendon,Techub News
以太坊面临的挑战之一是,默认情况下,任何区块链协议的膨胀和复杂性都会随着时间的推移而增长。这发生在两个地方:
-
历史数据:历史上任何时间点进行的任何交易和创建的任何账户都需要由所有客户端永久存储,并由任何新客户端下载以完全同步到网络。这会导致客户端负载和同步时间随着时间的推移而不断增加,即使链的容量保持不变。
-
协议特性:添加新功能比删除旧功能要容易得多,这导致代码复杂性随着时间的推移而增加。
为了让以太坊能够长期维持下去,我们需要对这两种趋势施加强大的反压力,随着时间的推移降低复杂性和膨胀。但与此同时,我们需要保留使区块链变得的重要特性之一:永久性(Permanence)。你可以把一个 NFT、一封交易调用数据(Transaction Calldata)中的情书或是一份包含一百万美元的智能合约放在链上,然后进入一个山洞十年,出来后会发现它仍然在那里等着你阅读和交互。对于 DApp 而言,要想完全去中心化并删除升级密钥,它们需要确信其依赖项不会以破坏它们的方式升级——尤其是 Layer 1 本身。
The Purge,2023 年路线图
平衡这两种需求,并在保持连续性的同时最小化或扭转膨胀、复杂性和衰退,如果我们用心去做,这是完全可能的。生物体可以做到这一点:虽然大多数生物体会随着时间的流逝而衰老,但少数幸运儿却不会。即使是社会系统也可以拥有极长的寿命。在一些情况下,以太坊已经取得了成功:工作量证明消失了,SELFDESTRUCT 操作码基本消失了,信标链节点已经存储了最多六个月的旧数据。以更通用的方式为以太坊找出这条道路,并朝着长期稳定的最终结果前进,是以太坊长期可扩展性、技术可持续性甚至安全性的终极挑战。
The Purge:关键目标
-
通过减少或消除每个节点永久存储所有历史记录甚至最终状态的需要来降低客户端存储要求。
-
通过消除不需要的功能来降低协议复杂性。
历史记录到期(History expiry)
解决了什么问题?
截至撰写本文时,完全同步的以太坊节点需要大约 1.1 TB的磁盘空间用于执行客户端,另外还需要数百 GB 的磁盘空间用于共识客户端。其中绝大部分是历史记录:有关历史区块、交易和收据的数据,其中大部分是多年前的数据。这意味着即使 Gas 限制根本没有增加,节点的大小每年也会增加数百 GB。
它是什么,它是如何工作的?
历史存储问题的一个关键简化特证是,由于每个区块都通过哈希链接(和其他结构)指向前一个区块,因此对当前达成共识就足以对历史达成共识。只要网络对最新区块达成共识,任何历史区块或交易或状态(账户余额、随机数、代码、存储)都可以由任何单个参与者提供,并附带 Merkle 证明,而该证明允许其他任何人验证其正确性。虽然共识是 N/2-of-N 信任模型,但历史是1-of-N 信任模型。
这为我们存储历史数据的方式提供了许多选择。一个自然的选择是每个节点仅存储一小部分数据的网络。这就是 Torrent 网络几十年来的运作方式:虽然网络总共存储和分发数百万个文件,但每个参与者只存储和分发其中的几个文件。也许与直觉相反,这种方法甚至不一定会降低数据的稳健性。如果通过使节点运行更便宜,我们可以获得一个拥有 10 万个节点的网络,其中每个节点存储随机 10% 的历史记录,那么每条数据都会被复制 10000 次——这与 10000 个节点网络的复制因子完全相同,每个节点存储所有内容。
如今,以太坊已经开始摆脱所有节点永久存储所有历史记录的模式。共识区块(即与权益证明共识相关的部分)仅存储约 6 个月。Blob 仅存储约 18 天。EIP-4444旨在为历史区块和收据引入一年的存储期。长期目标是有一个协调的时期(可能是约 18 天),在此期间每个节点负责存储所有内容,然后构建一个由以太坊节点组成的对等网络,以分布式方式存储旧数据。(Techub News 注,Blob 是一种数据存储概念,旨在降低 L2 扩展解决方案的交易成本。)
可以使用纠删码(Erasure Codes)来提高鲁棒性(Robustness,即稳健性),同时保持复制因子相同。事实上,为了支持数据可用性采样,Blob 已经采用纠删码。最简单的解决方案可能是重新使用这种纠删码,并将执行和共识块数据也放入 Blob 中。
与现有研究有哪些联系?
-
门户网络(Portal network)
还要做些什么,需要权衡什么?
剩下的主要工作涉及构建和集成一个具体的分布式解决方案来存储历史记录——至少是执行历史记录,但最终也包括共识和 Blob。对此,最简单的解决方案是 (i) 简单地引入现有的 torrent 库,以及 (ii) 一个名为「Portal 网络」的以太坊原生解决方案。一旦引入其中任何一个,我们就可以启用 EIP-4444。EIP-4444 本身不需要硬分叉,但它确实需要新的网络协议版本。因此,同时为所有客户端启用它是有价值的,否则将存在客户端连接到其他节点时出现故障的风险,这些节点期望下载完整的历史记录,但实际上却无法获取。
主要的权衡涉及我们如何努力使「古老的」历史数据可用。最简单的解决方案是明天停止存储古老的历史记录,并依靠现有的存档节点和各种集中式提供程序进行复制。这很容易,但这削弱了以太坊作为永久记录场所的地位。更困难但更安全的方法是首先构建和集成 torrent 网络以分布式方式存储历史记录。这里,「我们的努力程度」有两个维度:
1.我们如何努力确保最大的节点集确实存储了所有数据?
2.我们如何将历史记录存储深度集成到协议中?
对于(1),一种最偏执的方法是使用托管证明:实际上要求每个权益证明验证者存储一定比例的历史记录,并定期通过加密方式检查他们是否这样做。更温和的方法是为每个客户端存储的历史记录百分比设定一个自愿标准。
对于(2),基本实现只涉及今天已经完成的工作:Portal 已经存储了包含整个以太坊历史的 ERA 文件。更彻底的实现,实际上需要将其连接到同步过程,这样如果有人想要同步完整历史记录存储节点或存档节点,即使没有其他存档节点在线存在,他们也可以通过直接从 Portal 网络同步来实现此操作。
它如何与路线图的其他部分进行交互?
如果我们想让节点运行或启动变得极其容易,那么减少历史存储需求可以说比无状态性(Statelessness)更重要:在节点需要的 1.1 TB 中,约 300 GB 是状态存储,其余约 800 GB 是历史存储。只有在同时实现无状态性和 EIP-4444 的情况下,以太坊节点在智能手表上运行且只需几分钟即可设置的愿景才能实现。
限制历史存储也使得较新的以太坊节点实现更易于仅支持协议的最新版本,从而使它们变得更加简单。例如,由于 2016 年 DoS 攻击期间创建的空存储槽已全部被删除,因此现在可以安全地删除许多代码行。既然转向权益证明已成为历史,那么客户端可以安全地删除所有与工作量证明相关的代码。
状态到期(State expiry)
它解决了什么问题?
即使我们消除了客户端存储历史记录的需求,客户端的存储需求仍将继续增长,每年约 50 GB,因为状态持续增长:账户余额和随机数、合约代码和合约存储。用户可以支付一次性费用,永远给现在和未来的以太坊客户端带来负担。
状态比历史记录更难「过期」,因为 EVM 的设计从根本上是围绕一个假设,即一旦创建了状态对象,它将永远存在,并且可以随时被任何事务读取。如果我们引入无状态性,有人认为这个问题可能没有那么糟糕:只有一类专门的区块构建器才需要实际存储状态,而所有其他节点(甚至包含列表生成)都可以无状态运行。然而,有一种观点认为,我们不想过分依赖无状态性,最终我们可能希望让状态过期以保持以太坊的去中心化。
它是什么,它是如何工作的?
现在,当你创建一个新的状态对象时(这可以通过以下三种方式之一实现:(i)将 ETH 发送到新帐户;(ii)使用代码创建新帐户;(iii)设置以前未触及的存储槽),该状态对象将永远处于该状态。相反,我们想要的是对象随着时间的推移自动过期。要做到这一点,关键的挑战是要实现以下三个目标:
1.效率:不需要大量额外的计算来运行到期过程;
2.用户友好性:如果「有人进入山洞五年后再回来」,他们不应该失去对其 ETH、ERC20、NFT、CDP 头寸的访问权。
3.开发人员友好性:开发人员不必切换到完全不熟悉的思维模型。此外,目前僵化且不更新的应用程序应该可以继续正常运行。
在不满足这些目标的情况下,问题很容易解决。例如,用户可以让每个状态对象还存储一个计数器来表示其到期日期(可以通过销毁 ETH 来延长过期日期,这可以在读取或写入时自动发生),并有一个循环「遍历状态」以删除过期状态对象的过程。但是,这引入了额外的计算(甚至存储需求),并且它肯定不能满足用户友好性的要求。开发人员也很难推理涉及存储值有时重置为零的边缘情况。如果用户在整个合约范围内设置到期计时器,这在技术上使开发人员的工作变得更容易,但在经济上却变得更加困难:开发人员必须考虑如何将持续的存储成本「转嫁」给用户。
这些都是以太坊核心开发社区多年来一直在努力解决的问题,包括「区块链租金」和「再生(Regenesis)」等提案。最终,我们结合了这些提案中最好的部分,并集中于两类「已知最不糟糕的解决方案」:
-
部分状态到期解决方案
-
基于地址周期的状态到期建议。
部分状态到期
部分状态过期提案都遵循相同的原则。我们将状态分成多个块。每个人都永久存储「顶层映射(Top-Level Map)」,其中的块为空或非空。每个块中的数据只有在最近被访问时才会被存储。有一个「复活(Resurrection)」机制,如果某个块不再存储,任何人都可以通过提供数据的证明来恢复该数据。
这些提案之间的主要区别在于:(i)我们如何定义「最近」,以及(ii)我们如何定义「大的数据块(Chunk)」?一个具体的提案是EIP-7736,它建立在为 Verkle 树引入的「茎和叶」设计之上(尽管与任何形式的无状态树兼容,例如二叉树)。在这种设计中,彼此相邻的标头、代码和存储槽存储在同一个「茎」下。存储在「茎」下的数据最多为「256 * 31 = 7936 字节」。在许多情况下,帐户的整个标头和代码以及许多密钥存储槽都将存储在同一个「茎」下。如果给定「茎」下的数据在 6 个月内未被读取或写入,则不再存储该数据,而是只存储对该数据的 32 字节承诺(「存根 stub」)。未来访问该数据的交易将需要「复活」数据,并提供根据「存根」进行验证的证明。
还有其他方法可以实现类似的想法。例如,如果帐户级别的粒度不够,我们可以制定一个方案,其中「树」的每个「1/2 的 32 次方」部分都由类似的「茎和叶」机制控制。
由于激励因素,这变得更加棘手:攻击者可以通过将大量数据放入单个子树(Subtree)并每年发送单个交易来「更新树」,从而迫使客户端永久存储大量状态。如果使更新成本与「树」大小成正比(或更新持续时间成反比),那么有人可能会通过将大量数据放入与他们相同的子树中来伤害其他用户。用户可以尝试通过根据子树大小使粒度动态化来限制这两个问题:例如,每个连续的「2 的 16 次方」= 65536 个状态对象可以被视为一个「组」。然而,这些想法更为复杂;基于「茎」的方法很简单,它与激励措施保持一致,因为通常「茎」下的所有数据都与同一个应用程序或用户相关。
基于地址周期的状态到期建议
如果我们想完全避免任何永久性的状态增长,即使是 32 字节的「存根」,该怎么办?由于复活冲突(Resurrection Conflicts),这是一个难题:如果一个状态对象被删除,稍后的 EVM 执行会将另一个状态对象放在完全相同的位置,但之后关心原始状态对象的人回来并试图恢复它,该怎么办?在部分状态到期时,「存根」会阻止创建新数据。在完全状态到期的情况下,我们甚至无法存储「存根」。
基于地址周期的设计是解决此问题的最佳方法。我们不再使用一棵状态树来存储整个状态,而是拥有一个不断增长的状态树列表,并且任何读取或写入的状态都会保存在最新的状态树中。每个周期(例如 1 年)添加一次新的空状态树。较旧的状态树将保持稳定。完整节点仅应存储最近的两棵状态树。如果一个状态对象在两个周期内未被触及,因此落入过期状态树中,它仍然可以被读取或写入,但交易需要证明它的 Merkle 证明——一旦证明,副本将再次保存在最新的状态树中。
使这一切对用户和开发人员都友好的一个关键思想是地址周期的概念。地址周期是地址一部分的数字。关键规则是地址周期为 N 的地址只能在周期 N 期间或之后(即,当状态树列表达到长度 N 时)被读取或写入。如果用户要保存新的状态对象(例如,一个新合约或新的 ERC20 余额),如果你确保将状态对象放入地址周期为 N 或 N-1 的合约中,那么你可以立即保存它,无需提供证据证明之前什么都没有。另一方面,对旧地址周期中的状态进行任何添加或编辑都需要证明。
这种设计保留了以太坊当前的大部分特性,额外计算量非常小,允许应用程序几乎像现在一样编写(ERC20 需要重写,以确保地址周期为 N 的地址余额存储在本身具有地址周期为 N 的子合约中),并解决了「用户进入山洞五年」的问题。然而,它有一个大问题:地址需要扩展到 20 个字节以上才能适应地址周期。
地址空间扩展(Address space extension)
一项提议是引入一种新的 32 字节地址格式,其中包括版本号、地址周期号和扩展哈希值。
红色是版本号。橙色的四个零表示空白空间,将来可以容纳分片编号。绿色是地址周期号。蓝色是 26 字节的哈希值。
这里的关键挑战是向后兼容性。现有合约是围绕 20 字节地址设计的,并且通常使用严格的字节打包技术,明确假设地址正好是 20 字节长。解决这个问题的一个想法是使用转换映射(Translation Map),其中与新式地址交互的旧式合约将看到新式地址的 20 字节哈希值。然而,要确保这一点的安全性,存在着很大的复杂性。
地址空间收缩(Address space contraction)
另一种方法则采取相反的方向:我们立即禁止一些「2 的 128 次方」大小的地址子范围(例如,所有以 0x ffffffff 开头的地址),然后使用该范围引入带有地址周期和 14 字节哈希值的地址。
这种方法的主要牺牲是,它为反事实地址引入了安全风险:持有资产或权限但其代码尚未发布到链上的地址。风险在于有人创建一个地址,声称拥有一段(尚未发布的)代码,但还有另一段有效代码,该代码的哈希值指向同一地址。计算这样的碰撞目前需要「2 的 80 次方」个哈希值;地址空间收缩会将这个数字减少到易于访问的 「2 的 56 次方」个哈希值。
关键风险领域是反事实地址,即不是由单个所有者持有的钱包,这在今天是一种相对罕见的情况,但随着我们进入多 L2 世界,这种情况可能会变得更加常见。唯一的解决方案是简单地接受这种风险,但要确定可能出现问题的所有常见用例,并提出有效的解决方法。
与现有研究有哪些联系?
早期提案
部分状态到期提案:EIP-7736
地址空间扩展文档:
还要做些什么,需要权衡什么?
我认为未来有四条可行的道路:
1.我们实行无状态,并且从不引入状态到期。状态正在不断增长(尽管速度缓慢:几十年内我们可能不会看到它超过 8 TB),但只需要由相对专业的用户类别持有:甚至 PoS 验证器都不需要状态。
需要访问部分状态的一个功能是包含列表生成,但我们可以以去中心化的方式实现这一点:每个用户负责维护状态树中包含自己帐户的部分。当他们广播交易时,他们会广播在验证步骤中访问的状态对象的证明(这适用于 EOA 和 ERC-4337 帐户)。然后,无状态验证器可以将这些证明组合成整个包含列表的证明。
2.我们实施部分状态到期,并接受一个低得多但仍然非零的永久状态大小增长率。这一结果可以说类似于涉及对等网络的历史到期提案——如何接受一个低得多但仍然非零的永久历史存储增长率,因为每个客户端必须存储一个较低但固定百分比的历史数据。
3.我们使用地址空间扩展来进行状态到期。这将涉及一个多年的过程,以确保地址格式转换方法有效且安全,包括现有应用程序。
4.我们使用地址空间收缩来进行状态到期。这将涉及一个多年的过程,以确保处理所有涉及地址冲突的安全风险(包括跨链情况)。
重要的一点是,无论是否实现依赖于地址格式变化的状态到期方案,最终都必须解决有关地址空间扩展和收缩的难题。目前,大约需要「2 的 80 次方」的哈希值运算才能产生地址冲突,对于资源极其充足的参与者来说,这种计算负载已经是可行的:GPU 可以进行大约「2 的 27 次方」哈希值运算,因此运行一年可以计算「2 的 27 次方」次,因此世界上所有约「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。
与现有研究有哪些联系?
- 清除的后续步骤
- 自毁(SELFDESTRUCT)
- SSZ 化 EIPS:[1][2][3]
- 无状态 Gas 成本变化
- 线性内存定价
- 预编译删除
- Bloom 过滤器删除一种使用增量可验证计算进行链下安全日志检索的方法(阅读:递归 STARK)
还要做些什么,需要权衡什么?
进行此类功能简化的主要权衡是(i)我们简化的程度和速度与(ii)向后兼容性。以太坊作为一条链的价值在于它是一个平台,用户可以在其中部署应用程序,并确信它在多年后仍能正常工作。与此同时,这种理想也有可能被推得太远了,用 William Jennings Bryan 的话来说,「将以太坊钉在向后兼容性的十字架上」。如果整个以太坊中只有两个应用程序使用给定的功能,其中一个多年来没有用户,几乎完全未使用,并且总共获得了 57 美元的价值,那么我们应该删除该功能,如果需要,可以自掏腰包向受害者支付 57 美元。
更广泛的社会问题在于创建一个标准化的流程,用于进行非紧急的向后兼容性破坏性的更改。解决此问题的一种方法是检查和扩展现有先例,例如 SELFDESTRUCT 流程。该流程如下所示:
- 步骤 1:开始讨论删除功能 X
- 步骤 2:进行分析以确定移除 X 对应用程序造成的影响,根据结果:(i) 放弃这个想法,(ii)按计划进行,或(iii)找到一种修改后的「破坏性最小」的方法来移除 X,并继续进行。
- 步骤 3:制定正式的 EIP 来弃用X。确保流行的高级基础设施(例如编程语言、钱包)尊重这一点并停止使用该功能。
- 步骤 4:最后,实际删除X
在第 1 步和第 4 步之间应该有一个长达数年的流程,并明确说明哪些项目处于哪个步骤。此时,需要在「功能移除流程的力度和速度」与「更为保守和将更多资源投入协议开发的其他领域」之间进行权衡,但我们距离「帕累托前沿(Pareto frontier)」还很远。(Techub News 注,帕累托前沿是指在多目标优化问题中,所有帕累托最优解的集合)
EOF
针对 EVM 提出的一组主要更改是EVM 对象格式(EOF)。EOF 引入了大量更改,例如禁止 Gas 可观察性、代码可观察性(即没有 CODECOPY),仅允许静态跳转。目标是允许 EVM 进行更多升级,以具有更强大的属性,同时保持向后兼容性(因为 EOF 之前的 EVM 仍然存在)。
这样做的好处是,它为「添加新的 EVM 功能」和「鼓励迁移到具有更强保证的更严格 EVM 上」创造了一条自然路径。它的缺点是,除非我们能找到一种方法最终弃用和删除旧的 EVM,否则它会显著增加协议的复杂性。一个主要问题是:EOF 在 EVM 简化提案中扮演什么角色,特别是如果目标是降低整个 EVM 的复杂性?
它如何与路线图的其他部分交互?
路线图其余部分中的许多「改进」建议也是对旧功能进行简化的机会。重复上面的一些例子:
切换到单槽最终性使我们有机会移除委员会,重新制定经济学,并进行其他与权益证明相关的简化。
通过完全实现账户抽象,我们可以删除许多现有的交易处理逻辑,将其移至一段所有 EOA 都可以替换的「默认账户 EVM 代码」中。
如果我们将以太坊状态移至二进制哈希树,这可以与新版本的 SSZ 协调一致,以便所有以太坊数据结构都可以以相同的方式进行哈希处理。
更激进的方法:将协议的大部分内容转化为合约代码
一个更激进的以太坊简化策略是保持协议不变,但将其大部分从协议功能转移至合约代码。
最极端的版本是让以太坊 L1「技术上」只是信标链,并引入一个最小的 VM(例如RISC-V、Cairo或专门用于证明系统的更简单的 VM),允许其他人创建自己的 Rollup。然后,EVM 将成为这些 Rollups 中的第一个。具有讽刺意味的是,这与2019-20 年的执行环境提案的结果完全相同,尽管 SNARK 使其实际实施起来更加可行。
一种更温和的方法是,保持信标链与当前以太坊执行环境之间的关系不变,但对 EVM 进行原地交换(In-place Swap)。我们可以选择 RISC-V、Cairo 或其他 VM 作为新的「官方以太坊 VM」,然后将所有 EVM 合约强制转换为解释原始代码逻辑的新 VM 代码(通过编译或解释)。从理论上讲,甚至可以将「目标 VM」作为 EOF 的一个版本来完成此操作。