主页 > imtoken最新app下载 > 以太坊清零 观点 | 国家通货膨胀和无国籍状态

以太坊清零 观点 | 国家通货膨胀和无国籍状态

imtoken最新app下载 2024-01-24 05:14:59

本文献给 Alexey Akhunov 和 Igor Mandrigin,感谢他们对无国籍概念的贡献。

一、简介

本文旨在介绍一条解决“状态数据扩容”问题的技术路径——“无状态”。 “状态数据膨胀”是所有允许用户自主写入状态数据的公链都会面临的问题。 这意味着由于用户和合约的不断增加,全节点将存储越来越多的状态数据。 不断增加的状态数据会带来一系列的风险,包括:提高全节点运行门槛; 使得链上操作的定价不平衡。

在这篇文章中,我主要以以太坊区块链为例,因为我对以太坊最为熟悉,但是状态数据扩展的问题是普遍存在的,并不是以太坊独有的。 我还会引用我知道的其他项目考虑过这个问题。

为了让大家充分理解“无状态”的含义,我必须在开头说明一下问题的背景。 然后我介绍了以太坊社区为此提出的几个概念,以及相关的开放问题/权衡。 最后,我将回到最初的问题,以便通过对问题的各种描述(以及导致它的解决方案)拓宽我对问题的思考。

2.状态数据膨胀问题

“区块链协议”可以理解为允许将不定数量的计算机的行为同步到一台计算机中的协议。 然后,它的运行会在参与相关协议的计算机(即“节点”)上产生两种数据:一种是区块数据,也就是我们常说的区块链,这部分数据记录了网络(这台电脑)过去发生的所有事情; 另一种是状态数据,即代表整个网络当前状态的数据。 对于以太坊来说,“状态”的内涵包括:哪个账户有多少余额,发送了多少笔交易(不包括发出的交易内容,即区块数据); 哪个合约的代码是什么,里面哪个存储项的价值是多少; 还有一些与共识机制运行相关的数据。

状态数据的特殊性在于:一方面,状态数据是历史区块(包含的交易)执行后的结果; 另一方面,它是执行新区块的前提。 因此,在目前的以太坊区块链上,全节点必须保存状态数据,以验证(通过执行区块)新收到的区块的合法性。

可以想象,由于用户和合约的数量会不断增加,如果不进行一些控制,状态数据的大小会不断增加。 这就是状态数据膨胀问题。

状态膨胀问题的影响是肯定的:它使区块验证变得越来越困难。 因为一个状态对象也是读写的,当有10万个状态对象时,与只有1000个状态对象相比,增加了资源开销。 也正是因为如此,状态膨胀会提高运行全节点的门槛(单位时间内的资源开销——主要是硬盘随机读写——不断上升),也会逐渐失衡各个节点的Gas开销比EVM 的操作,导致针对节点的 DoS 攻击向量。 (注:资源开销的增加与客户端软件的实现有关。)

但是对于导致国家通货膨胀问题的原因(以及应该如何纠正)有许多不同的观点。 例如,Vitalik 对问题的归因 [1] 是:

“这些操作只需要交易的发送方支付一笔以 gas 使用量衡量的一次性交易费用,但会对整个网络造成永久性的持续成本”

换言之,问题的根源在于支付与成本的不匹配——当前的以太坊协议既不能合理删除状态来“瘦身”区块链[2],也不能让用户继续保存自己的状态支付。 如果能做到,这个问题就可以得到控制,不会那么严重。 因此,他倾向于向“状态保质期”的方向改进:用户创建或更新某个状态对象后,只能保证全节点存储该对象一段时间; ) 来“复活”对象。

问题的其他归因和“状态保质期”的概念将在后面讨论。 现在让我们转向“无国籍”。

注 1:Vitalik Buterin,

注2:在目前的以太坊协议中,确实存在一个可以删除合约存储项的操作(SELFDESTRUCT),同时也为这个操作代码的使用提供了一个粗略的激励机制(Gas返还机制)。 但事实证明,Gas 返还机制不仅没有改善状态膨胀问题,反而助长了 Gas Token 的出现,加剧了状态膨胀问题; 而 SELFDESTRUCT 导致了其他问题。 看””

