bot.gif
close
正在加载
Vitalik:以太坊协议可能的未来—The Purge
互联网 · 2024-10-28 13:30
67252
摘要
以太坊面临的挑战之一是,协议的膨胀和复杂性会随着时间推移而增加。这发生在两个方面,历史数据和协议功能 。
币界网报道:

作者:以太坊创始人Vitalik;编译:邓通,

按:本文为以太坊创始人Vitalik近期发表的“以太坊协议的未来发展”系列文章的第五部分“Possible futures of the Ethereum protocol, part 5: The Purge”,第四部分见“Vitalik:以太坊的未来The Verge”。第三部分见“Vitalik:以太坊The Scourge阶段的关键目标”,第二部分见“Vitalik:The Surge阶段以太坊协议应该怎么发展”,第一部分见“以太坊PoS还有哪些可以改进”。以下为第五部分全文:


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

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

cAsxEITlhZkzjvaVDQT9VqWQqe3PLm9Qiadwvn99.jpeg

The Purge, 2023 年路线图。

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

The Purge:主要目标

  • 通过减少或消除每个节点永久存储所有历史记录的需求来减少客户端存储要求,甚至可能最终声明

  • 通过消除不需要的功能来降低协议复杂性

历史数据过期

它解决了什么问题?

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

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

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

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

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

3CCZmM1irqCJHQ5oosNlQ251jxdKRvF94cXdCA59.jpeg

可以使用纠删码来提高稳健性,同时保持复制因子不变。事实上,为了支持数据可用性采样,blob 已经采用纠删码。最简单的解决方案可能是重新使用此纠删码,并将执行和共识块数据也放入 blob 中。

现有哪些研究?

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

Torrents 和 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 限制(范式): https://www.paradigm.xyz/2024/05/how-to-raise-the-gas-limit-2

剩下要做什么,又有哪些权衡?

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

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

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

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

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

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

限制历史存储也使较新的以太坊节点实现更可行地仅支持协议的最新版本,这使它们变得更加简单。例如,由于 2016 年 DoS 攻击期间创建的空存储槽已全部被删除,因此可以安全地删除许多代码行。既然切换到权益证明已成为历史,客户端可以安全地删除所有与工作量证明相关的代码。

状态数据过期

它解决了什么问题?

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

状态比历史记录更难“过期”,因为 EVM 的设计基本假设是,一旦创建了状态对象,它将永远存在,并且可以随时被任何交易读取。如果我们引入无状态,有人认为这个问题可能没那么糟糕:只有一类专门的区块构建器才需要实际存储状态,所有其他节点(甚至包含列表生成!)都可以无状态运行。然而,有人认为我们不想过分依赖无状态,最终我们可能希望状态过期以保持以太坊的去中心化。

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

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

无需满足这些目标,问题也很容易解决。例如,您可以让每个状态对象还存储一个计数器来记录其到期日期(可以通过销毁 ETH 来延长,这可以在读取或写入时自动发生),并有一个循环遍历状态以删除过期状态对象的过程。但是,这引入了额外的计算(甚至存储要求),并且肯定不能满足用户友好性要求。开发人员也很难推理涉及存储值有时重置为零的极端情况。如果您将到期计时器设为合约范围内,这在技术上使开发人员的工作变得更容易,但会使经济变得更加困难:开发人员必须考虑如何将持续的存储成本“转嫁”给他们的用户。

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

部分状态过期

部分状态过期提案都遵循相同的原则。我们将状态分成块。每个人都永久存储“顶层映射”,其中哪些块是空的或非空的。每个块中的数据仅在最近访问过的情况下才会存储。有一个“复活”机制,如果某个块不再存储,任何人都可以通过提供数据是什么的证明来恢复该数据。

这些提案之间的主要区别是:(i)我们如何定义“最近”,以及(ii)我们如何定义“块”?一个具体的提案是 EIP-7736,它建立在为 Verkle 树引入的“茎叶”设计之上(尽管与任何形式的无状态树兼容,例如二叉树)。在这种设计中,彼此相邻的标头、代码和存储槽存储在同一个“茎”下。存储在茎下的数据最多可以是 256 * 31 = 7,936 字节。在许多情况下,账户的整个标题和代码以及许多密钥存储槽都将存储在同一个主干下。如果给定主干下的数据在 6 个月内未被读取或写入,则不再存储数据,而是只存储对数据的 32 字节承诺(“存根”)。未来访问该数据的交易将需要“复活”数据,并提供与存根核对的证明。

fSOCmKUg6ovk9kmRWRgZgLoGkNPdlLOh9MCDofTr.jpeg

还有其他方法可以实现类似的想法。例如,如果账户间隔不够,我们可以制定一个方案,其中树的每个 1/232 部分都由类似的茎叶机制控制。

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

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

如果我们想完全避免任何永久性的状态增长,即使是 32 字节的存根,该怎么办?这是一个难题:如果状态对象被删除,稍后的 EVM 执行将另一个状态对象放在完全相同的位置,但之后关心原始状态对象的人回来并试图恢复它,该怎么办?对于部分状态过期,“存根”会阻止创建新数据。对于完整状态过期,我们甚至无法存储存根。

