以太坊协议可能的未来(五):The Purge
2024-11-11 20:18
LXDAO
2024-11-11 20:18
订阅此专栏
收藏此文章


本期文章由 LXDAO 翻译小组成员 ChoeyGit、183Aaros 翻译, 校对 Ray、路鹿鹭、Elsa、Pignard。原文是 Possible futures of the Ethereum protocol, part 5: The Purge。

本系列文章翻译已获得原作者 Vitalik Buterin 授权。




01

译者前言


作为一名区块链技术、以太坊生态的关注者与学习者,当看到 Vitalik 提出的"The Purge"计划,深感振奋与期待。这项计划提出了一个独特的发展思路:在区块链追求功能扩展的背景下,转而通过优化和简化系统架构来提升网络效率。该计划主要聚焦于解决区块链数据膨胀问题,简化系统复杂度,以期降低参与门槛,提升网络的可持续性。

随着区块链技术的快速发展,网络数据持续增长、系统架构日益复杂的困难逐渐显现。特别是在 Layer 2 解决方案广泛应用的今天,提供了更高的扩展性,同时也为系统带来了额外的复杂性。在这样的背景下,本文的"The Purge"计划提出了一种新的思考方向。

这一技术路线是否能在不影响网络性能的前提下实现有效瘦身?如何在简化和功能之间取得平衡?接下来请跟随文章一起对这些问题进行深入探讨。



02

本文概述


本文共约 10000 字,有 3 个部分,阅读完本文预计需要 50 分钟。

  1. 历史过期(History expiry)

  2. 状态过期(State expiry)

  3. 特性清理(Feature cleanup)




03

正文内容


《以太坊协议可能的未来(五):The Purge》

编译:ChoeyGit、183Aaros

特别感谢 Justin Drake、Tim Beiko、Matt Garnett、Piper Merriam、Marius van der Wijden 和 Tomasz Stanczak 的反馈和审阅。

以太坊面临这样一个挑战:默认情况下,区块链协议的膨胀和复杂度都会随时间推移而增长。这种情况主要体现在两个方面:

历史数据:无论何时(在链上)产生的交易、创建的账户,都需要被所有客户端永久存储,同时新客户端在进行全节点同步时也需要下载全部数据。这导致即使链的处理容量保持不变,客户端的负载和同步时间也会持续增加。

协议特性:添加新特性比移除旧特性要容易得多,这导致代码复杂度会随时间不断增加。

为了以太坊可持续的长期发展,我们需要找到对抗这两种趋势的强有力措施:随着时间的推移,不断降低复杂度和膨胀。同时,我们还需要保留区块链的核心特性:永久性。你可以存储 NFT、一封写在交易数据(calldata)中的情书、或者在链上部署一个包含百万美金的智能合约。即使你在山洞中隐居十年,出来的时候发现它仍在那里等着你去阅读和交互。去中心化应用(dapps)需要在确信自身应用运行所依赖的组件,不会因升级而导致破坏性变更的前提下 ,才能够放心地实现完全去中心化并移除它们的升级密钥 ——— 特别是 L1 本身。


The Purge,2023 年路线图

在保持连续性的同时,最小化或扭转数据膨胀、复杂度和衰退,我们要在这两种需求之间寻找一个平衡。我们相信只要我们在这方面投入研究,这绝对是可以实现的。生物体就可以做到这一点:虽然大多数人会随时间衰老,但也有少数幸运儿不会。甚至社会系统也可以实现超长寿命。以太坊已经在几个方面展示了成功案例:工作量证明机制(Pow)已经被淘汰, SELFDESTRUCT 操作码(opcode)基本已消失,信标链(beacon chain)节点现在只存储最近六个月的历史数据。这是以太坊在长期可扩展性、技术可持续性甚至安全性方面的终极挑战,旨在为以太坊找到一条更具普适性的发展道路,并朝着长期稳定的最终目标迈进。

The Purge :关键目标

  • 降低客户端的存储要求,通过减少或消除每个节点永久存储所有历史数据的需求,甚至可能减少对存储状态数据的依赖。

  • 通过消除不必要的特性来降低协议复杂度。

