以太坊协议的可能未来 ❺:Purge
作者:维塔利克·布特林 2024年10月26日 原文链接
以太坊面临的一个挑战是,默认情况下,任何区块链协议的膨胀和复杂性都会随着时间的推移而增长。这发生在两个地方:
- 历史数据: 任何时候进行的任何交易和创建的任何账户都需要被所有客户端永久存储,并且任何新客户端要完全同步到网络时都需要下载。这会导致客户端负载和同步时间不断增加,尽管链的容量保持不变。
- 协议特性: 添加一个新特性要比删除一个旧特性容易得多,导致代码复杂性随着时间的推移而增加。
特别感谢Justin Drake, Tim Beiko, Matt Garnett, Piper Merriam, Marius van der Wijden和Tomasz Stanczak的反馈和审阅
为了让以太坊长期可持续发展,我们需要一个强大的力量来抵消这两种趋势,随着时间的推移减少复杂性和膨胀。但与此同时,我们需要保留使区块链伟大的关键特性之一:永久性。你可以在链上放置一个NFT、一个交易calldata中的爱的注记,或者一个包含100万美元的智能合约,进入一个山洞10年,出来后发现它们仍在等待你阅读和交互。为了让去中心化应用感到舒服地完全去中心化并移除他们的升级密钥,他们需要确信它们所依赖的组件不会以破坏它们的方式升级 - 特别是L1本身。
保持这两种需求之间的平衡,同时最小化或扭转膨胀、复杂性和衰落,同时保持连续性,这是绝对可能实现的,只要我们下定决心。生物体就能做到这一点:虽然大多数会随着时间的推移而衰老,但一些幸运的却不会。社会系统也可以拥有极长的寿命。在某些情况下,以太坊已经取得了成功:工作量证明已经消失,SELFDESTRUCT
操作码基本上已经消失,且信标链节点目前只存储最近六个月的旧数据。找到这条路径,让以太坊朝着最终稳定的长期状态发展,是以太坊长期可扩展性、技术可持续性乃至安全性的终极挑战。
说明
为 Vitalik 文章的全文翻译,为便于阅读增加少量标签式图示展示重要术语。
The Purge:关键目标
- 减少客户端存储需求,通过减少或移除每个节点永久存储所有历史数据的需求,最终甚至可能包括状态
- 减少协议复杂性,通过消除不需要的特性
本章内容
- 历史数据过期
- 状态过期
- 功能清理
历史数据过期
解决了什么问题?
据统计,截至本文撰写时,全量同步的以太坊节点需要约1.1TB的磁盘空间来存储执行客户端数据,另外还需要几百GB来存储共识客户端数据。其中绝大部分数据都是历史数据,即有关历史上区块、交易和收据的信息,这些数据大部分来自数年以前。这意味着,即使gas上限未发生变化,节点的存储空间需求每年也会增加数百GB。
它是什么?工作原理是什么?
历史存储问题的一个关键简化之处在于,由于每个区块都通过哈希链接指向前一个区块(以及其他结构如slots_per_historical_root、EIP-4788)。因此,只要就当前状态达成共识,就可以间接达成对历史数据的共识。只要网络对最新区块达成共识,任何单个参与者都可以提供某个特定的历史区块、交易或状态(账户余额、nonce、代码、存储)以及其Merkle证明,证明允许其他任何节点验证数据的正确性。虽然共识需要N/2的N个节点互相信任,但对于历史数据只需要1/N的互信程度。
基于这一特性,我们可以有多种选择来存储历史数据。其中一个自然的选择是,令每个节点只存储一小部分数据的网络。这种做法与几十年来BT种子网络的运作方式相似:尽管整个网络总计分发了数百万个文件,但每个参与者只需存储和分发其中的几个文件即可。虽然看起来有点违反直觉,但这种方式并不会降低数据的健壮性。如果通过让节点运行更加经济实惠,我们能够增加以太坊网络中的节点数量到10万个,而每个节点只存储10%的历史数据,那么每个数据实际上会被复制10,000次,复制因子与每个节点都存储全部数据的10,000节点网络是完全相同的。
如今,以太坊已经开始逐步摆脱所有节点永久存储全部历史数据的做法。与权益证明(PoS)共识相关的共识块只需存储约6个月。而存储blob数据(指由区块头和交易组成的大数据块)的时间仅为18天左右。EIP-4444提案旨在为历史上的区块和收据引入一年的存储期限。长远来看,目标是在每个节点负责存储所有最新数据的一段时间(例如18天)后,建立由存储旧数据的以太坊节点组成的分布式点对点网络。
纠删码可用于在保持相同的复制因子的情况下提高数据的健壮性。事实上,blob数据已经使用了纠删码以支持数据可用性采样。最简单的解决方案或许是,重用这种纠删码机制,并将执行层和共识层的区块数据也整合到blob中一并存储。
查看更多:现有研究资料链接
现有研究资料链接
- EIP-4444:"历史数据过期规范" - https://eips.ethereum.org/EIPS/eip-4444
- 种子(Torrent)网络与EIP-4444 - https://ethresear.ch/t/torrents-and-eip-4444/19788
- 门户网络(Portal Network)概述 - https://ethereum.org/en/developers/docs/networking-layer/portal-network/
- 门户网络与EIP-4444的关系 - https://github.com/ethereum/portal-network-specs/issues/308
- 门户网络中SSZ(简单序列化)对象的分布式存储与检索 - https://ethresear.ch/t/distributed-storage-and-cryptographically-secured-retrieval-of-ssz-objects-for-portal-network/19575
- 如何提高gas上限 (Paradigm研究) - https://www.paradigm.xyz/2024/05/how-to-raise-the-gas-limit-2
待解决的问题及权衡考虑
待完成的工作
待完成的主要工作是开发并实施一种具体的分布式存储方案,用于保存历史记录,至少包括执行历史,最终还应当包括共识历史和blob数据。最简单的解决方案如下:
- 直接引入现有的BT种子库
- 采用一种名为Portal网络的以太坊原生解决方案
一旦引入上述其中之一,我们就可启用EIP-4444提案。EIP-4444本身无需进行硬分叉,但需要升级网络协议版本。因此,同时为所有客户端启用它很有价值,否则客户端可能会因与期望获取完整历史记录但实际上未获得的节点连接而发生故障。
权衡考量
主要的权衡在于,我们需要努力使"古老"的历史数据可用的程度。最简单的做法是明天就停止存储古老历史,而依赖现有的存档节点和一些中心化提供商来复制和提供这些历史数据。这种方式很简单,但会削弱以太坊作为永久记录载体的地位。更安全但更困难的路径是,首先构建并集成torrent网络,以分布式的方式存储历史。
在这方面,我们努力的程度可分为两个维度:
- 确保尽可能多的节点真正存储所有历史数据的程度
- 将历史存储与协议集成的深度
对于第一个维度,最彻底的做法是采用一种被称为"存储量证明"(proof of custody)的方案:实际要求每个PoS验证者节点存储一定比例的历史记录,并定期使用加密方式检查它们是否真的这样做了。一种更温和的做法是,为每个客户端存储历史记录的份额设定一个自愿标准。
对于第二个维度,基本实现可以采用如今已有的方式:Portal网络已经在存储包含以太坊完整历史的ERA文件。更彻底的实现则是将这一存储机制与同步过程挂钩,这样即使在线上不存在其他存档节点,新节点也能通过直接从Portal网络同步的方式获取完整历史记录,并启动一个全历史存储或存档节点。
与路线图其他部分的关系
减少节点存储历史记录的需求,或许比不再存储全量状态(无状态性)更为重要。这样才能让运行或启动以太坊节点变得极其简单:目前一个全节点需要1.1TB的存储空间,其中约300GB用于存储当前状态,而剩余约800GB则是历史执行记录。只有同时实现无需存储状态和历史数据,以太坊节点才有望在智能手表上运行,且仅需数分钟即可设置完毕。
限制只保存最新的历史记录,也为新兴的以太坊节点实现提供了优化空间,使它们只需支持最近的协议版本,从而大幅简化代码。例如,由于2016年发生的一系列DDoS攻击导致当时产生了大量空存储时隙,后来通过 EIP-158 对这些存储进行了清理。如今以太坊已全面转向权益证明机制,相关的工作量证明算法和代码都可以被移除了,为节点实现瘦身提供了机会。
状态过期
它解决了什么问题?
即使我们不需要客户端存储历史记录,客户端的存储需求仍将持续增长,因为不断有新的状态被添加: 账户余额和nonce、合约代码和合约存储。用户能够支付一次性费用,永远给当前和未来的以太坊客户端增加负担。
与历史记录相比,状态更难"过期",因为EVM从根本上就是围绕着一旦创建了状态对象,它就将永远存在并且可以被任何时候的任何交易读取这一假设设计的。如果我们引入无状态,有一种观点认为这个问题可能不太严重:只有一小部分专门的区块生产者需要实际存储状态,其他所有节点(甚至包括创建包含列表)都可以无状态运行。然而,也有一种观点认为,我们不应过于依赖无状态,最终以太坊可能需要让状态过期以保持去中心化。
它是什么?工作原理是什么?
如今,当你创建一个新的状态对象时(可以通过以下三种方式之一发生:(i)向新账户发送ETH,(ii)创建具有代码的新账户, (iii)设置先前未设置过的存储位),该状态对象将永远存在于状态中。相反,我们希望这些对象能够随着时间自动过期。关键的挑战是以一种实现以下三个目标的方式来做到这一点:
- 效率: 不需要耗费大量额外的计算资源来执行过期过程
- 用户友好性: 如果有人离开很长一段时间后回来,他们不应该失去对自己的ETH、ERC20、NFT、CDP头寸等的访问权限。
- 开发者友好性: 开发者不应该必须切换到一个完全陌生的心智模型。此外,当前已被固化且不再更新的应用程序应该能继续较好地工作。
很容易在不满足这些目标的情况下解决这个问题。例如,你可以让每个状态对象也存储其过期日期的计数器(可以通过燃烧ETH来延长,燃烧操作可以在任何时候自动发生时读取或写入),并引入一个循环遍历状态并移除过期状态对象的过程。然而,这会引入额外的计算(甚至额外的存储需求),并且它肯定不满足用户友好性要求。开发人员也很难处理涉及存储值有时重置为零的边缘案例。如果你让过期计时器适用于整个合约,从技术上讲,这会让开发人员的生活更轻松,但它会让经济层面变得更加困难:开发人员将不得不考虑如何向用户"传递"存储的持续成本。
这些是以太坊核心开发社区多年来一直在努力解决的问题,包括"区块链租金"和"重生"等建议。最终,我们结合了这些建议中的最佳部分,并最终汇聚成两大类"已知的最不理想的解决方案":
- 部分状态过期解决方案
- 基于地址-期间的状态过期建议
部分状态过期
所有部分状态过期提案的工作原理都是一致的。我们将状态划分为多个区块。每个人都永久存储"顶层映射",该映射显示了哪些区块为空或非空。区块内的数据只有在最近被访问过的情况下才会被存储。有一种"复活"机制,如果某个区块的数据不再被存储,任何人都可以提供该数据先前存在的证明将其带回。
这些提案之间的主要区别在于: (i) 我们如何定义"最近", (ii) 我们如何定义"区块"? 一个具体的提案是 EIP-7736,它建立在 Verkle 树引入的"stem 和 leaf"设计之上 (尽管它也可以与其他任何形式的无状态性兼容,例如二叉树)。在这种设计中,彼此相邻的 header、code 和存储槽都存储在同一个 "stem" 下。存储在一个 stem 下的数据最多可以是 256 * 31 = 7,936
字节。在许多情况下,一个账户的整个 header、code 和许多关键存储槽都将存储在同一个 stem 下。如果某个给定 stem 下的数据在 6 个月内没有被读取或写入,则该数据将不再被存储,而只存储一个 32 字节的"桩"。未来访问该数据的交易将需要 "复活"该数据,并提供一个将与桩进行验证的证明。
还有其他方式来实现类似的想法。例如,如果账户级别的粒度不够,我们可以制定一种方案,使树的每个 1/2^32 部分都受到类似的 stem 和 leaf 机制的约束。
这种方式相对更加棘手,因为存在激励问题:攻击者可能会强迫客户端永久存储大量状态,方法是将大量数据放入单个子树中并每年发送一次交易来续订树。如果将续订成本设置为与树的大小成正比(或续订持续时间设置为与树的大小成反比),那么某人就可能通过将大量数据放入与他人相同的子树中来骚扰另一个用户。人们可以尝试通过根据子树的大小动态调整粒度来解决这两个问题:例如,每连续 2^16=65536 个状态对象可以被视为一个"组"。然而,这些想法相对较为复杂;基于 stem 的方法很简单,而且它可以很好地调整激励机制,因为通常所有与同一应用程序或用户相关的数据都在同一个 stem 下。
基于地址时期的状态过期提案
如果我们想完全避免任何永久状态增长,即使是32字节的存根也不行,会怎么样?这是一个棘手的问题,因为存在状态对象复活冲突的可能:如果一个状态对象被删除,后来EVM执行又在同一位置创建了另一个状态对象,但之后有人关心最初的状态对象并试图恢复它,会发生什么?在部分状态过期的情况下,存根可以防止新数据被创建。但在完全状态过期的情况下,我们连存根都无法存储。
基于地址时期的设计是已知解决此问题的最佳方案。我们不再使用一个存储整个状态的状态树,而是拥有一个不断增长的状态树列表。任何被读取或写入的状态都会保存在最新的状态树中。一个新的空状态树会在每个周期(设想一下:1年)被添加。较旧的状态树会被冻结状态。全节点只需存储最近的两棵树。如果一个状态对象未在两个周期内被访问,从而落入了已过期的树中,它仍然可以被读取或写入,但交易需要提供Merkle证明 - 一旦提供,它的副本就会再次保存在最新的树中。
使这整个设计对用户和开发者友好的关键是地址时期的概念。地址时期是一个地址的一部分。关键规则是:具有地址时期N的地址只能在N时期或之后(即当状态树列表长度达到N时)被读取或写入。如果你要保存一个新的状态对象(例如新合约或新ERC20余额),只要你确保将状态对象放入地址期为N或N-1的合约中,就可以立即保存它,而无需证明之前那里什么都没有。而对较旧的地址期进行状态添加或编辑则需要提供证明。
这个设计基本上保留了以太坊目前的大多数属性,额外计算开销很小,应用程序的编写方式与当前差别不大(ERC20 token合约需要重写,以确保地址时期为N的地址的余额存储在地址时期也为N的子合约中),并且解决了"用户进入冬眠5年"的问题。然而,它还是存在一个重大问题: 地址需要扩展至超过20字节,以容纳地址时期。
地址空间扩展
一种建议是引入新的32字节地址格式,其中包括版本号、地址周期号及扩展哈希值。
0x01000000000157aE408398dF7E5f4552091A69125d5dFcb7B8C2659029395bdF
红色部分是版本号,橙色的四个零是留作未来使用的空间,可容纳分片编号。绿色部分是地址周期号,而蓝色部分则是26字节哈希值。
在这里,关键的挑战在于确保向后兼容性。现有合约都是基于20字节地址来设计的,通常采用紧凑的字节打包技术,明确假设地址长度恰好为20字节。一种解决方案涉及使用地址转换映射:旧式合约与新式地址交互时,会看到新式地址的20字节哈希值。然而,要确保这种方式的安全性仍存在诸多复杂性需要解决。
地址空间收缩
另一种方法则朝相反的方向而去:我们立即禁止 2128 大小地址范围内的某个子范围(如所有以0xffffffff
开头的地址),然后使用该范围来引入带有地址周期和14字节哈希值的地址。
0xffffffff000169125d5dFcb7B8C2659029395bdF
这种方法的关键牺牲是,它为所谓的"未实现地址"引入了安全风险。"未实现地址"指的是虽然持有资产或权限,但其代码尚未发布到链上的地址。风险在于,有人可能创建一个声称具有某段(尚未发布的)代码的地址,但实际上又有另一段有效代码哈希到同一个地址。目前计算这种冲突需要 280 次哈希运算,而地址空间收缩会将这个数字降低到 256 次,从而变得可行。
主要风险领域是不由单一所有者控制的"未实现地址",这种情况如今并不常见,但随着我们进入多 L2 世界,可能会变得更加普遍。唯一的解决方案是接受这种风险,并确定所有常见的潜在问题场景,为之制定有效的解决方法。
查看更多:现有研究资料链接
现有研究资料链接
早期提案
以太坊状态大小管理理论: https://hackmd.io/@vbuterin/state_size_management
通向无状态(stateless)和状态过期的几种可能路径: https://hackmd.io/@vbuterin/state_expiry_paths
部分状态过期方案建议
- EIP-7736: https://eips.ethereum.org/EIPS/eip-7736
地址空间扩展文档
如果失去地址碰撞抗性(collision resistance)会出现什么情况: https://ethresear.ch/t/what-would-break-if-we-lose-address-collision-resistance/11356
待解决的问题及权衡考虑
我看到未来有四条可行路线:
实现无状态化,但不引入状态过期。状态数据虽然会持续缓慢增长(几十年内可能不会超过8TB),但只有一些特殊用户需要保存完整状态。甚至作为PoS验证者也无需保存全部状态。
唯一需要访问部分状态数据的是生成交易包含列表这一功能,但我们可以采用去中心化的方式实现:每个用户负责维护包含自身账户的那部分状态树。在广播交易时,他们需要附带在验证步骤中访问到的状态对象证明(适用于EOA和ERC-4337账户)。无状态节点可以根据这些证明组装出完整的包含列表证明。
部分状态过期,接受较低但非零的永久状态增长速率。这种结果类似于涉及点对点网络的历史数据过期方案,每个节点只需存储较小比例的历史数据,从而降低整体的永久存储增长速率。
状态过期,同时扩展地址空间。这需要经过为期数年的过程,以确保地址格式转换方案可行且对现有应用程序安全。
状态过期,同时收缩地址空间。这也需要经过为期数年的过程,以处理地址冲突(包括跨链情况)带来的所有安全风险。
一个重要观点是,无论最终是否采用依赖于地址格式变更的状态过期方案,我们迟早都必须解决围绕地址空间扩展和收缩的棘手问题。目前,生成一次地址冲突需要大约 280 次哈希运算,这对于资源极为雄厚的参与者而言已经算得上是可行的:一块GPU可以进行约 227 次哈希运算,因此在一年内就能计算 252 次,那么全球约 230 块GPU就能在1/4年内完成一次冲突计算,而FPGA和ASIC技术还可以进一步加速。将来,这种攻击会变得更加普遍。因此,实施完全状态过期的实际成本可能并没有看上去那么高,因为无论如何我们都必须解决这一极具挑战性的地址问题。
与路线图其他部分的关系
采用状态过期可能会使从一种状态树格式平稳过渡到另一种新格式更加容易,因为不再需要过渡程序:你可以直接开始使用新格式创建状态树,稍后再通过硬分叉将旧树转换过来。因此,虽然状态过期本身相当复杂,但它确实有助于简化路线图中的其他方面。
功能精简
它解决了哪些问题?
安全性、可访问性和可信中立性的关键先决条件之一是简单性。如果一个协议设计简单美观,就能减少出现bug的概率。它增加了新开发者参与协议任何部分的机会。它更有可能公平公正,也更容易防范特殊利益的干扰。不过遗憾的是,协议和任何社会系统一样,默认情况下会随着时间推移变得越来越复杂。如果我们不希望以太坊陷入日益增长的复杂性漩涡,我们需要做两件事之一:(i)停止进行更改,使协议版本固化,(ii)能够真正删除功能并减少复杂度。一种中间路线就是对协议进行更少的更改,并在一段时间内至少削减一些复杂性,这也是可行的。本节将探讨如何减少或删除复杂度。
它是什么?工作原理是什么?
没有一个大手笔的单一修复方案可以减少协议的复杂度;这个问题的本质在于需要进行许多小修小补。
一个已经基本完成的例子,可以作为处理其他问题的蓝本,是移除SELFDESTRUCT操作码。SELFDESTRUCT是唯一一个在单个区块中可以修改无限数量存储槽的操作码,这需要客户端实现更多复杂逻辑以避免DoS攻击。该操作码最初的目的是启用自愿状态清除,允许随着时间推移减小状态大小。但在实践中,很少有人使用它。在坎昆升级中,该操作码被削弱,只允许自毁在同一交易中创建的账户。这解决了DoS问题,并使客户端代码得以大幅精简。将来,完全移除该操作码可能是恰当的。
到目前为止已经确定的一些协议精简机会的关键示例包括以下几点。首先,一些在EVM之外的示例;这些相对不具侵入性,因此更容易达成共识并在较短时间内实施。
RLP → SSZ转换: 最初,以太坊对象使用称为RLP的编码进行序列化。RLP是无类型的,且复杂程度不必要。如今,信标链使用SSZ,它在许多方面都更出色,包括支持序列化和哈希处理。最终,我们希望完全抛弃RLP,将所有数据类型转换为SSZ结构,这反过来也会使升级更容易。目前的相关EIP包括[1] [2] [3]。
删除旧的交易类型: 当前有太多交易类型,其中许多可能会被删除。一种更温和的替代方案是账户抽象功能,通过该功能,智能合约账户可以自主选择处理和验证旧式交易的代码。
日志改革: 日志功能会创建布隆过滤器和其他逻辑,增加了协议的复杂度,但实际上并没有被客户端所使用,因为它运行太慢。我们可以删除这些功能,而是努力使用现代技术(如SNARK)开发去中心化的日志读取工具作为替代品。
最终移除信标链同步委员会机制:同步委员会机制之所以被引入,是为了让轻节点能够验证以太坊网络。然而,它给协议增加了大量的复杂性。最终,我们将能够直接使用 SNARK 验证以太坊共识层,从而不再需要专门的轻节点验证协议。潜在地,如果共识机制发生变革,我们甚至可以更早地移除同步委员会,转而采用一种更"原生"的轻节点验证方案,即验证来自以太坊共识验证者随机子集的签名。
数据格式统一:当前,执行层状态存储在Merkle Patricia树中,共识层状态存储在SSZ树中,而Blob数据则使用KZG承诺提交。将来,采用统一的格式来存储区块数据和状态是有意义的。这些格式需要满足几个重要需求:(i)为无状态客户端提供简便的证明;(ii)实现数据序列化和纠删码;(iii)标准化数据结构。
移除信标链委员会:该机制最初被引入是为了支持一种特定的执行分片方案。但最终,我们通过第二层网络和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成本与合约中JUMPD EST总数成线性关系)来解决这个问题。EOF确实这样做了,不过要想从中获得协议简化的好处,EOF需要成为强制执行的规范。
查看更多:现有研究资料链接
现有研究资料链接
- 下一步Purge: https://notes.ethereum.org/I_AIhySJTTCYau_adoy2TA
- SELFDESTRUCT: https://hackmd.io/@vbuterin/selfdestruct
- 简单序列化(SSZ)相关EIP: [1] [2] [3]
- 无状态Gas成本变化: https://eips.ethereum.org/EIPS/eip-4762
- 线性内存定价: https://notes.ethereum.org/ljPtSqBgR2KNssu0YuRwXw
- 预编译(Precompile)移除: https://notes.ethereum.org/IWtX22YMQde1K_fZ9psxIg
- 布隆过滤器移除: https://eips.ethereum.org/EIPS/eip-7668
- 使用可递增验证计算(即递归STARK)实现链下安全日志检索的一种方式: https://notes.ethereum.org/XZuqy8ZnT3KeG1PkZpeFXw
待解决的问题及权衡考虑
进行这种功能简化时的主要权衡是(i)我们简化的程度和速度与(ii)向后兼容性。以太坊作为一条链的价值在于,你可以在上面部署一个应用程序,并确信它在未来多年仍然可以工作。同时,我们也有可能把这个理想推得太过火,正如[威廉·詹宁斯·布赖恩所言]"把以太坊钉在向后兼容性的十字架上受难"。如果整个以太坊网络只有两个应用程序在使用某个特性,而其中一个多年来没有任何用户,另一个几乎完全没被使用,仅保护着价值57美元的资产,那么我们就应该直接移除该特性,必要时可以自掏腰包赔偿那57美元给受害者。
更广泛的社会问题在于,如何建立一个标准化的流程,来进行非紧急情况下的向后不兼容改动。一种解决方式是检视并扩展现有先例,比如SELFDESTRUCT流程。这个流程大致如下:
- 第1步: 开始讨论移除特性X
- 第2步: 进行分析了解移除X会在何种程度上破坏应用程序,根据分析结果(i)放弃这个想法,(ii)按计划继续推进,或(iii)确定一种"最小破坏性"的修改方式来移除X,并采用这种方式继续推进
- 第3步: 提出正式的EIP来否决X。确保热门的高级基础设施(如编程语言、钱包)尊重这一点,停止使用该特性
- 第4步: 最后实际移除X
第1步和第4步之间应有一个长达数年的流程,并明确标示出哪些项目处于哪个阶段。届时,我们需要权衡功能移除流程的决心和速度,与将更多资源投入到其他方面的协议开发之间的平衡,但我们目前距离这个帕累托前沿还有一段距离。
EOF
EOF
一组被提出应用于 EVM 的重大变更是 EVM 对象格式 (EOF)。EOF 引入了许多变更,例如禁止 gas 可观察性、代码可观察性(即无 CODECOPY)、仅允许静态跳转。其目标是以保持向后兼容性的方式(原 EVM 仍将继续存在)允许 EVM 以更强的属性升级。
这具有创建添加新 EVM 功能并鼓励迁移到更严格但有更强保证的 EVM 的自然路径的优点。但缺点是,除非我们能找到最终淘汰和移除旧 EVM 的方式,否则它显著 增加了 协议复杂度。一个重要问题是: EOF 在 EVM 简化方案中扮演什么角色,尤其是在旨在降低 EVM 整体复杂度的目标下?
与路线图其他部分的关系
路线图中其余的"改进"提案也是简化旧功能的机会。重复上面的一些例子:
- 切换到单槽决定性可让我们移除委员会、重新调整经济学设计,并进行其他与权益证明相关的简化。
- 完全实现账户抽象化可让我们移除大量现有的交易处理逻辑,将其移至可取代所有 EOA 的"默认账户 EVM 代码"中。
- 如果我们将以太坊状态迁移到二进制哈希树,则可以与新版 SSZ 协调一致,使得所有以太坊数据结构均可按相同方式哈希。
一种更激进的方法:将协议的大部分内容转变为合约代码
一种更激进的以太坊简化策略是保持协议原样,但将其中大部分从协议特性转变为合约代码。
最极端的版本将是使得以太坊 L1 从技术上"仅"是信标链,并引入一个极简 VM(例如 RISC-V、Cairo或其他更加专门用于证明系统的 VM),允许任何人创建自己的 rollup。EVM 将成为这些 rollup 中的第一个。这讽刺地与 2019-20 年的执行环境提案产生了完全相同的结果,尽管 SNARK 大大增加了实施的可行性。
一种更温和的方法是在信标链与当前以太坊执行环境之间保持现有关系,但就地替换当前的 EVM。我们可以选择 RISC-V、Cairo 或其他 VM 作为新的"官方以太坊 VM",然后强制将所有 EVM 合约转换为解释原始代码逻辑的新 VM 代码(通过编译或解释)。理论上,这甚至可以以 EOF 的某个版本作为"目标 VM"来完成。