基于地址周期的设计是解决此问题的最佳方法。我们有一个不断增长的状态树列表,而不是用一棵状态树存储整个状态,并且任何读取或写入的状态都会保存在最新的状态树中。每周期(想想:1 年)添加一次新的空状态树。较旧的状态树是固定的。完整节点只需要存储最近的两棵树。如果状态对象在两个周期内未被触及并因此落入过期树,它仍然可以被读取或写入,但交易需要为其证明 Merkle 证明 —— 一旦这样做,副本将再次保存在最新的树中。

on7iQgfP2y1IpojhP5zFHqOsNdP3xAk2oiqPB8w5.jpeg

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

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

地址空间扩展

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

0x01000000000157aE408398dF7E5f4552091A69125d5dFcb7B8C2659029395bdF

红色是版本号。此处橙色的四个零表示空白,将来可以容纳分片号。绿色是地址周期号。蓝色是 26 字节哈希值。

此处的关键挑战是向后兼容性。现有合约是围绕 20 字节地址设计的,并且通常使用紧密字节打包技术,明确假设地址正好是 20 字节长。解决这个问题的一个想法是使用转换图,其中与新式地址交互的旧式合约将看到新式地址的 20 字节哈希值。但是,要确保其安全,需要付出相当大的努力。

地址空间收缩

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

0xffffffff000169125d5dFcb7B8C2659029395bdF

这种方法做出的关键牺牲是,它为反事实地址引入了安全风险:持有资产或权限但其代码尚未发布到链上的地址。风险涉及有人创建一个地址,该地址声称拥有一段(尚未发布的)代码,但还有另一段有效代码,该代码的哈希值指向同一地址。计算这样的碰撞今天需要 280 个哈希值;地址空间收缩将把这个数字减少到非常容易获得的 256 个哈希值。

关键风险领域,不是由单个所有者持有的钱包的反事实地址,在今天是一种相对罕见的情况,但随着我们进入多 L2 世界,这种情况可能会变得更加普遍。唯一的解决方案是简单地接受这种风险,但要确定所有可能出现问题的常见用例,并提出有效的解决方法。

现有哪些研究?

早期提案

区块链租用费: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

还剩下什么要做?需要权衡什么?

我认为未来有四条可行的路径:

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

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

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

功能清理

它解决了什么问题?

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

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

没有一个大的单一修复可以降低协议复杂性;问题的本质是存在许多小修复。

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

迄今为止已确定的一些协议简化机会的关键示例包括以下内容。首先,一些 EVM 之外的示例;这些示例相对非侵入性,因此更容易达成共识并在更短的时间内实施。

现在,EVM 内部的一些示例:

现有哪些研究?

Purge 的后续步骤:https://notes.ethereum.org/I_AIhySJTTCYau_adoy2TA

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

SSZ-ification EIPS:[1] [2] [3]

无状态 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

一种使用增量可验证计算进行链下安全日志检索的方法(阅读:递归 STARK): https://notes.ethereum.org/XZuqy8ZnT3KeG1PkZpeFXw

还要做什么,又有哪些权衡?

进行这种功能简化的主要权衡是 (i) 我们简化的程度和速度与 (ii) 向后兼容性。以太坊作为一条链的价值在于它是一个平台,您可以在其中部署应用程序并确信它在多年后仍能正常工作。与此同时,也有可能将这一理想发挥得太过,用威廉·詹宁斯·布莱恩的话来说,“将以太坊钉在向后兼容性的十字架上”。如果整个以太坊中只有两个应用程序使用某个功能,其中一个多年来没有用户,而另一个几乎完全没有使用,并且总共获得了 57 美元的价值,那么我们应该删除该功能,如果需要,可以自掏腰包向受害者支付 57 美元。

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

在第 1 步和第 4 步之间应该有一个长达数年的流程,并明确说明哪些项目处于哪个步骤。此时,需要在功能移除流程的力度和速度与更为保守和将更多资源投入协议开发的其他领域之间进行权衡,但我们距离 Pareto 前沿还很远。

EOF

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

这样做的好处是,它为添加新的 EVM 功能和鼓励迁移到具有更强保证的更严格 EVM 创造了一条自然途径。它的缺点是,它显著增加了协议的复杂性,除非我们能找到最终弃用和删除旧 EVM 的方法。一个主要问题是:EOF 在 EVM 简化提案中扮演什么角色,尤其是如果目标是降低整个 EVM 的复杂性?

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

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

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

更激进的以太坊简化策略是保持协议原样,但将协议的大部分内容从协议功能转变为合约代码。

最极端的版本是让以太坊 L1“技术上”只是信标链,并引入一个最小的 VM(例如 RISC-V、Cairo 或专门用于证明系统的更简单的 VM),允许任何其他人创建自己的汇总。然后,EVM 将成为这些汇总中的第一个。具有讽刺意味的是,这与 2019-20 年的执行环境提案的结果完全相同,尽管 SNARK 使其实际实施起来更加可行。

YXuY3KxC2q9U1ZIZay6rq9XK2aIpesYrubu00Itl.jpeg

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

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

发表评论
暂无评论
查看更多评论
相关资讯