Skip to content

Ethereum 1.x

概览

以太坊1.x是以太坊主网近期内将实行的一系列全面网络升级的代号。

以太坊2.0(Serenity,即宁静)不会在2-3年内全面上线,但阶段0和阶段1会在1-2年内实现,阶段2可能会在2022年推出。以太坊2.0将作为一条全新且独立于ETH 1.0的区块链进行部署,因此并不会接替ETH 1.0链,这也就意味着ETH 1.0链将继续存在5-10年。

Eth1.x概念的出现,要追溯到2018年的第四届开发者大会(Devcon IV)。当时许多以太坊核心开发者和好友在谈到以太坊面临的挑战时,不约而同地表达了一个类似的观点:随着网络性能的严重下降以及存储需求的不断攀升,如果以太坊主网不进行升级,那么很可能会变得难以持续。

  • 网络性能下降主要归因于状态(state)体积较大且还在不断增长。
  • 存储需求攀升主要是由于保留了区块、事件日志(收据)以及状态历史记录(当前可在主要客户端中删除)。

1.x系列升级将为以太坊主网带来颠覆性的改变,而以太坊2.0(Serenity,即宁静)会同步进行原型设计和开发。1.x计划包含三个主要目标:(1) 通过提高每秒交易的吞吐量来提升主网扩容性(可通过优化客户端,大幅提升区块gas限制实现);(2) 通过“存储租金”限制和减少磁盘空间需求,从而确保全节点的可持续运行;(3) 通过优化虚拟机 (VM) 提升开发者体验,其中包括eWASM的实现。

以太坊1.x前序历史

第三届Devcon 2017年10月,坎昆

Vitalik Buterin提出 "针对以太坊2.0的谨慎建议", 建议以太坊1.0的第1层(layer 1)应保持“安全且保守”,大部分创新都应在第2层和分片上施行。

EDCON 2018年5月,多伦多

Vitalik Buterin发表演讲“ 想成为Casper验证者吗”,表示Casper FFG验证者可以在笔记本电脑中运行,并且临近推行。

2018年6月

第40次核心开发者会议中,由于将Casper FFG作为合约实现具有一定挑战性,且与分片相关研究大量重叠,Casper FFG与分片研究进行了合并。

第四届Devcon 2018年10月-11月,布拉格

明确Serenity(完整的Casper+分片)在3-5年内不会在功能上取代以太坊1.0。

主要目标

  • 开发、规范并实现一系列措施,使其在两年内可以部署在以太坊1.0主网上,以确保1.0链持续存在且可用。主要包括抑制状态增长或是限制状态大小。
  • 重点放在这些措施本身,而不再强调引入特定的“功能”。而这就是我们需要eWASM的原因之一。目前的计算预编译功能需要逐例处理。引入eWASM将首先启用“预编译”工厂,引入预编译的速度和数量都得到了提升。之后,任何合约都将能够在eWASM中进行编写,从而完全不需要进行预编译。

工作方向

  • 状态租金(鉴于可能不只是租金,目前称作状态费用)
  • eWASM
  • 状态精简
  • 模拟仿真

状态租金

提案框架

由于状态租金与以太坊1.x阶段内的其他变动相比,可能会带来更大的影响(所以状态租金备受争议,甚至不受欢迎),因此在设计、对比并评估相关提案时要保持清晰的逻辑框架。这个框架旨在尽可能保证最终的更改方案是最优的。其遵循从“要解决的问题是什么(如果保持现状会怎样)”到“我们具体应该怎么应对”的逻辑路径。此处是目前的提案框架文档(进行中)。

Alexey对于状态租金的概念作出了如下解释:“(状态租金)并不是开始存储时一次性向用户收取费用,然后在其释放所占用的存储空间时退还一定金额,而是根据用户所占用的存储按天或按区块收取费用,如果他们不再需要进行存储了,可以提出ETH或是置之不顾,若是后者,其ETH将被回收。”