本章内容

  • 历史过期(History expiry)

  • 状态过期(State expiry)

  • 特性清理(Feature cleanup)


历史过期


我们要解决什么问题?

截至本文撰写时,一个全同步(full-synced)的以太坊节点需要大约 1.1 TB 的磁盘空间用于执行客户端,另外还需要几百 GB 用于储存共识客户端。其中绝大部分是历史数据:包括历史区块、交易和收据数据,这些数据大多已有多年历史。这意味着即使 gas 上限完全不增加,节点的大小每年仍会增加数百 GB。

它是什么,如何做到的?

历史存储问题有一个关键的简化特性:由于每个区块通过哈希链接(以及其他结构)并指向前一个区块,这意味着只要对当前状态达成了共识,就代表着对历史达成共识。只要网络对最新区块达成了共识,任何历史区块、交易或状态(账户余额、nonce、代码、存储)都可以由任何单个参与者提供,并附带着默克尔证明(Merkle proof),它允许除了单个参与者以外的所有人为验证其正确性。当共识使用 N/2-of-N 的信任模型,但历史是 1-of-N 的信任模型。

这为我们存储历史数据的方式提供了许多选择。一个自然的选择是让网络中的每个节点只存储一小部分数据。这就像 torrent networks 几十年来的运作方式:虽然整个网络存储和分发数百万个文件,但每个参与者只存储和分发其中的一小部分。也许与直觉相反,这种方法并不一定会降低数据的鲁棒性。如果通过降低节点运行成本,我们能够实现一个拥有 10 万个节点的网络,其中每个节点随机存储 10% 的历史数据,那么每条数据就会被复制 1 万次——这与一个拥有 1 万个节点且每个节点存储所有数据的网络具有完全相同的复制因子(replication factor)。

如今,以太坊已经开始逐步摆脱所有节点永久存储所有历史数据的模式。共识区块(即与权益证明共识相关的部分)仅存储约 6 个月。Blobs 仅存储约 18 天。EIP-4444 提案旨在为历史区块和收据引入一年的存储期限。长期目标是建立一个可协调的的存储期限(可能是约 18 天),在此期间每个节点负责存储所有数据,之后通过由以太坊节点组成的点对点网络以分布式方式存储较早的数据。

纠删码(erasure codes)可以在保持相同副本因子(replication factor)的同时提高数据鲁棒性。实际上,为了支持数据可用性采样,Blobs 本身就已经使用了纠删码技术。最简单的解决方案可能就是重复使用这种纠删码技术,并将执行层和共识层的区块数据也放入 Blobs 中。

与现研究有哪些联系?

  • EIP-4444 提案:

    https://eips.ethereum.org/EIPS/eip-4444

  • torrent networks 与 EIP-4444 提案:

    https://ethresear.ch/t/torrents-and-eip-4444/19788

  • Portal 网络: 

    https://ethereum.org/en/developers/docs/networking-layer/portal-network/

  • Portal 网络与 EIP-4444 提案:

    https://github.com/ethereum/portal-network-specs/issues/308

  • Portal 中 SSZ 对象的分布式储存与检索: 

    https://ethresear.ch/t/distributed-storage-and-cryptographically-secured-retrieval-of-ssz-objects-for-portal-network/19575

  • 如何提高 Gas Fee 上限 (Paradigm): 

    https://www.paradigm.xyz/2024/05/how-to-raise-the-gas-limit-2

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

剩余的主要工作涉及构建和集成一个具体的分布式历史存储解决方案 - 至少要包含执行层的历史数据,最终还要包括共识层数据和 Blobs。最简单的解决方案有两个:(i) 直接引入现有的 torrent 库,以及 (ii) 一个称为 Portal 网络的以太坊原生解决方案。一旦这两个方案中的任何一个被引入,我们就可以启用 EIP-4444。EIP-4444 本身不需要硬分叉,但需要一个新的网络协议版本。因此,让所有客户端同时启用该功能是很有价值的,否则当客户端连接到其他节点时,可能会出现期望下载完整历史数据,但实际无法获取的故障风险。

