主页 > 苹果商城可以直接下载imtoken吗 > 以太坊状态规模管理提案(第 1 部分)

以太坊状态规模管理提案(第 1 部分)

以太坊协议面临的最持久和未解决的挑战之一是由不断增长的状态数据引起的问题。 以太坊区块链上的很多操作(创建账户、写入合约存储槽、发送ETH到新账户...)都会向以太坊添加状态内容(即向状态数据添加数据对象),以及所有全节点必须存储全量的状态数据,以便验证新块和创建新块。 这些操作只需要交易的发送方支付一笔按使用的gas量计算的一次性费用,但会对整个网络造成永久和持续的成本,因为节点需要存储这些新数据(和节点以后加入的过程中也需要同步下载这些数据)。

这是系统设计中的一个显着不平衡,并且可能使以太坊系统越来越难以使用,因为状态充满了不再有用的“垃圾数据”。 这篇文章的目的是详细解释问题的根源和解决问题的一些方法。 如果我们能够实现某种解决方案,这将为安全和大幅提高区块 gas 限制铺平道路。

本文讨论的研究领域仍在不断进步,随时可能出现更新、更好的想法和更优雅的权衡。

简介: 有什么问题吗?

“状态”是指一个节点为了处理新产生的区块和交易而必须拥有的信息。 状态不同于“历史”,后者是关于过去时间的信息,节点可以保存这些信息以供日后重播或存档,但不需要处理区块链。

以太坊区块链_以太坊区块链信息存储在哪里_以太坊有区块链记录一定是真的吗

在以太坊协议中,状态信息包括:

历史信息由旧块和收据组成。 EVM 中没有允许您访问旧块、旧交易以及内容和收据输出的操作码,因此节点会丢弃该数据并仍然验证新块,因此这些都是历史信息。

上面状态信息列表中的最后一项——共识机制相关数据——经过精心设计以限制其大小,因此我们无需理会它。 但是前三项很重要。 这三类状态信息的大小会随着时间不断增加以太坊区块链信息存储在哪里,因为新用户会不断加入网络,他们会创建新账户、新合约、加入合约、接收代币等等。

棘手的是,很多状态在使用后就坐在那里(不再被触及); 一旦用户停用应用程序,就会产生一些“垃圾状态”——不再派上用场,但会一直存在。

以太坊区块链信息存储在哪里_以太坊有区块链记录一定是真的吗_以太坊区块链

理论上,用户可以做到“垃圾不落地”。 用户只能发布带有SELFDESTRUCT条件的合约,当不再需要该合约时,调用该操作码移除该合约并清空其代币余额; 他们还可以使用智能合约钱包通过现有的外部持有账户(EOA)发送交易,而无需生成新的 EOA(EOA 状态无法删除)。

但在实践中,很少有这样的激励措施,适当的状态清理的技术复杂性太大了。 允许任何人像这样调用 SELFDESTRUCT 在许多合同中都是不合适的(人们想要的是“无法终止的”应用程序!),并且会给用户体验和代码增加很多复杂性。 事实上以太坊区块链信息存储在哪里,由于 SELFDESTRUCT 的用途极其有限并且有很多副作用,我宁愿永远删除这个操作码。 如果我们真的想控制状态数据的大小,我需要的是一种让网络中的节点能够丢弃默认不再使用的“垃圾状态”的方法。

无状态客户端

这个问题的一类解决方案是基于“无状态客户端”的概念(本文是这个概念的来源,这里是讲座视频)。 基本原理是让块验证不再以持有全局状态为前提。 相反,块携带证据(或“见证”)证明他们访问的状态的价值。 就像现在的设计一样,区块会包含一个“状态根”,访问的值可以被证明对应于状态根(译者注:默克尔证明是一种常见的证明技术)。 以太坊的当前状态树方案(Merkel Patricia 树)支持这种证明技术,二叉树或 Verkle Tries 等更高效的方案也可以。 见证数据也证明了块被处理后新状态根的正确性。