三、“无国籍”的概念

(1) 无国籍

“无状态”背后的想法是,状态膨胀问题是一个问题,因为验证一个区块的节点必须首先有状态数据(你必须首先知道一个账户有多少钱)才能验证这个区块(然后 Only then能否知道账户消费X元是否合法); 但是如果我们可以在不在本地存储状态数据的情况下验证区块,那么我们就不需要担心这个问题。

具体方法是在广播一个区块时,传递一个区块内所有交易的访问状态的证据。 一个根本不保存任何状态的节点也可以使用这些证据来恢复所有交易的状态树,这些状态数据可以在验证后丢弃。 这里的“被访问状态的证据”通常被称为“见证”。

无状态代表了对状态膨胀问题的大刀阔斧的解决,完全不需要状态数据来进行区块验证,自然也就不用担心状态膨胀了。 另一方面,每个节点也可以选择存储哪个状态,允许开发者为自己的使用场景定制所需的客户端。

但是,从节点的角度来看,这意味着一种交换:以增加带宽开销为代价,来节省硬盘的读写和存储开销(虽然读写开销确实是目前全网最大的一部分节点成本)。 那么见证数据有多大呢?

如果不对以太坊协议进行任何更改,见证数据的大小将在 MB 级别 [3])。 相比之下,目前(区块 Gas 上限为 1250 万)以太坊区块数据量约为 45 KB [4]。 由此看来,见证数据的带宽开销是非常大的。 近两年,无状态以太坊研究的主要方向是思考如何减少见证数据的大小。 方向是:(1)Code Merkelization,减少见证数据中需要包含的合约代码数据[5];(2)改变以太坊状态树的格式,比如将十六进制树改为二叉树[6],或将 Merkle 树更改为 KZG 承诺树(即所谓的 Verkle 树 [7]); (3)见证数据以区块为单位提供,而不是以交易为单位,可以避免一些证据的重复。 改为二叉树可以节省一半甚至更多的带宽开销; 而 Verkle Tree 可以生成固定大小的见证数据。

除了带宽开销的增加,无状态还带来了一个革命性的变化:网络中的大部分节点可能不会保存状态数据,至少不会保存全量的状态数据。 所以过去我们习以为常的特性在无状态的基于客户端的网络中不一定能实现。 这些问题需要重新思考:

在当前条件下,用户无需担心谁能为他们提供钱包服务; 因为他们的账户状态在全网所有节点都有备份; 但实现“无国籍”后,谁来为用户提供见证数据? 用户如何知道节点在哪里存储他们的状态? 一个乐观的假设是:出块人必须已经存储了所有的状态,否则会影响它的出块; 因此至少区块生产者必须能够提供这样的服务。 但这会影响钱包服务的可用性吗? (其实在写的时候,我已经不担心这个问题了,假设可以降低无状态的带宽开销,那么全状态节点的门槛也会降低,自定义状态节点的门槛也会降低,所以钱包服务的提供门槛实际上降低了,可以认为无状态确实改变了钱包服务提供的假设,但不应该认为是使它变得更糟)如果一个节点是无状态的,则只保存块数据,虽然它可以参与历史区块和历史交易的广播,但不能参与新交易的广播。 确切地说,TA 无法验证新收到的交易的有效性。 那么P2P网络中怎么会有这样的节点(其他对等节点会认为它是无用节点而断开链接)呢? 交易如何在网络中传播? 这是否意味着我们无论如何都需要某种机制来以交易为单位提供见证数据? 还是无状态节点只能在专用的二级网络中生存? (基于后者的解决方案是形成一个二级网络[8],可以按需请求状态数据,就像我们常用的BitTorrent种子下载网络一样;当然,加入见证数据广播交易也是一种方式)如何指定见证数据的气体开销? 或者,如何限制见证数据的大小? 以上列表只是目前的研究成果,可能还会更长。