主要权衡的地方在于我们要在多大程度上努力确保“上古”历史数据的可用性。最简单的解决方案是从明天开始就停止存储“上古”历史数据,转而依赖现有的归档节点和各种中心化服务供应商来进行数据复制。这很容易实现,但这会削弱以太坊作为永久记录存储地的地位。更困难但更安全的路径是首先构建并集成 torrent networks,以分布式方式存储历史数据。在这里的"我们有多努力"有两个维度:

  1. 我们需要投入多少的努力去确保最大数量的节点真正存储了所有数据?

  2. 我们应该在多大程度上将历史数据存储整合到协议中?

对于维度(1)而言,一个极度严谨的方案就会涉及到托管证明(proof of custody):实际要求每个权益证明验证者存储一定比例的历史数据,并定期进行加密检查以确保他们验证其存储情况。另一个更温和的方案则是设定一个自愿标准,让每个客户端自愿存储一定比例的历史数据。

对于维度(2)而言,基础实现方案是直接采用现有成果:Portal 已经储存了包含完整以太坊历史的 ERA 文件。一个更全面的实现方案是将其实际连接到同步过程中,这样如果有人想要同步一个存储完整历史的节点或归档节点,即使在线上没有其他归档节点的情况下,也可以直接从 Portal 网络进行同步。

他如何与路线图中的其他部分互动

如果我们想要让运行或启动节点变得极其简单,那么降低历史数据存储需求可以说比无状态化更为重要:在节点所需的 1.1 TB 存储空间中,状态数据约占 300 GB,而历史数据则占据剩余的约 800 GB。让以太坊节点能在智能手表上运行,且只需几分钟就能完成设置的愿景,只有在同时实现了无状态化和 EIP-4444 的情况下才能实现。

限制历史数据的储存为“只需要通过支持最新版本的协议就可以让较新的以太坊节点实现”提高了可行性,这也让节点实现变得更简单。例如,由于 2016 年 DoS 攻击期间创建的空存储槽位已全部被移除,现在可以安全删除许多相关的代码行。同样,既然向权益证明(PoS)的切换已成为“上古”历史,客户端现在可以安全地移除所有与工作量证明(PoW)相关的代码。

状态过期

它解决了什么问题?

即使我们移除了客户端存储历史数据的需求,客户端的存储需求仍会持续增长,每年增加约 50 GB,这是因为状态数据在持续增长:账户余额和 nonce 值、合约代码和合约存储。用户只需支付一次性成本,就能给现在和未来的以太坊客户端施加永久的储存负担。

状态数据比历史数据更难“过期”,这是因为 EVM 的基础设计建立在这样一个假设之上:一旦状态对象被创建,它就会永久存在,并且可以被任何交易在任何时候读取。如果我们引入无状态化,有一种观点认为这个问题可能并没有那么严重:只有特定类别的区块构建者才需要实际存储状态数据,而所有其他节点(甚至包括 inclusion list 的生成!)都可以以无状态方式运行。然而,另一种观点认为我们不应过度依赖无状态化,最终我们可能还是需要状态过期以保证以太坊的去中心化。

它是什么,如何做到的?