以太坊区块链信息存储在哪里_以太坊区块链_以太坊有区块链记录一定是真的吗

无国籍状态有两种形式:

强无状态是一种非常“优雅”的解决方案,因为它将责任完全转移给了用户,尽管在实践中为了保证良好的用户体验,我们需要创建某种协议来帮助不运行个人节点的用户维护状态和处理用户需要与意外帐户进行交互的情况。 达成这样的协议非常困难。

此外,所有类型的无状态都会增加网络所需的数据带宽; 强无状态还要求交易声明与之交互的帐户和存储项目的密钥(概念上称为“访问列表”)。

更温和的解决方案:状态过期

以太坊区块链信息存储在哪里_以太坊区块链_以太坊有区块链记录一定是真的吗

更温和的解决方案归结为不同形式的“状态到期”方案。 必须持续访问的状态可以保持“活动”; 长时间未访问的状态将变为“不活动”(或“已过期”)。 究竟使用什么机制来更新状态有很多选择(例如预先支付“租金”,或者只是访问该状态),但一般原则是除非明确更新状态对象,否则它处于某种形式的失败。 活状态。 因此,任何创建新状态对象(以及更新现有状态对象)的活动都只能成为节点一段时间内的负担,而不是像现在这样成为永久的负担。

死状态,顾名思义,不是“状态”的一部分; 想要处理块或创建块的节点不需要存储死状态。 但是,非活动状态并没有完全消除! 在所有类型的状态过期提议中,都预设了某种“恢复”停用状态的方法。

总的原则是active状态和当前一样使用,而inactive状态通过上面描述的无状态客户端的机制来使用。 恢复处于过期状态的对象的事务需要提供对象是停用状态的一部分的证据(见证数据)。 为了能够生成这样的证明,用户自己需要存储和维护至少一部分失活状态(对应于它关心的那部分失活状态对象)。

什么时候到期

以太坊有区块链记录一定是真的吗_以太坊区块链_以太坊区块链信息存储在哪里

确定到期条件的设计也有很多。 最常见的类型是:

我自己越来越喜欢“触摸刷新”方案,因为(1)它避免了应用程序需要创建复杂的经济模型来让用户支付状态租金; (2) 保证激活状态的规模有明确的上限(区块gas上限/reach状态对象的gas消耗×状态存活时长)。 定期使大量状态过期的方案(又名 ReGenesis)具有相同的好处,但有一些有趣的权衡:关键好处是过期方案更简单(无需遍历整个状态树来停用一个一个对象状态),但关键问题是,当你在过了一个过期点后激活自己的状态对象时,你需要多少见证数据将与你到达状态对象的时间点有关。

帐户级别的过期与槽级别的过期

状态过期的逻辑可以在账户层面进行操作,也可以在单个存储槽层面进行操作。 目前,我强烈支持在时隙级别实施状态过期方案。 因为很多合约账户的存储槽数是无限的,任何用户都可以加入合约,增加合约名下的存储槽数(比如空投就是一个已经发生过的案例)。 无论使用何种账户级到期方案,要真正限制状态的大小,租金金额必须与合约中存储槽的数量成正比(或与生命周期成反比)。 因此,用户仍然可以通过仅支付一次性费用来对合约及其用户施加永久性的持续成本。

为了解决这个问题,合约要么增加复杂的内部逻辑,将存储操作的租金“转嫁”给用户,要么重新设计自己的合约模式,转而使用CREATE2操作码创建新的合约,并使用这些合约来充当存储槽。 无论采用哪种方式,最终都会变成一个等同于存储槽级别的过期方案。 因此,我个人认为我们应该只在合约存储槽级别实施状态到期方案。

但是,存储槽级别的过期方案也有其自身的缺点:每个存储槽都需要添加一个元数据来指示何时过期(或者是否已经被灭活),这也意味着“复活冲突问题”(见下文)会影响不仅是帐户,还有存储槽。