常见问题

  • 为什么将状态看作是宝贵资源?于谁而言有价值?(其价值能被复制吗)
  • 为什么要限制状态大小?(提升系统性能 + 可能有一定程度的缓解作用)
  • 如何管理状态大小?(前馈 vs. 反馈控制)
  • 需要管理哪些指标?(状态大小、状态增长或是两者同时)
  • 指标本身有无状态?
  • 我们使用什么参数(控制输入)?(状态扩张的成本,按每个区块每个大小单位收费)
  • 受控系统能削弱或是逃避控制吗?(潜在租金,矿工返利)
  • 我们如何获得占用大量存储的有效合约来支付租金,而租金更准确地代表了一段时间内将数据永久存储在链上的成本? (线性跨合约存储可能是一种解决方案)
  • 如何清理废弃合约中不再使用的状态?(由于废弃合约仅占状态的6%,因此还没有提案讨论过这个问题)
  • 如何在协议层面上保持简单且效用最大化的费用,并完全删除耗费大量费用的信息?(这不是一个好主意,用户总是会遗忘自己参与其中的应用)
  • 能否将智能合约的某些数据移至链下?(这种做法需要一个子协议)

“假如你现在有一个占用存储的智能合约,且必须要有人为其支付费用,那如果没有人进行支付又会怎么样?”

在目前既有的三个提案中,当智能合约的余额与状态费用是相互独立的,如果合约的两个余额都消耗完毕,那么会发生驱逐情况。
在现有的提案中,合约驱逐不会自动进行,必须要有人“戳”一下合约。简单来说,必须有人创建一个交易,并以某种方式访问该合约。

对于非合约来说,驱逐就只是意味着从状态中移除,因为其中并不包含任何信息。而合约不同,合约会占用存储,因此合约的驱逐不能直接从状态中完全移除,而是会产生一个“存根”(stub),其本质上是保留驱逐前合约的整个状态。存根带来的一个影响是,不能将合约在状态中完全删除,因此仍然会处于悬挂状态,但是存根使得我们能够恢复合约。

我们举个例子,“假如你有一个多签钱包,里面有许多代币,但是你忘记支付存储费用,你的钱包就会“消失”,但你仍然可以通过恢复机制另起一个合约来重建合约存储。只需要借助一个简单的代码将其从存根中恢复,你的合约就能“死而复生”。另外,你也可以直接充值状态费用从而继续使用合约,或者你也可以将合约中的数据移至别处。”
存根将是一串32字节的哈希值,保留了合约被驱逐之前的内容。

与无状态合约有何区别?

区别在于,无状态合约即使以存根形式存在,仍然可以通过正常操作进行访问。而在状态费用提案中,当合约处于休眠状态(即以存根形式存在),我们无法对其进行访问。如此可以说合约在以太坊虚拟机(EVM)中是不可见的,只有恢复合约的特殊操作码才能辨识出存根。

这是否是最好的解决方案?

假使有很多小型合约只保留了哈希存根,但状态大小仍然高居不下,那么我们就可以说这并不是完美的解决方案。

点击此处观看Alexey解释状态费用及Eth1.x的完整视频。

既有提案

目前针对状态费用存在三个提案:
* 对所有账户引进费用机制,无论是合约账户或是非合约账户,既有账户或是新建账户,且都能够恢复被驱逐的合约。当前提案 * 在状态扩展时(创建账户,增加存储项目)进行费用锁定,在状态清除后及释放一定金额。只针对先前存在的状态进行收费。当前提案 * 在“短期”内提升状态扩张的成本,以便在实现状态费用之前提高区块gas上限。

固有挑战

  • 现有的dApp将受到什么影响?是否会由于太过昂贵/繁琐而无法使用?是否需要优化/完全重写?
  • 状态额外扩张的费用或租金的定价──应该gas还是ETH来定价?如何确定价格?(状态规模的反馈周期?) ETH价格的波动会对费用产生多大影响?矿工会帮助用户逃避费用吗?

合约种类及影响

部分状态费用研究的目的在于识别哪些合约种类易受协议变更的影响,并且为其提供解决方案。可能受影响的重要合约种类:

  • ERC20代币合约及其管理合约(DAI、Augur)
  • 链上买卖合约(DEXs)
  • 以太坊域名服务 ENS
  • 非同质代币(NFT)合约
  • 多签钱包
  • 游戏合约
  • 博彩合约

相关资源

eWASM

由于当前的以太坊虚拟机(EVM)架构缺乏灵活性,对以太坊协议的强化有一定限制性。扩展执行层的方法是引入特殊的“预编译”合约。通过使用WebAssembly作为虚拟机规范,以执行高性能的“预编译”合约,有望简化引入此类合约的过程。