如今,当你创建一个新的状态对象(可以通过以下三种方式之一实现:(i) 向新账户发送 ETH,(ii) 利用代码创建的新账户,(iii) 设置此前未被使用的存储槽,该状态对象将永久存在于状态中。而我们想要的是让对象随时间自动过期。做到这一点需要实现以下三个目标

  1. 效率:运行过期流程时不应该花费大量的额外计算

  2. 用户友好性:如果某人进入山洞五年后重新出现,他们不应该失去对其 ETH、ERC20 代币、NFT、CDP 头寸等资产的访问权限

  3. 开发者友好性:开发者不应该被要求切换到一个完全陌生的思维模型。此外,那些目前已经固化且不再更新的应用程序应该能继续正常运行

如果不考虑满足这些目标,解决问题其实很容易。例如,你可以让每个状态对象都存储一个过期日期计数器(可以通过销毁 ETH 来延长期限,这种延长可以在每次读写时自动进行),并设置一个循环遍历状态以删除过期状态对象的流程。然而,这会引入额外的计算(甚至增加存储需求),而且显然不满足用户友好性要求。对开发者来说,处理存储值有时会重置为零的极端情况也会很困难。如果将过期计时器设置为合约级别,这在技术上确实让开发者更轻松,但在经济性方面却带来更多困难:开发者需要考虑如何将持续的存储成本“转嫁”给他们的用户。

这些问题困扰以太坊核心开发社区多年,期间出现过“区块链租金(blockchain rent)”和“激活重生(regenesis)”等提案。最终,我们整合了这些提案中最好的部分,得出了两类“已知的最不坏的情况”:

  • 局部状态过期解决方案

  • 基于地址周期的状态数据过期机制提案

局部状态过期

所有局部状态过期提案都遵循相同的原则。我们将状态数据分割成多个数据块。每个人都永久存储一个“顶层映射表”,用于标记哪些数据块是空的或非空的。每个数据块内的数据只有在近期被访问过的情况下才会被存储。同时存在一个“激活”机制:如果某个数据块不再被存储,任何人都可以通过提供该数据的证明来使其恢复。

这些提案之间的主要区别在于:(i) 如何定义“近期”,以及 (ii) 如何定义“数据块”。其中一个具体的提案是 EIP-7736,它基于为 Verkle 树引入的“茎叶结构(stem-and-leaf)”设计(尽管它与任何形式的无状态化都兼容,例如二叉树)。在这个设计中,相邻的头部、代码和存储槽都存储在同一个“茎”下。每个茎下存储的数据最多为 256 * 31 = 7,936 字节。在许多情况下,一个账户的整个头部、代码以及许多关键存储槽都会存储在同一个茎下。如果某个茎下的数据在 6 个月内没有被读取或写入,这些数据就不再存储,取而代之的是只存储一个 32 字节的承诺(“存根”)。未来访问这些数据的交易需要“激活”这些数据,并提供一个可以与存根(stub)进行检查的证明。

还有其他方式可以实现类似的想法。例如,如果账户级别的粒度不够细,我们可以设计一个方案,让状态树的每 1/232 的部分都由类似的茎叶机制(stem-and-leaf )来管理。

但这种方法会使激励机制的实现更为棘手:攻击者可能通过在单个子状态树中存入大量数据,然后每年发送一个交易来“更新状态树“,从而强制客户端永久存储大量状态。如果将更新成本设置为与状态树的大小成正比(或更新持续时间与树的大小成反比),那么攻击者可能通过在同一个子级状态树中存入大量数据来骚扰其他用户。我们可以尝试通过基于子级状态树大小的动态粒度来限制这两个问题:例如,每连续的 2^16 = 65536 个状态对象可以被视为一个“组”。然而,这些想法都更为复杂;相比之下,基于茎的方法简单,且能够很好地协调激励机制,因为通常一个茎下的所有数据都与同一个应用程序或用户相关。

基于地址周期的状态过期机制提案

如果我们想完全避免永久性的状态增长,甚至连 32 字节的存根都不想保留,该怎么办?这是一个棘手的问题,因为会出现激活冲突:假设一个状态对象被移除后,后续的 EVM 执行在完全相同的位置放置了另一个状态对象,而这时关心原始状态对象的人回来尝试恢复它,会发生什么?在局部状态过期方案中,“存根”可以防止新数据被创建。但在完全状态过期方案中,我们连存根都无法存储。

基于地址周期(address-period-bssed)的设计是解决这个问题最好的已知方案。它不是使用一棵状态树来存储整个状态,而是维护一个持续增长的状态树列表,任何被读取或写入的状态都会被保存在最新的状态树中。每个周期(比如说:1 年)都会添加一棵新的空状态树。较旧的状态树会被完全冻结。全节点只需要存储最近的两棵状态树。如果某个状态对象在两个周期内都未被访问,因此落入了过期的状态树中,它仍然可以被读取或写入,但相关交易需要为其提供默克尔证明 —— 一旦证明成功,该状态的副本就会再次被保存在最新的状态树中。

使这一切对用户和开发者友好的一个关键概念是“地址周期”。地址周期是地址的一部分。一个关键规则是:具有地址周期 N 的地址只能在周期 N 期间或之后被读取或写入(即当状态树列表长度达到 N 时)。如果你要保存一个新的状态对象(例如:一个新合约或一个新的 ERC20 余额),只要确保将该状态对象放入地址周期为 N 或 N-1 的合约中,就可以立即保存,而无需提供之前该位置为空的证明。但另一方面,对更早地址周期的状态进行任何添加或编辑都需要提供证明。

这个设计保留了以太坊当前的大部分特性,额外的计算开销很小,而且允许应用程序几乎可以按照现在的方式编写(不过 ERC20 需要重写,以确保地址周期为 N 的地址的余额被存储在一个同样具有地址周期 N 的子合约中),并解决了“用户进入山洞五年”的问题。然而,它有一个重大问题:地址需要扩展到超过 20 字节才能容纳地址周期

地址空间扩展

一个提议是引入一种新的 32 字节地址格式,其中包含版本号、地址周期号和扩展哈希值。

红色部分是版本号。这里橙色的四个零是预留的空间,未来可用于存放分片号。绿色部分是地址周期号。蓝色部分是 26 字节的哈希值。

这里的关键挑战是向后兼容性。现有的合约是基于 20 字节地址设计的,而且经常使用紧凑的字节打包技术,这些技术明确假设地址长度恰好是 20 字节。解决这个问题的一个思路是使用转换映射表,让与新式地址交互的旧式合约看到的是新式地址的 20 字节哈希值。然而,要确保这种方式的安全性还涉及许多复杂的问题。

地址空间收缩

另一种方法则相反:我们立即禁用一个大小为 2^128 的地址子范围(例如:所有以 0xffffffff 开头的地址),然后使用该范围来引入包含地址周期和 14 字节哈希值的地址。

这种方法的主要代价是,它为反事实地址(counterfactual addre sses)带来了安全风险:这些地址虽然持有资产或权限,但其代码尚未发布到链上。风险在于有人可能创建一个地址,声称拥有一段(尚未发布的)代码,但同时还有另一段有效代码也能哈希到相同地址。目前计算这样的碰撞需要 2^80 次哈希运算;而地址空间收缩会将这个数字降低到非常容易达到的 2^56 次哈希运算。

主要的风险领域是那些不由单一所有者持有的反事实地址钱包,这在今天是相对罕见的情况,但随着我们进入 L2 多层拓展(multi-L2)世界,这种情况可能会变得更加普遍。唯一的解决方案就是接受这个风险,并且识别出所有可能出现这个问题的常见使用场景,并提出有效的规避方案。

与现有研究有哪些联系?

早期提案

  • 区块链租金(Blockchain rent):

    https://github.com/ethereum/EIPs/issues/35

  • 激活重生提案(Regenesis):

    https://ethresear.ch/t/regenesis-resetting-ethereum-to-reduce-the-burden-of-large-blockchain-and-state/7582

以太坊状态大小管理理论: 

https://hackmd.io/@vbuterin/state_size_management

实现无状态和状态过期的几种可能路径: 

https://hackmd.io/@vbuterin/state_expiry_paths

部分状态过期提案

EIP-7736: https://eips.ethereum.org/EIPS/eip-7736

地址空间拓展文档

  • 原始提案:

    https://ethereum-magicians.org/t/increasing-address-size-from-20-to-32-bytes/5485

  • Ipsilon 审阅: 

    https://notes.ethereum.org/@ipsilon/address-space-extension-exploration

  • 博客文章审阅: 

    https://medium.com/@chaisomsri96/statelessness-series-part2-ase-address-space-extension-60626544b8e6

失去碰撞抗性会带来什么问题: 

https://ethresear.ch/t/what-would-break-if-we-lose-address-collision-resistance/11356

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

我看到四条在未来有可能性的道路:

实现无状态化,而不引入状态过期机制。状态数据会持续增长(尽管增长缓慢:可能在几十年内都不会超过 8 TB),但只需要由相对专业的用户群体持有:甚至权益证明(PoS)验证者都不需要持有状态。唯一需要访问部分状态的功能是生成纳入列表,但我们可以通过去中心化的方式实现这一点:每个用户负责维护包含其自身账户的那部分状态树。当用户广播交易时,会同时广播验证步骤中访问的状态对象的证明(这适用于外部拥有账户 EOA 和 ERC-4337 账户)。无状态验证者随后可以将这些证明组合成完整包含列表的证明。

实施局部状态过期机制,接受一个虽然大幅降低但仍然非零的永久状态大小增长率。这个结果可以说类似于历史过期提案中涉及点对点网络的情况:每个客户端需要存储一个较低但固定比例的历史数据,从而接受一个降低但非零的永久历史存储增长率。

实施状态过期机制,同时进行地址空间扩展。这个过程将持续很多年,以确保地址格式转换方法是可行且安全的,这也包括对现有应用程序的安全性保障。

实施状态过期机制,同时进行地址空间收缩。这个过程将持续很多年,以确保所有与地址碰撞相关的安全风险都得到处理,包括跨链场景下的风险。

有一个重要观点是,无论是否实施依赖于地址格式变更的状态过期方案,这些围绕地址空间扩展和收缩的棘手问题最终都需要解决。目前,生成一个地址碰撞大约需要 2^80 次哈希运算,这种计算负载对于资源极其充足的参与者来说已经是可行的:一个 GPU 每秒可以进行约 2^27 次哈希运算,因此运行一年可以计算 2^52 次,这样全球约 2^30 个 GPU 在大约 1/4 年内就能计算出一个碰撞,而 FPGA 和 ASIC 还可以进一步加快这个速度。在未来,这种攻击将会对越来越多的人开放。因此,实施完整状态过期的实际成本可能并没有看上去那么高,因为无论如何我们都必须解决这个极具挑战性的地址问题。

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

实施状态数据过期机制可能会使状态树格式之间的转换变得更容易,因为不需要转换过程:你可以直接用新格式创建新的状态树,之后通过硬分叉来转换旧状态树。因此,尽管状态数据过期机制很复杂,但它确实在简化路线图的其他方面带来了好处。

特性清理

我们要解决什么问题?

安全性、可访问性和可信中立性的关键前提之一是简单性。如果一个协议优雅且简单,就能降低出现漏洞的可能性。这也会增加新开发者能够参与并处理其任何部分的可能性。同时,这种简单性使得协议更有可能公平,也更容易抵御特殊利益的影响。不幸的是,协议和任何社会系统一样,默认会随时间变得越来越复杂。如果我们不希望以太坊陷入不断增加复杂性的黑洞,我们需要做以下两件事之一:(i)停止变更并让协议固化,(ii)能够实际移除某些功能并降低复杂性。另外还有一条中间路线也是可能的:减少对协议的变更,同时随着时间推移逐步降低一些复杂性。本节将讨论如何降低或移除复杂性。

它是什么,如何做到的

不存在一个能够降低协议复杂性的统一大型解决方案;问题的本质在于存在许多小的修复方法。

这里有一个已基本完成且可以作为处理其他类似情况参考的例子,那就是 SELFDESTRUCT 操作码的移除。SELFDESTRUCT 操作码是唯一一个能在单个区块内修改无限数量存储槽的操作码,这要求客户端实现更多的复杂性来避免 DoS 攻击。这个操作码最初的目的是实现自愿的状态清理,使状态数据大小能随时间减少。但实践中很少有人最终使用它。在 Dencun 硬分叉中,该操作码被削弱,只允许自毁在同一交易中创建的账户。这解决了 DoS 问题,并使客户端代码得到显著简化。在未来,完全移除这个操作码可能是合理的。

目前已确定的一些关键的协议简化机会包括以下几点。首先是一些 EVM 之外的例子;这些变更相对来说影响较小,因此更容易在短期内达成共识并实施。

  • RLP 到 SSZ 的转换:最初,以太坊对象使用一种称为 RLP 的编码方式进行序列化。RLP 是无类型的,且存在不必要的复杂性。如今,信标链使用 SSZ,这在许多方面都有显著优势,不仅支持序列化,还支持哈希运算。我们希望最终完全摒弃 RLP,将所有数据类型转换为 SSZ 结构体,这反过来会使升级变得更加容易。目前相关的 EIP 提案包括 [1]https://eips.ethereum.org/EIPS/eip-6465

    [2]https://eips.ethereum.org/EIPS/eip-6465

    [3]https://eips.ethereum.org/EIPS/eip-6465

  • 移除旧交易类型:当前存在太多交易类型,其中许多都可以被移除。相比完全移除,一个更温和的替代方案是引入账户抽象特性,允许智能账户根据需要选择包含处理和验证旧式交易的代码。

  • 日志改造:日志会创建布隆过滤器(bloom filters)和其他逻辑,这些增加了协议的复杂性,但由于速度太慢,客户端实际上并未使用它们。我们可以移除这些特性,转而投入精力开发替代方案,比如使用 SNARKs 等现代技术的协议外去中心化日志读取工具。

  • 信标链最终移除同步委员会机制:同步委员会机制最初是为了实现以太坊的轻客户端验证而引入的。然而,它给协议增加了显著的复杂性。最终,我们将能够使用 SNARKs 直接验证以太坊共识层,这样就不再需要专门的轻客户端验证协议。通过创建一个更“原生”的轻客户端协议(该协议涉及验证以太坊共识验证者随机子集的签名),共识的变更可能使我们更早地移除同步委员会。

  • 数据格式统一化:目前,执行状态存储在 Merkle Patricia 树中,共识状态存储在 SSZ 树中,而 Blobs 则使用 KZG 承诺进行提交。在未来,为区块数据和状态数据分别制定统一格式是有意义的。这些格式将满足所有重要需求:(i) 为无状态客户端提供简单的证明,(ii) 数据的序列化和纠删码编码,(iii) 标准化的数据结构。

  • 移除信标链委员会:这个机制最初是为了支持执行分片的特定版本而引入的。然而,我们最终通过二层网络和数据块实现了分片。因此,委员会变得不再必要,目前正在推进移除它们的工作。

  • 移除混合字节序:EVM 采用大端字节序,而共识层采用小端字节序。重新统一并将所有内容统一为其中一种字节序(可能是大端序,因为 EVM 更难改变)是有意义的。

现在,让我们来看看一些在 EVM 内的例子:

  • gas 机制的简化:当前的 gas 规则在限制验证区块所需资源量方面并未得到很好的优化。主要的例子包括:(i) 读写存储的成本,这本应该用于限制区块中的读写次数,但目前实现得相当随意;以及 (ii) 内存填充的规则,目前很难估算 EVM 的最大内存消耗。提议的修复方案包括无状态 gas 成本变更(将所有与存储相关的成本统一为一个简单公式),以及这个关于内存定价的提案。

  • 预编译合约的移除:以太坊当前的许多预编译合约既不必要地复杂又很少被使用,且在险些发生的共识失败事件中占据了很大比例,却实际上没有任何应用在使用它们。处理这个问题有两种方式:(i) 直接移除预编译合约,(ii) 用实现相同逻辑的 EVM 代码替换它(这不可避免的会增加成本)。这份 EIP 草案建议首先对根身份预编译合约进行这样的处理;在这之后,RIPEMD 160、MODEXP 和 BLAKE 可能成为移除的候选对象。

  • gas 可观察性的移除:使 EVM 执行过程无法再查看剩余 gas 总量。这会影响一些应用程序的运行(最明显的是 sponsored transactions 代付交易),但将使未来的升级变得更容易(例如,用于更高级版本的多维 gas)。EOF 规范已经使 gas 不可观察,不过为了实现协议简化的目的,EOF 需要成为强制性规范。

  • 静态分析的优化:当前的 EVM 代码很难进行静态分析,特别是因为跳转(jumps 代码)可以是动态的。这也使得(将 EVM 代码预编译成其他语言)优化 EVM 的实现变得更加困难。我们可以通过移除动态跳转来解决这个问题(或者使其代价更高,例如,使 gas 成本与合约中 JUMPDEST 的总数呈线性关系)。EOF 已经实现了这一点,不过要从中获得协议简化的收益,则需要强制执行 EOF。

与现有研究有哪些联系?

  • Purge 的下一阶段: 

    https://notes.ethereum.org/I_AIhySJTTCYau_adoy2TA

  • 合约销毁:

    https://hackmd.io/@vbuterin/selfdestruct

  • SSZ 化相关的 EIPS: 

    • https://eips.ethereum.org/EIPS/eip-6493

    • https://eips.ethereum.org/EIPS/eip-6466

    • https://eips.ethereum.org/EIPS/eip-6465

  • 无状态 gas 成本变更:

    https://eips.ethereum.org/EIPS/eip-4762

  • 现行内存定价: 

    https://notes.ethereum.org/ljPtSqBgR2KNssu0YuRwXw

  • 预编译合约的移除:

    https://notes.ethereum.org/IWtX22YMQde1K_fZ9psxIg

  • Bloom 过滤器的移除:

    https://eips.ethereum.org/EIPS/eip-7668

  • 使用增量可验证计算(即:递归 STARKs)进行链下安全日志检索的方法:

    https://notes.ethereum.org/XZuqy8ZnT3KeG1PkZpeFXw

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

进行这类功能简化的主要权衡在于:(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)还有很远的距离。

EOF

EVM 对象格式(EOF)是一个已经被提议的 EVM 重大变更集。EOF 引入了大量改变,例如禁止 gas 可观察性、禁止代码可观察性(即不允许 CODECOPY)、仅允许静态跳转等。其目标是让 EVM 能够进行更多升级,以实现更强大的特性,同时保持向后兼容性(因为 pre-EOF 版本的 EVM 仍将继续存在)。

这种方案的优点是为添加新的 EVM 功能提供了一条自然的路径,并鼓励迁移到具有更强保障的更严格的 EVM。其缺点是会显著增加协议复杂性,除非我们能找到方法最终废弃并移除旧版 EVM。一个重要的问题是:在 EVM 简化提案中 EOF 扮演什么角色,特别是当整体目标是降低 EVM 复杂性的情况下?

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

路线图中的许多“优化”提案同时也是简化旧功能的机会。重复一些上述例子:

  • 切换到单时隙最终性给我们提供了移除委员会、重构经济模型以及进行其他权益证明相关简化的机会。

  • 完整实现账户抽象让我们可以移除大量现有的交易处理逻辑,方法是将这些逻辑转移到一段“默认账户 EVM 代码”中,所有 EOA 都可以被该代码替代。

  • 如果我们将以太坊状态迁移到二进制哈希树,这可以与新版本的 SSZ 协调统一,使得所有以太坊数据结构都能以相同的方式进行哈希处理。

一个更激进的方法是:将协议的大部分内容转换为合约代码。

一个更激进的以太坊简化策略是:保持协议本身不变,但将其大部分内容从协议特性转变为合约代码。

这种方法最极端的版本是:让以太坊 L1 在“技术上”仅作为信标链存在,同时引入一个最小化的虚拟机(例如 RISC-V、Cairo 或者某种更简化的、专门用于证明系统的虚拟机),使得任何人都能创建自己的 rollup。EVM 则会转变为这些 rollup 中的第一个。有趣的是,这个结果与 2019-20 年的执行环境提案完全一致,不过 SNARKs 使得实际实施这一方案的可能性大大提高。


欢迎阅读本系列其他文章:

《以太坊协议可能的未来(一):The Merge》

《以太坊协议可能的未来(二):The Surge》

《以太坊协议可能的未来(三):The Sourage》

《以太坊协议可能的未来(四):The Verge》


(点击“阅读原文”跳转本文的英文原文链接)


·END·


编译 | ChoeyGit、183Aaros

编辑 & 排版 | 环环
设计 | Daisy


【免责声明】市场有风险,投资需谨慎。本文不构成投资建议,用户应考虑本文中的任何意见、观点或结论是否符合其特定状况。据此投资,责任自负。

LXDAO
数据请求中
查看更多

推荐专栏

数据请求中
在 App 打开