这些操作假设的变化可能比其对带宽开销的影响更重要; 如果不分析这些假设,就无法判断无状态是否真的值得实施,或者哪种实施更好。 目前对无状态有一个分类:在我看来,两个方向都有优点和缺点,但不应该认为网络的最终形态是可以规划的。 从节省带宽的角度,弱无状态是更好的选择; 但相应的,也必须面对上面提到的新事务传播的问题。 我们稍后会回到这个类别。 现在我们进入第二个概念:“准无国籍”。 注3:Alexey Akhunov,这篇文章是理解“无状态”的最佳入门读物。 在 Alexey 测试的主要时间段内,平均区块大小约为 20 KB(800 万 Gas),实测见证数据的平均大小约为 1MB。 这意味着,在当前块大小下,必须预期更大大小的见证数据。 注4:注5:Sina Mahmoodi,注6:Igor Mandrigin,注7:Dankrad Feist,注8:Piper Merriam,

(2)准无国籍准无国籍的概念来源于这篇文章[9]。 其背后的直觉是,对见证数据的无状态要求可以帮助完全无状态的节点构建一棵状态树,从0开始验证对应的区块,但这很可能会浪费带宽资源; 因为一旦收到见证数据后,节点就已经有了稀疏状态树。 这棵树是可以重复使用的,不需要完全删除,收到新块后从0开始构建。 因此,假设节点的状态数据存量在收到区块之前是已知的,我们可以使用见证数据为其提供状态增量。 这个增量加上它的初始存量刚好足以构建一个用于验证新块的能量 A 状态树。 这样,我们就可以获得无状态的大部分好处(通过附加见证数据来最小化区块验证的硬盘读写开销),而无需支付无状态那么高的带宽开销。 而且,准无状态还有一个额外的好处:当状态数据越来越多时,状态树会变得更深更密,无状态状态下的见证数据理论上也会增加。 大,即带宽开销趋于上升; 但是准无状态见证数据只提供增量数据,所以它的见证数据也是最小化的。 麻烦的是,这个“节点状态数据存量”怎么知道呢? 从理论上讲,除非我们从具有准无状态的一致股票开始,否则不可能与这只股票实现同步。 但只要“一致”,数字是多少并不重要。 由此我们发现了准无状态的另一个优势:如果状态数据已经变得过大,我们可以“清除”它们,从无状态重新开始,开始一个新的状态丰富的节点(比如传输见证数据的过程(和状态)到验证器。这是 ReGenesis,它会定期重启以太坊计算机。注释 9:Igor Mandrigin,(3)Regenesis

ReGenesis的想法最早是由Alexey[10]提出的,更详细的解读可以参考这篇文章[11]。 大致思路是:周期性地(比如每100万个区块)将协议设置为空状态,开始执行一个准无状态的过程——每个区块在传输时都必须伴随一些见证数据,这样a 再生事件开始将状态数据归零,并且从那时起拥有所有块的证明数据的节点可以验证该块。 也就是说,每触发一次再生事件,一个只想验证区块但不想生成区块的节点可以清除本地状态数据。 有了新收到的区块附带的witness message,就可以构造Verify区块的状态树; 每个见证数据都会带来增量状态数据,节点只要缓存自己的状态树,见证数据就够了。 当节点本地状态数据足够时,甚至可能出现不需要伴随见证数据的区块。 不过不需要担心状态数据的膨胀,因为节点会周期性的清除状态。 ReGenesis 是一个特别平衡的解决方案(事实上,它也是当今“无状态以太坊”研究的主要方向)。 而且,由于追求准无状态,ReGenesis虽然需要实现基于交易的见证数据,但它绕过了无状态基于交易的见证数据的一个缺点:需要频繁更新一笔交易的见证数据。 一次状态根更新(即每次出块)需要更新未打包交易的见证数据; 然而,在准无状态中,准无状态节点每次收到一个块时,本地状态都会发生变化。 更多,并且交易打包的时间必须晚于其广播时间,因此广播时交易附带的见证数据必须足以满足验证的需要。

那么它的缺点在哪里呢? (1) 如果一个交易无法提前确定它会访问哪些交易(这被称为“动态访问模式”[12]),它可能无法提供足够的见证数据从而失败。 这不是无法解决的问题,因为根据准无状态的性质,只需要多次发起并补充见证数据,总会成功的。 但这意味着用户可能不得不多次发送同一个交易。 (2) ReGenesis 下的节点是否也会丢弃区块数据尚不确定,因此可能会影响到 rollup 等 layer-2 解决方案。 从我们上面的推论来看,ReGenesis 非常像一个无状态或准无状态的解决方案。 然而,从另一个角度来看,ReGenesis 也非常类似于“状态保质期”方案或“状态租金”方案:每一次,所有状态对象都会过期并变为非活动状态,为了恢复自己的状态,额外必须付出代价; 用户一次性支付只能保证相关状态在节点保存一段时间,不能保证永久保存。 从这个角度来看,ReGenesis 遇到了所有州保质期计划都面临的另一个问题:“复活冲突”。 如果有人直接在死状态存储位置创建新状态(而不是通过提供见证数据来复活状态),就会出现冲突——之前的富状态节点(存储已经死掉的旧状态)无法到达一个与无状态节点(存储新创建的状态)达成共识。

在对应的 ReGenesis 上,在触发再生事件后,有人试图在一个已经有状态的存储位置创建新的状态(比如直接向自己的账户存入 10 ETH),一直存储状态数据的富状态节点将be 不可能与刚刚清空状态的无状态节点就状态根达成共识(因为余额不匹配)。 Vitalik [12] 提出的解决方案是:为其创建周期对应的账户分配一个标识符(例如地址为0x1234,第0个再生周期创建的账户标记为(0, 0x1234),该账户第四个再生周期创建的状态标记为(4, 0x1234) ),以此明确用户是想复活上一周期创建的状态以太坊清零,还是想创建一个新的状态,从而解决复活冲突问题. 目前,ReGenesis 已完全被视为状态保质期方案,与以弱状态无状态为代表的无状态方案竞争[12]。 但在我看来,因为它的运行需要使用见证数据,而围绕见证数据使用的研究是从对无状态的研究中诞生的,所以无状态是一个不应该被抛弃的视角,尤其是准无状态的概念很有指导意义。 注释 10:Alexey Akhunov,注释 11:Igor Mandrigin,注释 12:Vitalik Buterin,

(4) 总结 从无状态和准无状态的概念出发,我们最终走向了像 ReGenesis 这样更平衡的解决方案。 从状态保质期来看,也可以断定ReGenesis是相当有竞争力的。 但是,这绝不意味着对无国籍的研究已经完成或被淘汰。 事实上,我们还没有确定无状态的所有影响都已经分析过了,所以不可能说已经有一个绝对值得实施的解决方案。 而且,即使方案确定,也需要时间才能获得安全高效的工程结果(比如假设状态树真的从Merkle树变成Verkle树,工程上需要多少时间? ). 因此,我对无状态的实现并不那么乐观。 接下来,让我们回到状态扩展的问题上,看看这个问题的不同表述是否会给我们带来一些启发。

4、问题出在哪里?

国家通货膨胀问题究竟意味着什么? 在什么意义上它是一个问题? 如何归因并提出可行的解决方案? 如何衡量一个解决方案是否值得? 至少可以从以下几个方面来思考状态扩展对我们的影响:(1)会增加区块验证的成本,从而提高全节点运行的门槛; (2) 意味着一种只增不减的永久性负担,对网络的长期生存和去中心化构成威胁; (3) 意味着链上操作的 gas 定价存在持续的不平衡风险(也是 DoS 风险); 我们一个一个。

(1) 验证成本 为什么状态数据的增加会增加区块验证的成本? 因为对于以太坊来说,(1)区块执行和区块验证是一回事,所有的计算过程都是完整执行的; (2)区块验证需要本地最新的状态数据; (3) 状态数据的增加意味着对单个状态对象的读写变得更加困难。 在这三个条件中,如果任何因果关系被打破或削弱,状态扩展对区块验证的影响就会被削弱甚至消除。 如果区块验证和执行不是一回事,区块验证的开销是恒定的,那么状态扩展问题不会影响区块验证的成本; 这是 Mina 等新兴区块链所采用的思想:每次产生一个区块时,区块生产者都会为区块的执行生成一个计算完整性证明。 验证者只需要验证这个证明就可以验证相关区块的有效性,验证成本是常数,打破了状态膨胀。 块验证成本的影响。 理论上,以太坊也可以引入类似的技术; 我们要付出的代价是:找到一个安全可靠的工程实现以太坊清零,可以实现通用计算的计算完整性证明,这可能会彻底改变应用开发者的体验,需要重新设计链上操作的gas消耗比例。 同样,无国籍正在破坏或影响(2)中的因果关系。 实现无状态后,区块验证不再需要本地存储最新的状态数据,但也留下了一个风险:随着状态数据的增加,见证数据也随之增加(因此验证区块的带宽开销增加了风险)。 而(3)向我们指出,优化客户端也可以帮助减少这个问题对我们的影响。 例如:Geth client version 1.10 [13] 实现了状态快照,可以保证状态读取的开销是一个常量,消除了状态扩展对状态读取开销的影响; 然而,即使优化到 Ultimately,状态写入的开销仍然会随着状态数量的增加而增加。 注 13:Péter Szilagyi,

(2) 永久负担 从这个角度来看,问题在于: (1) 用户可以强制节点存储自己的状态; (2) 付款与费用在时间上不匹配,一次性付款永久存储。 无国籍的激进和革命性的地方在于,它针对的是(1)而不是(2),即不把这个问题解释为经济机制问题,也不考虑改变经济模式来解决这个问题。 无状态完全消除了节点与本地部分特殊数据(状态数据)交互来验证区块的需要,从而完全消除了存储状态数据的需要。 实现无状态后,是存储部分还是全部状态,完全由节点运营者自己决定。 事实上,用户不能强制所有节点都存储自己的状态。 他们只能期望矿池或钱包服务提供商等专业运营商来存储自己的状态。 地位,这是完全公平的。 (2)的解决方案可以分为两类:一类倾向于:一次性支付,限时存储; 无限期存储,连续支付。 前者以各种状态保质期方案为代表; 后者以 Nervos 区块链为代表。 在 Nervos 区块链上,当用户想要存储状态时,必须绑定一定数量的区块链原生资产 CKB,绑定的代币数量与可写入的状态数据大小成一定比例; 因此,用户在存储状态时,虽然没有货币支出,但由于资产绑定带来的不便(或失去的机会收入)是与存储状态持续时间对应的持续成本。 因此,这种模式约束了用户存储状态的行为; 而 CKB 的数量构成了状态数据的上限,控制着状态的扩张。 state shelf life scheme 和 statelessless 相比有点三心二意——在很多 state shelf life 方案中,虽然它可以约束状态数据的大小(因为给定时间内可以刷新的状态对象的数量是有限的),但并不一定减少与特殊数据交互的需要,它需要一个额外的数据结构来记录失活状态的信息,同时也需要与这些数据进行交互。 解决复活冲突其实就是解决这个问题。 此外,包括 ReGenesis 在内的状态保质期方案也意味着全网的交易处理能力将被一类不创造经济价值、仅用于支付租金(或购买保险)的状态复活交易所占用。 这让人怀疑状态保质期是否是一个能够获得公众支持的长期可持续发展方向。 毕竟,用户会越来越多。

(3) 操作代码 Gas 定价失衡 链上操作的 Gas 消耗绝对值是没有意义的。 如果一个操作消耗 100 Gas,则没有任何意义; 有意义的是不同操作的 Gas 消耗比例:一个操作消耗 100 Gas 一个操作的计算开销被认为是一个操作消耗 1 Gas 的 100 倍。 它有两个含义: (1) 引导应用程序开发人员朝着代码优化的方向发展。 假设两条运行路径都能达到相同的效果,且其中一条路径的Gas开销较低,开发者会实现这条路径;(2)如果比例失衡,则意味着标称开销(Gas消耗)为某个操作偏离了它的实际开销,这样的操作码更有可能被用来对节点发起DoS攻击。 著名的“上海攻击”是这样的:攻击者在耗费极少gas但节点实际计算开销较大的交易中包含大量操作码,处理这些交易会导致节点超负荷运行离线。 状态膨胀会造成这样一个不平衡的问题:状态操作的gas成本是一个常数,但是状态读写的成本其实并不是一个常数,它会随着状态数量的增加而增加。 那为什么状态操作的Gas开销不能实时动态变化呢? 因为状态读写在逻辑上是由EVM实现的,但实际上并不是。 它由客户端软件的数据库实现。 不同客户端的实际开销既不统一,也不被 EVM 感知。

值得提醒的是,以上两种效果会相互叠加。 如果相关操作的标称开销率只是引导应用程序开发人员使用实际开销被低估的资源,问题会变得更加严重——事实上,状态膨胀问题本身就是这样一个例子。 开销设置得太低。 目前以太坊社区的做法是通过硬分叉来调整不同操作的gas消耗量。 这相当于说,以太坊目前的治理流程作为EVM感知状态运行开销的信息输入机制。 这样做当然不能完美解决问题,而且它提醒人们以太坊计算机在多大程度上依赖于人类工程师的定期维修。 此外,合理的 Gas 定价的另一个挑战是它需要使用相同的计量单位来衡量本质上需要不同资源的操作的开销比例。 我提出这个问题是因为无国籍状态也受到这个问题的影响。 目前节点执行区块的主要开销不是计算,而是状态读写; 而在使用见证数据取代状态数据后,主要的开销就变成了带宽。 当然,区块生产者需要计算见证数据,但即使我们不考虑这一点,或者认为当前状态操作名义消耗足够准确,我们仍然要考虑如何约束见证数据的大小。 好的办法无疑还是价格,但是它的Gas消耗量应该怎么确定呢? (注:CALLDATA类型数据的定价有点像按带宽消耗定价,这点值得思考。)

(4) 回到无状态,理解这些问题,我们或许可以更好地理解无状态解决了哪些问题,还有哪些问题有待解决。 其实回过头来看无状态,原理很简单:用带宽开销换取硬盘读写的节省。 但是,你能确定这一定是值得的吗? 假设我们生活在一个硬盘驱动器读写便宜且带宽稀缺的世界中? 或者,假设这两种资源的价格在未来发生逆转? 也就是说,无论选择无状态还是保持现状,事后看来都未必是一个灵活的选择——理想的情况应该是节点可以选择牺牲哪一个来换取哪一个,随时切换,而不是被治理程序所迫 每个人都选择一个,无论选择多么好,最终只是有限头脑智慧的产物,也不能排除依赖治理程序逆转选择的风险稍后。 这是否意味着最佳解决方案应该是与当前以太坊网络部分重叠并并行运行的无状态客户端网络? 用户可以自由加入和切换吗? 我们可以有这样的方案吗?

五、结语

自从2019年3月了解到“无状态”这个概念后,我就认定无状态是以太坊底层协议演进最值得研究的方向。 只有它才能解决状态扩张的问题,维护以太坊属性的经济。 我今天仍然相信。 However, thinking about the state expansion problem will continue to involve the underlying paradigm of Ethereum—global state and on-chain computing—and finally visualized as a question: how to formulate a nominal cost ratio (gas cost) for on-chain operations? No matter what improvements are made to Ethereum, this problem cannot be avoided. In the end, you will come to the same conclusion as me: Ethereum's design imbalance is not one, but two. After statelessness, we still have a long way to go. Indeed, originally, the expectation of any Messiah is an illusion. For now, let's tackle the biggest hurdle in Ethereum's long-term survival: state bloat.

(结束)

(本文链接较多,可点击左下方“阅读原文”从EthFans网站获取)