eWASM作为Wasm的衍生,可以通过在部署时对合约进行验证来克服Wasm的一些非确定性功能。如果合约使用了非确定性功能,则会被拒绝。

当前的提案建议使用更为狭义的eWASM(仅允许将预编译编写为eWASM)。

主要待解决问题

  • Gas计量
  • 内存配置
  • 内存配置
  • 解释器/编译器如何保障编译时及运行时

Gas计量

两种主要方式:

  • 注入。预处理Wasm字节码,额外添加一个寄存器用以gas计量。在进行某些操作时(跳转、调用)递增,并检查gas是否耗尽。优点:通用性;缺点:性能开销。
  • 自动估算上限。对字节码执行静态分析,对于某些代码子集,可以计算已执行指令(虚拟gas)的上限。优点:无性能开销;缺点:仅适用于代码子集。

目前第一阶段(预编译)采用的方式是基于gas上限。

内存配置

Wasm语义决定了其执行具有线性内存(在当前规范版本中只有一个),可以按需增长。线性内存是否会在每次调用引擎时进行分配,然后在执行结束时回收?如果是这样的话,则与当前的EVM模型相比(每个CALL操作码都会进行分配和回收),效率更高。

与其他EVM状态的交互(例如合约存储、余额)

这是通过外部函数提出的,例如(函数名为虚构):

function_SLOAD(storage_index: uint256)

另一种方式是不允许eWASM代码访问EVM状态,而仅在调用时交换输入/输出。当然,这并不适合维护大型的持久数据结构。

解释器/编译器保障

起初,这个问题是在JITs(Just In Time,即时编译)编译器语境中被提及的。JIT编译器是WebAssembly大大提升了JavaScript性能的原因之一。

在对抗性环境中,JIT编译器可能会出现问题,因为经常会出现编译耗时异常之久的程序,而且决定哪些内容要“即时编译”的算法也可能被攻击。

AOT(Ahead of Time,预先编译)编译器能够用于由核心开发者控制的预编译(阶段1)。阶段2的计划是首先使用简单解释器,继而开发AOT编译器,以提供必要保障。之所以首先引入解释器的原因是要确保eWASM可使用,使参与者更有动力围绕编译器展开工作(这比解释器更难)。

相关资源

eWASM提案
eWASM设计

状态精简

以太坊1.0存在扩容问题。增长率本身隐隐受到区块gas上限的限制,但数据的累积总量不受限制。
状态精简也称为链精简,这项工作并不直接与状态本身相关联,而是限制日志、区块以及数据等信息的增长。
按照核心团队的说法:“如果以太坊按照目前的速度增长,那么每年将增加91 GB的存储量"。
精简存储是有必要的,目的是限制以太坊的数据存储增长。提议的一部分包括删除历史区块、日志和索引。

待解决问题:

  • 我们必须要保留哪些部分才能与以太坊协议保持一致?
  • 是否需要一直保留所有区块?(也许不需要,例如我们可以采取向后同步方式)
  • 是否需要保留收据或是日志?保留的话需要保存多少(多少GB)?保存多久?
  • 是否总是需要下载整个头链?是否可以进行压缩(或许可以使用STARK证明)?
  • 能否通过优化快照同步流程(快速同步、压缩同步)防止无效的状态转换(或许可以使用有效证明)?

删除历史信息面临的挑战

对历史区块链进行精简所要面临的第一个挑战就是,即使我们删除了历史信息,也要依然能够对其进行证明。以下是两种潜在解决方案:

保留已删除区块链部分的默克尔证明(或其他加密证明形式)

轻客户端就是以这种方式运行,因此我们能够在短短几分钟内完成同步。轻客户端无需遍历从创世区块到链头的每个区块头,而是通过一个可靠检查点进行硬编码(或是从配置文件中获取),并从该检查点开始同步。然而,这种机制也存在两个问题:

  • 为了保证快速同步,必须不断更新硬编码快照或配置文件。这种方式适用于主网,因其会进行常规维护,但并不适用于私有以太坊网络。
  • 如果没有新版本发布,同步所耗费的时间会越来越长。而且如果全节点开始自行删除历史链头,那么历史检查点将失去效用,这迫使开发者要不断发布新版本,而用户也要不断拉取新版本。这对于扩容性来说毫无帮助。
