什么是ETH 1.x和无状态节点?
本篇文章将剖析 eth 1.0 存在的各项问题,并介绍 Ethereum Foundation 提出的 eth 1.x 升级相关改动能如何改善当前以太坊的困境。
什么是 eth 1.x
以太坊 2.0 的研究行之有年,迄今(2020/06 )距离全面启动仍需要 2–3 年的时间,并且 eth 2.0 将被部署为由信标链(Beacon Chain)与多条分片链( Shard Chains)构成的独立区块链,而 eth 1.0 需要经过改动与升级方能成为 eth 2.0 中的其中一条分片链。这意味着现在运行的以太坊 1.0 区块链需要进行改动,并且在未来的 5~10 年保持运作,持续发展。而 eth 1.x 即为以太坊 1.0 升级版本的代称。
eth 1.x 的首要目标旨在解决现在区块链日益增长的资料负担(编者注:即数据规模负担),在区块链大小持续增长的情况下保持 eth 1.0 网络的弹性。
以太坊 1.0 的弊端与问题
在开始介绍以太坊 1.x 之前,必须先认知到目前(2020/06)以太坊存在的问题,如此方能充分了解 eth 1.x 被提出的背景与旨在解决的痛点。
Problem (A):网络趋于中心化
自 2020/05 以来,Gas Price 的节节攀升导致开发者与高频率使用者叫苦连天,其背后原因除了以太坊用户数量的增加,亦是由于耗费大量 Gas 的智能合约互动行为比例提升(单纯转帐 ETH 的占比被稀释),使得以太坊网络持续壅塞。
面对这样的情景,矿工社群于 2020/6/19 UTC 投票通过,将每个区块的 Gas Limit 从 10,000,000 提升到 12,000,000。
截至 2020/06/30,尽管每个区块的 Gas Limit 提升至12,000,000,合约交易占比的提升依旧让每个区块所能容纳的交易数十分有限,在 Etherscan 上可以查看到以太坊的 TPS(Transactions Per Second)在 Gas Limit 提升前平均落在 12 左右(低于号称的 15 TPS);在 Gas Limit 扩增后,TPS 亦没有出现明显的提升。
- etherscan.io -可能有些人会想说既然 12,000,000 Gas Limit 依旧壅塞,那怎么不再往上提升?原因是 Gas Limit 的提升将导致每个区块的处理时间变长,进而造成 Uncle Block 的数量增加,使得网络的共识机制变不健康,矿工必须耗费大量额外运算来进行处理。
此外,由于独立节点与小型矿池更容易挖到 Uncle Block,长期下来出块奖励的期望值降低将导致部分节点入不敷出,进而离开网络。如此将让以太坊网络变得更加中心化,更向大型矿池集中,危害了网络的长期健康与安全性。
Problem (B):状态爆炸
随着越来越多的智能合约被部署,以及大量的合约互动行为,导致以太坊网络需要储存的「状态」大小正以「等比级数」增长。状态的增长即反映在节点的储存空间大小上。
笔者于另一篇文章中摘要介绍了以太坊网络中的节点: 全节点与轻节点:以太坊节点面面观(10)文科生也该知道的区块链技术知识
在 2019 年年底,全节点的每月增长大小「小于 20 GB」;到了 2020/06,随着 Gas Limit 的提升,全节点的每月增长大小「逼近 40 GB」。状态不断加速增长的结果会对以太坊网络的性能带来衰退与网络健康的损害。未来全节点的运行将会变得更加艰难,可能导致网络变得越来越「中心化」。(编者注:此处作者的计算有点粗疏了,以 Etherscan 上的数据来看,Gas Limit 提升以后,以太坊区块的平均大小上升到 30 多 KB(在提升以前平均是 20 多 KB),即以 30 KB 计算,单月的区块数据增长量为 30×4×60×24×30 = 5,184,000 KB,换算过来就是 5 GB。而状态数据的增长更不可能有几十 GB 之巨。)
此外,区块验证的难度将随之提升,导致整体网络的延迟与 TPS 的进一步下降。
尽管这个过程如同温水煮青蛙,在数年之后才会导致以太坊网络出现巨大的安全性问题,然而为了避免走到那步田地,早在数年前便开始以太坊 2.0 的相关研究与开发。
-Roadmap of Ethereum tweeted by Vitalik on 2020/3/19-
以太坊的未来
Vitalik 于 2020/3/19 在推特上分享了他对于以太坊未来 5~10 年发展观点的路线图,主要由以下四个部分构成:
eth 1.x other
eth 1.x statelessness(无状态性)
eth 2 phase 0 prep(核心路径,聚焦于eth 1 ➔ eth 2 合并,移除 PoW)
eth 2 phase 2 and beyond
图中间的横轴代表时间线,沿着时间轴是一个从 Phase 0 启动,到 Phase 1,再到「eth1 ➔ eth2 合并」的「核心路径」。要完成合并有三个先备条件:eth 2 phase 1
eth1 ➔ eth2 合并的规范与实现
eth 1.x statelessness(无状态性)
其中,「eth 1.x statelessness(无状态性)」可说是对于 eth1 ➔ eth2合并最至关重要的一个条件,本文将以「无状态性」为主轴做相关的介绍。状态爆炸对以太坊网络的影响
由于以太坊区块链的本质是一台依靠矿工维护的去中心化大型「状态机」,随着区块数量的增加更迭状态,不断向前移动。以太坊的完整「状态」包含所有个人帐户和余额的当前状态,以及在 EVM 中部署和运行的所有智能合约的整体记忆体。
以太坊网络在每个区块高度都只有唯一一个获得全网所有节点共识的「状态」,这个「状态」在每一个新区块会产生变动并随着区块接至区块链上。
矿工在执行交易运算时,必须依据交易内容至节点内以「Merkle-Patricia Trie 」资料结构组成的状态树中更改相关的状态值,再重新计算出每个树状节点的 hash 值,算出新的「Merkle Root」,生成新的状态树。
- 图片来源:https://blog.ethereum.org/ -截至 2020/06,当前的以太坊网络中约有 5 亿个状态值,总状态大小约为 10 GB,状态会随着网络上的帐户与智能合约数量增加而按比例增长。因此,如果以太坊继续获得主流采纳,状态可能会在未来数年持续爆发性增长。不断扩大的状态主要会对节点造成两大影响:
节点读取状态耗时增加,交易处理速度变慢
目前每个新区块矿工大约需要添加或修改 3000~6000 个状态值。由于矿工处理每一笔交易时都必须要读取节点资料库中状态的相关资讯,当状态数量持续增长,在状态树中查询到指定状态值的耗费时间就越长。
建构新的状态树耗时更长,区块验证速度减慢
当矿工将交易处理完时,必须建构一个由新的状态组成的 Trie 结构状态树,当中涉及大量的 hash 值运算。计算完 Root Hash 方能建构出新的 Block Header,打包出新区块。
小结
综合来说,持续增大的「状态」与「节点大小」将导致新的全节点启动成本大幅提升:对于「储存空间」的需求与「同步时间」的增加可能会进一步导致网络中全节点数量的减少。
此外,以太坊网络的整体性能下降也在所难免。以太坊随着状态树查询与运算耗时的增加以及越来越多的合约交易,TPS 可能会进一步下降,导致网络变得更加壅塞,迎来更高的 Gas Price 竞逐。
eth 1.x 的提出
对于以太坊 1.0 升级的相关研究最早可以溯及到 2018/10 在捷克布拉格召开的 Devcon IV,会议谈论到以太坊 2.0 无法在未来 3~5 年内完全取到以太坊 1.0 的所有功能,因此 eth 1.0 仍必须保持安全稳定运行,于是乎无数的核心开发人员开始研究一系列延长 eth 1.0 寿命以及与 eth 2.0 介接的解决方案。
既然状态的持续增大对于以太坊网络的健康带来重大影响,解决方案之一便是「消除以太坊网络对状态的需求」。细看 Vitalik 于 2020/3/19 发布的以太坊未来路线图中即可看到一系列的解决方案:
上述的路线图是较为精要的版本,以太坊研究员 Griffin Ichiba Hotchkiss 于 2020/4/2 在 Ethereum Blog 分享了他对于目前 eth 1.x 研究开发方向的理解,整理出下图的「技能树」 :
-2020/4/2 更新的 eth 1.x 科技树-由于细节族繁不及备载,本文只会挑出其中几个核心来做说明。有兴趣的朋友可以参考并持续关注 Ethereum Blog 中的相关文章:
The 1.x Files: The Updated Stateless Tech Tree (April 2, 2020)The 1.x Files: A Primer for the Witness Specification (May 4, 2020)
The 1.x Files: EIP 1559 and the Ethereum Improvement Horizon (June 16, 2020)(Up to date)
eth 1.x 的目的
简而言之,eth 1.x 的核心目的有两个:
(A) 延长 eth 1.0 的寿命
在区块持续增长的情况下维持 eth 1.0 区块链的安全、稳定与弹性,让人们可以选择仅下载部分的状态,在较便宜的硬件上运行节点。
(B) 与 eth 2.0 介接
由于 eth 2.0 中的分片(shards)将是无状态的,因此「无状态」将是参与 eth 2.0 区块验证的先决条件。eth 1.0 要与 eth 2.0 相容的话势必得支援无状态运作,方能顺利过度,与 eth 2.0 介接。
为了达成这两个目的,在技能树图最右侧的终点我们可以看到「无状态以太坊 Stateless Ethereum」。然而,「无状态」的以太坊这个词可能有些不够精确,因为整个以太坊网络就是基于状态而存在的。
具体来说,是找到一种方式让以太坊网络中的部分节点可以将「保留整个以太坊状态的副本」这件事变为一个选项,而非必须。因此,要让现行的以太坊网络能够支援没有保存完整全网状态的轻量级节点:「无状态节点」参与到网络中的新区块验证。
而为了让无状态节点能够进行验证,以太坊 1.x 提出了以下三项主要改动,我们将逐一来进行介绍:
(1) 区块见证机制
(2) EVM 改动
(3) 资料结构转换为二进位制(Binary)
(1) 区块见证机制
无状态节点如何参与验证
简单来说,作法是:拥有全网状态资讯的「完整状态节点 Full State Node」在打包新区块时会一并产生「区块见证 Block Witness」,让没有保存全网状态的「无状态节点」能藉由区块见证提供的资讯对新区块进行验证。
什么是「区块见证 Block Witness」
前面提到,以太坊的资料结构是由约 5 亿个状态值所构成的 Merkle-Patricia Trie。然而,其中大约只有 0.1% 状态值(约 50 万个)会随着区块高度产生变化,如:个人帐户的 ETH 余额、合约底下记载的每个地址持有 Token 数量。99.9% 的状态值如:智能合约的程式码、Uniswap 手续费 0.3% 的参数等资讯一但智能合约部署完成便不会再进行更动。
由于一个新的区块(目前为 1,200 万 Gas Limit)至多只能容纳 571 笔交易,其涉及的状态值更改是十分有限的。那么一个没有储存所有状态值的无状态节点只要向拥有完整状态的节点请求涉及交易的相关状态值与未涉及到的 hash 值其实即可算出 Merkle Root 进行验证。
如下图所示,假设底层的 14 个菱形代表以太坊网络中所有的状态值,而新区块中仅有一笔交易,针对绿色的状态值进行更改,那么无状态节点其实只需要 1 个绿色的原状态值以及紫色的 Hash 值与其它未变动的 6 个Hash 值资讯即能透过 4 次 Hash 值计算,算出新的 Root Hash(Merkle Root),而不需要拥有所有的 14 个状态值来进行 9 次 Hash 值计算。
-图片来源:https://blog.ethereum.org/-这些为了完成 Root Hash 计算所需要向拥有全网状态资讯的「完整状态节点(全节点)」请求的「最小资讯量」即为「区块见证 Block Witness」,包含了状态 Trie 中「不涉及变动的部分 Hash 值」与「涉及变动的原状态值」。如此一来,没有保存完整全网状态的「无状态节点 Stateless Client」将可以藉由请求而来的「区块见证」资讯计算出新的 Root Hash。
为了便于让无状态节点参与验证,目前的最新研究方向是「区块见证」将可能成为「区块标头 Block Header」的一部分,随着新挖出的区块一并广播给全网节点,让无状态节点不用再发起额外的「区块见证请求」即能进行验证区块的动作。
透过这样的方式,无状态节点即能参与以太坊网络中新区块的验证。
碍于篇幅,我们在这篇文章只会做概念性的阐述,具体的实作细节先不展开细说,想更进一步了解的朋友可以参考我上方附上的链接以及以太坊博客中的其它相关文章。
(2) EVM 改动
状态值的更改和运算都是在 EVM 中进行,同理,区块见证也必须经由全节点的 EVM 透过运算来生成。EVM 的改动目标与成本和激励机制息息相关,主要包含耗费 Gas 的估算以及如何降低对节点间广播延迟的影响。
区块见证 Gas 计算(Witness Gas Accounting)
由于区块见证必须由全节点花费额外的计算资源来运算生成,因此会产生相应的 Gas 成本,而这个成本目前比较可行的方式是由交易的发起者来进行负担。至于如何让交易发起者在发送交易时即能准确估算额外的 Gas,以设定精确的 Gas Limit,目前仍在研究中,尚未产生明确的定案。
另外,考虑到在同个区块中可能有一个状态值被不止一笔交易进行更改,因而产生重复支付 Gas 的情形,这部分可能会成为矿工额外的奖励费用。
智能合约程式码分块(Code Merkleization)
区块见证的目的是为了让无状态节点能够进行新区块的验证,其中必定包含了智能合约相关的运算。然而,无状态节点没有储存包含智能合约程式码在内的状态,所以当无状态节点要进行一笔智能合约交易的状态运算时,便需要一并拥有包含智能合约程式码的在内区块见证。
这时会有另外一个问题,智能合约洋洋洒洒的程式码中可能只有其中的一小片段是与该交易运算相关联的,因此「程式码分块」的概念被提出。
「程式码分块」是一种拆分智能合约位元组码(Bytecode)的方式,将智能合约中与涉及交易相关的程式码拆出,作为区块见证中的一部分,一并提供给无状态节点让其做运算验证之用。
其目的便是避免调用到不必要的程式码,免于生成庞大的区块链见证导致运算时间的增加及节点间传递沟通的延迟。
(3) 资料结构转换为二进位制(Binary)
根据以太坊研究员 Igor Mandrigen 进行的实验(Binary Tries Experiment),若将以太坊资料结构从目前的十六进位制(Hex)更改为二进位制(Binary),每个区块的区块见证大小将能从 800~3,400 kB缩小至 300~1,400 kB,如此将大幅减低区块见证在网络中传播的延迟时间,让区块见证机制能够运行得更加理想。
然而从 Hex 转换为 Binary 具体的实作方式以及过度策略目前仍未有完全的定论,有兴趣的朋友可以持续关注 Ethereum Foundation 释出的相关消息。
无状态以太坊Stateless Ethereum
介绍至此,透过引入「区块见证机制」、对「EVM」进行必要的改动,以及将资料结构转换为「二进位制」,已能勾勒出 eth 1.x 的大致样貌。
支援无状态节点的 1.x 网络,将能够对以太坊 1.0 的区块链网络产生下方几点关键影响:
i. 对新加入节点更加友善
随着全网状态的膨胀与区块高度的提升,启动一个新节点的同步时间会变得越来越长(截至 2020/06,启动一个新全节点需要同步至少一周的时间),超长耗时的原因是因为全节点的同步必须从创世区块开始对每一个区块进行验证与同步的动作,而验证区块必须要拥有该区块高度的全网状态,因此在每一个区块同步状态是目前同步节点的极大瓶颈。
无状态节点时代的到来将能够大幅改善同步区块的痛苦过程,未来仅需凭借「区块标头」与「区块见证」即能完成区块的验证,同步节点体验的改善将能让更多人有意愿且能够负担运行节点的成本(时间与硬件资源)。
ii. 轻节点得以自力更生
在现行的以太坊网络中,轻节点不具备独立验证新区块与验证交易的能力,因为轻节点没有保存验证交易需要的 merkle proof 资讯,因而必须向邻近全节点发出 p2p request 进行请求,但轻节点现在愿意提供支援的佛心全节点变得越来越少。
无状态机制将能帮助轻节点依靠自己维护的部分状态(自己帐户与合约的余额等资讯),以区块标头和区块见证独立进行验证,不求于人。
iii. 节点网络安全性提升
由于区块链网络的安全性取决于能参与新区块验证的节点总数量,对网络的攻击成本将随着节点总数量的增加而提高,能有效地低系统被击溃的风险。
随着新节点启动成本的降低以及大量的轻节点投入到新区块的验证中,将让网络的整体安全性大幅提升。
iv. 介接 eth 2.0
最后一点也是最核心的一点,前面提到 eth 2.0 将会是由核心的信标链与多条分片链构成,全网的状态将被多个分片分开储存。由于每条分片各自拥有不同的状态,并且没有保存其它分片的状态资讯。因此对每条分片来说,其它条分片都像是「无状态节点」。
为了能够在多条分片链间有效验证与同步,必须依靠「无状态的验证机制」。因此现在的 eth 1.0 未来要能顺利成为 eth 2.0 的其中一条分片链,升级为无状态的 eth 1.x是至关重要的一个步骤。
结论
透过以上介绍,相信读者们应该对于现行的 eth 1.0 升级到 eth 1.x 需要进行的改动,以及改动完成后的未来有更清晰的认识。
在 eth 1.x 升级完成后,人们将能用便宜的硬件运行自己的无状态节点(轻节点),更多能够参与验证的轻节点可以进一步维护全网的安全性。
拥有无状态验证机制的 eth 1.x 方能顺利和 eth 2.0 的信标链与其它分片链介接,正式让以太坊网络进入由无状态验证机制与分片技术构筑成的轻量化 eth 2.0 未来。
Scan QR code with WeChat