无限期维护头链

这解决了Merkle证明机制的所有问题,我们始终可以仅基于头链和创世区块就进行快速同步。其弊端在于,与默尔克证明相反(默克尔证明是32个字节的任意历史记录),使得区块头无限期可用也就意味着头链的无限增长。

垃圾回收

如果我们就N个月/区块的保留策略达成一致,那么当区块链增长时,每个客户端都会删除N区块头之前的区块体和收据。然而这也会对RPC API造成影响。对此我们需要引入“虚拟创世块”(或许有更好的名字)概念,以定义APIs停止返回数据(或返回其停止维护数据)的历史点。

区块/收据存档

如何对历史链部分进行存档以便在之后的重建中可以重新启用,这是提案中最具挑战性的部分。因此,我们需要考虑在何处放置这些存档(内部或外部):

  • 协议外存储意味着将数据文件托管在传统外部服务器中,并根据我们的安全需求进行镜像和复制:FTP、S3、CDN等等。这些文件可以由主要参与者进行存档(以太坊基金会、Consensys、Parity Technologies、Internet Archive等等)。可以将这些文件的访问方式简化为Web请求。
  • 协议内存储意味着将数据文件托管在以太坊网络内部的某些节点处:Swarm/devp2p、IPFS/libp2p、BitTorrent等。存档仍将由主要参与者运行,但任何人都有机会参与运行存档,因此这种方式更贴近去中心化的精神。

以太坊秉承着去中心化的精神,我们只会选择协议内的方案。但其实还有许多其他方式使得我们可以对存档进行去中心化存储。

打破惯例

精简历史链会打破以太坊生态内部的一些重要惯例:

  • DApps将不能再访问保留期限外的事件
  • 节点将无法获知交易是否已删除或者是否从一开始就不存在
  • 节点会更难进行完整同步,目前在以太坊主网上使用Geth进行完整同步大约需要5天,其中最后270万个区块需要4天。如果我们将交易吞吐量提高到10倍,那么除了特殊用户之外,将没有人能够完成完整同步,也不会有人愿意进行完整同步。

相关资源

精简提案

模拟仿真

要对以上提及的工作领域(状态费用、状态精简)进行支持、运行测试方案并且对我们将来可能面临的难题进行预测,我们能够借助哪些工具?

模拟仿真能够为其他工作方向提供数据,以便进行预测、基准测试和参数校准。

模拟仿真工作有三项开发任务: * 模拟框架,当输入数据集时,该框架将生成输出,以预估被提议更新的属性(例如叔块率降低和gas上限增长)。目前建议使用Wittgenstein模拟器 * 仿真框架,可以更改环境条件,以测试已启用更新的属性 * 测试网,能够同一网络上一并启用这些更新

模拟工作负责处理软件代理的模型(当前语境为以太坊客户端软件实例),模型需要做到能够良好运行、能够捕获代理的重要方面。

仿真工作主要负责处理实际的软件代理(当前语境为实际的以太坊客户端实现,例如geth和parity),将其置于虚拟环境中,可以自由更改虚拟机以及网络参数。

通过模拟或许可以得到解答的问题:

  • 如果大多数以太坊节点在验证工作量证明之后直接广播区块(而不是像之前一样对区块进行完整处理),叔块率是否不再能代表网络的拥堵情况?

通过仿真或许可以得到解答的问题:

  • 快照同步(快速同步、压缩同步)成功率与主要带宽和状态历史精简阈值这类事物之间的关系应该用哪个函数进行描述?

开发者正在收集用于仿真的数据集,并对用于仿真的参数进行最终确定(其中之一可能是叔块率)。

需测试的属性

  • 区块广播,能否降低叔块率
  • 如果可以,提升区块gas上限
  • 如果可以,考虑提高存储成本和计算成本
  • 确定下一个瓶颈是什么 (a) 假设计算时间缩短 (b) 假设由于带宽限制出现许多叔块

准备数据集

这里从多种来源收集数据集,例如WhiteBlock, Etherscan等等。

相关资源

模拟提案

交付内容

需要实行硬分叉的措施:

  • 状态费用(或限制状态增长)
  • eWASM

可能无需实行硬分叉,但是需要在网络协议层面进行跨客户端协作的措施:

  • 状态精简

相关资源