TL;DR
⠀
上海升级的主要内容是 Withdrawal 和 EOF,EIP-4844 不会包含在上海升级
⠀
Withdrawal
⠀
提款无需主动发起,是全自动实现的,每天可以为 115,200 个 Validators 执行取款
⠀
有「部分提款」和「全部提款」两种规则,分别对应不同的条件,大部分提款都将会是「部分提款」
⠀
「部分提款」提取的是 Validators 的收益部分,由于长达两年的质押,信标链上已经累计了不少收益,因此在解锁刚开的前四天,解锁量最大;
「全部提款」则是收益 + 质押的 32 ETH 同时取走
⠀
理想状态下,预计升级后第一天解锁 400k ETH 左右,第二天 300K 左右,第三天 180K 左右,第四天 60K 左右,前四天解锁量大部分来源都是「部分提款」,从第五天开始由于所有的 Validators 基本都经历过了一次提款,大部分节点的收益已经提取完了,因此第五天开始提款的主要来源将「全部提款」,这个数字会间接受到流动限制系数的限制
⠀
准确来说,流动限制系数限制的不是每天能处理的「全部提款」数量,而是每天能达成「全部提款」条件的数量,也就是说即如果在上海升级之前,有大量的 Validator 满足了「全部提款」的规则,那仍然有可能发生远超预期的大量 ETH 解除质押的情况
⠀
EOF
⠀
EOF 是对 EVM 的升级,引入了新的合约标准和一些新的操作码,升级后 EVM 将可以进行版本控制,并且同时运行多套合约规则
⠀
有了 EOF 后,EVM 来说在进行迭代的时候,就不再受限于向前兼容的需求,升级难度变低了可能会导致未来以太坊 EVM 的升级可能更频繁
⠀
EVM 迭代频繁可能会导致对 EVM 兼容的虚拟机有更高的要求,如 zkEVM,要想保持始终能跟上版本,可能需要其他 EVM 兼容的 VM 有自动转化 EOF 更新到自己的 VM 的能力
⠀
了解以太坊上海升级
⠀
什么是上海升级
⠀
上海升级是以太坊执行层的下一次硬分叉,此前已经经历了君士坦丁堡升级、伊斯坦布尔升级、柏林升级、伦敦升级、巴黎升级(Merge),每次升级都意味着以太坊有了一些重大的更新,比如 EIP-1559 改变了矿工的收入结构,Merge 改变了以太坊的运行机制等等。
⠀
Beacon 链(信标链)—— 长达两年的共识层练习生
⠀
2020 年 12 月以太坊引入了 Beacon 链,从此以太坊从执行层和共识层由一条链负责,开始向执行层共识层由两条平行的链分开负责的方向转变,也是从 PoW 向 PoS 转变。
⠀
转变后,共识层由 Beacon 链负责,执行层由曾经的以太坊主网负责,也就是大家平时和以太坊上的用户交互会用到的那一个,Beacon 链和主网在合并前,只能通过执行层上的 Deposit Contract 进行通信,简而言之就是用户在执行层的 Deposit Contract 上面存入 ETH,就把 ETH 存入了信标链,但是从此信标链上的 ETH 没有办法回到执行层,Deposit Contract 里的 ETH 也无法取出。
⠀
注:Deposit contract,简而言之 Deposit Contract 是一个部署在 ETH 主网上的智能合约,它会接受任何包含至少 1 ETH 和一个有效 input data 的交易,信标链上的节点则会监听这个合约,并且使用监听到的交易中的输入数据来在信标链建立相对应的 Validator。
⠀
但是 Beacon 链并不是一上线就出道的,它经过了长达两年的共识练习生阶段,直到 2022 年 9 月才正式和以太坊主网完成合并。中间 Beacon 链经过了多次升级,从最初的 Phase 0,到 Altair upgrade,再到 Bellatrix(又称 The Merge),终于顺利出道,从此 Beacon 链和以太坊主网合二为一共同组成一个新的 Ethereum,二者通过 Engine API 进行通信。
⠀
在 Beacon 链长达两年的共识练习生的过程中,积累了许多 ETH 在 Beacon 链上,至今仍然无法被取出,而用户平时在以太坊网络上进行操作的时候,用的都是自己在执行层上的 ETH 余额。因此信标链 ETH 的提款功能必须被实现,就等来了本次 Shanghai Upgrade(上海升级)。
⠀
事实上,上海升级指的是执行层的升级,而除了上海升级外,同时进行的还有共识层信标链的升级,叫做 Capella 升级,Beacon 链上的 ETH 提款到执行层上的功能,是由上海升级和 Capella 升级共同完成的。
⠀
上海升级的重点
⠀
上海升级的首要目标是实现信标链的取款功能。除了信标链取款外,EOF(EVM Object Format) 同样也是一个重大升级,但是恰恰由于他重大所以会需要更多的测试时间,为了不拖延信标链取款功能的实现,EOF 的升级可能会推迟,主要取决于他的进度。
⠀
EIP-4844 是另一个备受关注的重要升级,由于他对于以太坊意义十分重大且同样可能推迟信标链取款功能的实现,因此 EIP-4844 已经确认会放在下一次的 Cancun Upgrade 中(Shanghai Upgrade 的下一次)。
⠀
上海升级的进度
⠀
预计 2023 年 1 月进行影子分叉,3 月进行上海升级硬分叉,本次升级实际除了执行层的 Shanghai Upgrade 外,还会进行共识层的 Capella Upgrade,执行层和共识层的共同升级来完成信标链的取款功能,除了信标链上质押的 ETH 取款功能外,同时还会实现 EOF 以及一些其他的小升级,预期共计实现 9 个 EIP。另一方面根据 2023 年 1 月 5 日举办的下一次 All Core Developers 会议,会决定是否推迟 EOP 的实现到 2023 年秋季,以免影响取款功能实现的进度。同时备受期待的 EIP-4844 将于 2023 年秋季执行。
⠀
注:影子分叉,简单来说,影子分叉就是一种压力测试的方法,用主网的数据,在小范围的节点内进行测试。通过运行少量 config 更新了的节点来对以太坊网络进行分叉得到影子分叉的网络,这样影子分叉可以继承原来网络的状态和历史,同时又不影响原来网络中的大部分节点的状态,也就不会影响分叉前网络的运行。这样做的好处是,主网的数据量和交易都是最复杂的,可以帮助节点模拟真实的情况。
⠀
升级的具体内容
⠀
提款
⠀
可能涉及的概念
⠀
首先要了解提款,大致需要对什么是 Validator,什么是 ETH 2.0,The Merge 发生了什么有一个模糊的概念,如果下面提到的这些概念很熟悉可以跳过。
⠀
如果没有概念的话,也可以阅读 Ethereum 2.0 Knowledge base,也可以对现状做一个这样的简单理解:Ethereum 现在分为共识层和执行层,共识层有一堆称之为 Validators 的打工仔,他们在共识层(信标链)质押了 32 ETH 作为他们作为他们打工干活的担保,靠这个担保,Validators 可以为 Ethereum 出工出力同时互相监督,以此来换取一些收益,目前这些用于担保和收益的资金,Validators 都是取不出来的。
⠀
Validator 的职责
⠀
Validator 职责主要有三个:
⠀
(1)Propose block,继承了之前矿工的职责,但是目前大部分的 Validator 都选择了安装 mev-boost,来间接实现 Proposer builder separation,如果想了解更多关于 MEV 和 MEV-boost 的事情,可以阅读 A&T View:以太坊质押可提取价值中的投资机会
⠀
(2)Sign Attestation,指 Validator 投票来确认其他 Validator propose 的 block 的有效性,Attestation 每个 Epoch 进行一次,是职责 1 的补充
⠀
(3)监控其他 Validators 有没有 Slashable offenses(监控有没有违规行为),常见的违规行为有 Attestaion Violation
⠀
Slot 和 Epoch
⠀
可以把 Slot 和 Epoch 理解成一种时间的单位,它代表了一个时间区间,一个窗口期,他们对应了一段时间的长度,12s / slot,32 Slots = 1 Epoch,6.4mins / Epoch,因此每 12s 一个 slot,每 6.4 分钟一个 Epoch,而每天又有 225 个 Epoch。
⠀
Slot 和 Epoch 在理解提款时有重大作用,因为 Validators 是以 Slot 或者 Epoch 为单位活动的,也正因为此,提款也是以 Slot 或者 Epoch 来统计的。
⠀

⠀
图片来自:https://eth2book.info/altair/part2/building_blocks/aggregator
⠀
通常每个 Slot 会有一个 Validators 被随机选中,这个 Validator 可以 propose 一个 block(一个 Slot 只会有一个有效的 block,但是每个 Slot 里并不是一定有 block,比如被选中在这个 slot propose block 的 validator 离线了)。同时所有的 Validators 会被分成许多个委员会(committees),每个委员会里至少 128 个至多 2048 个 Validators,这些委员会会独立负责 attest 每一个 slot,attest 时会从每个委员会中随机选择一些 Validators 作为 Aggregator,每个委员会中 Aggregators 数量目前是 16,Aggregators 负责聚合 Validators 的 Attestation 投票并广播给下一个 block proposer。再每个 Epoch 之后,committees 会解散后重组。
⠀
Validator 的状态
⠀
Validator 有几种常见的状态,根据状态的不同,会满足 Validator 不同的提款条件,所以要正确了解提款会怎么发生,知道 Validator 的几种主要状态也是有必要的。显然并不是所有的 Validator 都是 Active 状态,而只有状态为 Active 和 Withdrawable 的 Validator 满足提款条件。
⠀
1. 存款
⠀
首先用于成为 Validator 的 32ETH 要先被存入主网的存款合约(Deposit Contract)中,并且这个状态要保持 7 个小时左右才会进入 Pending 状态,每个 Validator 创建成功后,都会有一个对应的编号(index),这个编号是单调递增的,也就是说你越晚成为 Validator 你的 index 就越大
⠀
2. Pending
⠀
Validator 完成存款,就成了一个正式 Validator 预备军,需要等待其他活跃(Active)状态的 Validator 投票才能进入 Pending 状态,这种投票每 4 个小时进行一次。
⠀
进入 Pending 状态后,Validator 会进入一个队列等待被彻底激活,每个 Epoch 能激活的 Validators 数量受到「流失限制系数(CHURN_LIMIT_QUOTIENT)」的限制,计算方式是
⠀
max(MIN_PER_EPOCH_CHURN_LIMIT, n // CHURN_LIMIT_QUOTIENT)
⠀
其中 MIN_PER_EPOCH_CHURN_LIMIT= 4,n 是 active validators 的数量,CHURN_LIMIT_QUOTIENT = 65536。
⠀
因此以 2022 年 12 月 29 日的数据为例,目前网络中有 492,975 个 Active Validators,那么目前每个 Epoch 能激活的新 Validators 数量是 7 个,以一天 225 个 Epoch 计算,每天能激活的新增 Validators 数量是 1575 个。
⠀
3. Active
⠀
Active 状态的 Validator 可以参与 Attestation 和 propose block(开始打工),直到 Validator 的余额降低到 16ETH 以下,自愿退出或被 Slashed 为止。
⠀
如果有 Validators 错过了 Block Proposed 或者参与 Attestation,这个状态就叫离线(旷工了),如果至少 2 个 Epoch 没有参与 Attestation,Validator 就会被扣钱,通常来说一个 Validator 至少要有 50% 的时间在线才能获得正收益。但是离线状态的 Validator 仍然保持 Active 状态,只有遭到了 Slash(被发现违纪),才会被强制退出网络,并且至少没收余额的 1/32
⠀
4. Exit & Withdrawable
⠀
非活跃状态的 Validator 都会被强制离开网络(Exit)并且无法重新加入,同时另一方面,Validator 离开网络的速度也是被严格限制的。事实上,在 Pending 部分提过的 Validator 激活速度的限制其实也是对整个网络验证者离开的限制。这个限制的目的是为了防止验证者(Validator)的数量变化太快引起的对网络的不稳定。同时另一方面,对于退出网络的 Validator (Exit 状态)也需要大约 27 个小时才能提款(Exit -> Withdrawable),同时对于因为违规被惩罚而强制退出的 Validator 来说,还需要额外 36 天才能变为 Withdrawable 状态。目前信标链上主动退出的 Validators 有 867 个,被 Slashed 而退出的 Validator 有 223 个,他们目前全都是 Withdrawable 的状态。想要主动退出网络可以参考 Exit your validator | Prysm
⠀
Validators 数量和以太坊发行量以及 APR 的关系
⠀
详细可见:Upgrading Ethereum
⠀
N 是验证者的数量,225 是每天能运行的 Epoch 数量
⠀


图源
⠀
APR 和 N 的增长是一种负相关关系,这么设计有几个原因,首先是保证 APR 是一个和 N 相关的函数,这样可以避免理性的验证者在成本明显高于收益时果断退出,同时可以避免支出过高的成本来保证安全性。
⠀
另一方面,让 APR 和 N 是一种负相关关系会激励 Validators 去审查其他人的工作成果,来想办法让那些有不正当行为的 Validators 被从网络中赶出去。
⠀


图源
⠀
0x01 Credential 和 0x00 Credential
⠀
0x01 和 0x00 都是一种存款时 Validator 收到的证明,对于提款这件事来说,只需要知道只有持有 0x01 Credential 的 Validators 才可以顺利提款,因为 0x01 包含了这个 Validators 收益的目标地址,而目前绝大部分的 Validators 持有的都是 0x00 Credential,因此对他们来说需要在上海升级后升级到 0x01 Credential,具体想了解怎么升级到 0x01 Credential 可以看 [Tim 的推特](https://twitter.com/TimBeiko/status/1600939567523037184)。这种转变是由于提款方案的变化。
⠀
现在信标链有多少 Validators 和 ETH?
⠀
根据 Beaconcha.in 的数据,截止 12 月 29 日,Beacon 链上上有效质押的 ETH 为 15,775,062 ETH(这个数据统计的是用于计算 Stake 收益和惩罚的 ETH 数量),活跃(Active)的验证者数量为 492,975,总共有 494,096 个验证者,当前每个验证者平均质押的 ETH 为 33.93 ETH(也就是说 Beacon 链上 ETH 的总数为 16,764,677 ETH)。目前质押获取收益最高的 Validator 地址上有 36.9690 ETH,质押时间超过 700 天。
⠀
Withdrawal 会如何实现
⠀
Withdrawal 会由执行层和共识层共同升级实现,执行层主要是通过引入 EIP-4895 协助共识层执行提款的过程。具体来说,EIP-4895 是基于「Push」的思路架构而非「Pull」的思路完成提款,即用户无需主动发起提款请求,而是会根据 Validators 在信标链中的状态产生一个对应「收据」,这个收据包含了完成提款所需要的细节,收据们会进入一个取款队列,每个区块打包的时候会执行一部分的收据,而且在固定时间内能执行的取款请求数量是被严格限制的。
⠀
注:1)这些取款请求将是一种「系统级」的操作类型,不会独立进行也不会进入用户正常交易的 mempool 中,换言之,提款会在交易结束后进行,因此不会和用户去竞争区块空间。只有当执行客户端通过 Engine API 进行同步时,才会进入到执行区块中。因此提款行为不会提高以太坊的 gas 或者让以太坊更拥堵
⠀
2)Payload 用于告诉合约用户想要调用的函数及这个函数用到的参数的值。System-level operation 意味着将会定义一种新的 payload object `withdrawal` 来将提款行为和用户正常的 Transaction 行为区分开来,而不是将提款定义为一种新的 Transactions 类型,这种方法虽然更复杂但是实现起来更易于测试也更安全。更多关于 Payload 可以看
⠀
What-is-the-use-of-the-payload-field-in-the-ethereum-transaction-reciept
Understanding-data-payloads-in-ethereum-transactions
⠀
3)Capella Upgrade 的内容
⠀
Capella is a consensus-layer upgrade containing a number of features related to validator withdrawals. Including:
⠀
Automatic withdrawals of `withdrawable` validators.
Partial withdrawals sweep for validators with 0x01 withdrawal credentials and balances in excess of `MAX_EFFECTIVE_BALANCE`(32ETH).
Operation to change from `BLS_WITHDRAWAL_PREFIX`(0x00) to `ETH1_ADDRESS_WITHDRAWAL_PREFIX`(0x01) versioned withdrawal credentials to enable withdrawals for a validator.
⠀
Withdrawal 的条件
⠀
Withdrawal 分两种。「部分提款(Partial Withdrawal)」和「全部提款(Fully Withdrawal)」,对应不同的条件,部分取款和完全取款不会有优先级上的区别,因为提款是全自动进行的,也就是说只需要满足必要条件然后等着就行了。
⠀
必要条件:Validator 具备 0x01 Credential
部分提款条件:Validator 是 Active 状态,同时 Validator 的余额大于 32ETH
全部提款条件:Validator 是 Withdrawable 状态(这通常意味着 Validator 已经退出网络)
⠀
提款具体会如何进行
⠀
可以直接看 https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#has_eth1_withdrawal_credential
⠀
Validator propose 区块的时候,会按 Validator 的 index 去线性扫描所有 Validators,找到的前 16 个满足 Withdrawal 条件的 Validators 会组成一个集合被包含在 ExecutionPayload 中,等待取款执行。
⠀
也就是说,每个 Epoch 会有 512 个 Validator 可以取款(因为一个 Epoch 有 32 个 Slot,而一个 Slot 一个区块),一天有 115,200 个 Validators 会被执行取款(一个 Epoch 6.4 分钟,一天大概有 225 个 Epoch),5 天之内所有 Validator 现有的所有 Validators 都会被遍历一边。
⠀
理想状态下,如果这 115,200 个取款都是 Partial Withdrawal,那么根据 index 从低到高,index 前 115,200 个 Validator 的可供提取的余额在 3 - 4 ETH(根据 beaconcha 数据质押最早的 Validator 余额大概是 36.3 ETH,第 115,200 个 Validators 的余额大概是 35 ETH),以中间数 3.5 ETH 来计算,第一天因为取款功能解锁的 ETH 大概是 403,200 个 ETH(115200 * 3.5)。同样的计算方式,升级第二天大概解锁 2.5 * 115,200 = 288,000 ETH,第三天大概解锁 1.5*115200 = 172,800。第四天大概解锁 0.5*115200 = 57,600 ETH,从第五天开始,已经有大部分 Validators 进行过提币了,因此不会在产生像前几天那么大的抛压。
⠀
注:ETH 开质押的时候是 2020 年 12 月,此时 ETH 的价格在 $1,000 左右,因此此后参与质押的 ETH 大部分和当下的价格相比都是亏损的。
⠀

图片来自:Cryptorank
⠀
但是事实上,提款并不可能总是如预期那么顺利,总会有一些意外情况让实际的提款金额高于或低于理想值。
⠀
让解锁金额低于理想值的情况
⠀
并不是所有 Validators 都是 0x01 Credential,也并不是所有 Active 的 Validators 都有 32 ETH。因此有一部的 Validators 是不满足提款条件的(原因千奇百怪),这些不符合规则的 Validator 会在遍历的时候被 Pass,由于这个 Pass 机制的存在,Validator 在遍历(Sweep)的时候的时候是有上限的,这个上限是`MAX_VALIDATORS_PER_WITHDRAWALS_SWEEP` = 16384(2**14)
⠀
让解锁金额高于理想值
⠀
会有 Validators 选择全部取款的选项。理论上如果前 115,200 个 Validators 全部选择全部取款,那么第一天的解锁金额就是 3,686,400 ETH。但是想要全部提款的前提是退出网络,而每天能退出网络的 Validators 数量严格受到「流失限制系数」限制,目前每天能退出网络的 Validators 数量上限是 1,575。
⠀
提款可能的影响
⠀
注:以下都只是个人做的时候想到的一些问题和自己的看法,不是投资建议
⠀
Q1:解锁的 ETH 是否会在市场上大量抛售
⠀
很大概率不会,虽然在升级的前几天,解锁的 ETH 量很大,但是解锁并不意味着会出售。这批解锁 ETH 的质押者的成本以目前 ETH 的价格来说并不低,作为在不知道解锁何时会发生就加入了 ETH 质押的用户来说,相信大部分都是 long ETH 的(没有证据纯猜测),没有足够获利的情况下个人认为并不会选择出售 ETH 反而可能会选择再质押。同时由于开放提款后,质押 ETH 有了更明确的解锁时间和解锁期限,也就意味着更低的风险,相信也会吸引更多的用户参与质押。
⠀
Q2:会对流动性质押服务产生什么样的影响
⠀
在此处以 Lido 为例,进行一个猜测。
⠀
根据提款的流程,大部分的提款都将会是通过「部分提款」的方式,也就是说对于流动性质押服务商来说,实际能解锁的 ETH 只有平台运行的 Validator 的利润部分,除非平台主动去让 Validator 进行退出来,然而显然从各种角度来说,平台都没有动力这么做。
⠀
那么会导致一个极端情况出现,就是如果 stETH 在解除质押后可以立即 1:1 兑换成 ETH,那么一旦大量 stETH 的持有人去申请兑换,且这个总量超过了当时 Lido 通过 ETH 提款得到的 ETH 的总量的时候,就会发生 stETH 没有 ETH 可以兑换的情况(因为实际上还锁着呢),所以即使开放解锁后,stETH 和 ETH 的 1:1 兑换仍然会需要一段缓冲期,让平台有时间去解除 Validator 的质押,也正因为这个时间差的存在,stETH 为代表的质押衍生品在上海升级后,将仍然会以一个略低于 1:1 的汇率和 ETH 组池。
⠀
延迟提款有一个好处是,降低了挤兑造成的恐慌和风险。此外还有另一个潜在的好处,就是 Lido 遇到的困境所有流动性质押服务商都会遇到,因此 ETH 质押延迟取款将很有可能成为流动性质押服务商的一种通用模式。为什么这是件好事呢?因为 stETH 的护城河之一是其良好的流动性和可组合性,但有一种担忧是,在解除质押后,stETH 的流动性优势由于质押衍生品都可以 1:1 兑换 ETH 而消失了,但是由于延迟取款的机制存在,stETH 将仍然保存他的流动性优势。
⠀
想了解更多关于取款的事情,可以看下面几个资料:
⠀
https://www.youtube.com/watch?v=CcL9RJBljUs
https://notes.ethereum.org/@ralexstokes/validator-withdrawals-meta-spec
⠀
EOF
⠀
可能涉及的概念
⠀
EVM
⠀
以太坊和比特币最重要的区别之一就是加入了智能合约,而 EVM 可以被理解为运行智能合约的操作系统。推荐阅读:https://noxx.substack.com/p/evm-deep-dives-the-path-to-shadowy?s=r
⠀
Byte code
⠀
通常开发者可以用名为 Solidity 的高级编程语言编写智能合约,但是 Solidity 编写出来的智能合约人类读得懂计算机却读不懂,因此需要交由 EVM 解释(interpret)成 EVM bytecode 再交由计算机运行,把人类能读懂的高级语言(Solidity)变成只有计算机能读懂的语言(bytecode)。
⠀
下图中,上面这串不明所以的十六进制代码就是 bytecode,他们有个明显的特征就是 0x 开头的,0x 开头会让 EVM 把接下来的一连串当作十六进制来读;下面是编译前由 Solidity 所写的合约代码
⠀


图片来自:Etherscan 随便找了一笔交易截图
⠀
opcode 操作码
⠀
opcode a.k.a operation code,简单来讲 bytecode 通常就是一连串 opcode 与其输入值。opcode 代表了 EVM 的一些相对可读的操作指令,这些指令都有严格对应的十六进制代码,如 `ADD` 对应 0x01。每个 opcode 都是要 gas 的。
⠀

图片来自 https://ethervm.io/
⠀
Stack Machine
⠀
EVM 是一种 Stack Machine,采用 LIFO(Last in,First Out)的方式进行读取,简单理解就是 EVM 操作码的输入值都会进入栈里,并且由按照栈。以太坊理论上最多有 256 个操作码,每个操作码都会将栈顶的元素出栈,将结果入栈。了解更多可以看深入简出栈
⠀
Process flow operations
⠀
Process flow operations 主要是指以下几个 opcode
⠀

⠀
Stop:停止 EVM 代码的运行
⠀
PC:程序计数器,用于指定当前读取字节码的字段,会确认字节码下一个要执行的指令在哪里,然后可以通过 JUMP 跳转到需要执行的函数。
⠀
JUMP:改变下一个要执行的指令
⠀
JUMPI:有条件的 JUMP
⠀
JUMPDEST:JUMP 的目的地
⠀
offset:偏移量,用来表示每个指令的所在位置,以字节作为单位。位、字节、字是计算机数据存储的单位。位是最小的存储单位,每一个位存储一个 1 位的二进制码,一个字节由 8 位组成。而字通常为 16、32 或 64 个位组成。
位(bit)是最基本的概念,在计算机中,由于只有逻辑 0 和逻辑 1 的存在,因此很多东西、动作、数字都要表示为一串二进制的字码例如: 1001 0000 1101 等等。其中每一个逻辑 0 或者 1 便是一个位。
⠀
字节(byte),是由八个位组成的一个单元,也就是 8 个 bit 组成 1 个 Byte。字节有什么用呢? 在计算机科学中,用于表示 ASCII 字符,便是运用字节来记录表示字母和一些符号~例如字符 A 便用 「0100 0001」来表示。
⠀
字(Word)代表计算机处理指令或数据的二进制数位数,是计算机进行数据存储和数据处理的运算的单位。对于 32 位计算机与 64 位计算机,字的大小往往不同。
⠀
智能合约部署
⠀
要部署一个智能合约,只需发送一个包含编译后的智能合约代码的以太坊交易,而不需要指定任何收件人。目前由于以太坊是把编译好的智能合约包含在交易中,没有源代码,因为以太坊执行智能合约的时候面对的是 bytecode,难以在运行前事先验证智能合约的正确性。
⠀
EOF 是什么
⠀
EOF 是对 EVM 的升级,引入了新的合约标准和一些新的操作码,传统的 EVM 字节码(bytecode)是非结构化的指令序列(unstructured sequence of instructions)字节码。EOF 引入了容器(container)的概念,它实现了结构化的字节码。容器由一个 header 和几个 section 组成,来实现字节码的结构化。升级后 EVM 将可以进行版本控制,并且同时运行多套合约规则。本次 EOF 升级将由 5 个 EIP 共同组成来实现,分别是 EIP-3540, EIP-3670, EIP-4200, EIP-4750 和 EIP-5450。由于 EOF 是一个庞大的升级,因此为了保证 1 月能顺利开启提款,它可能会被推迟。
⠀
具体可以看 EVM Object Format(EOF)
⠀
EOF 的意义
⠀
简而言之,EOF 是一套新的合约规则。目前在运行的 EVM 只能同时运行一套 interpretation 和 validation 的规则,这套规则会适用于所有现存的合约,称之为 Legacy contracts。EOF 引入了一套新的合约规则,同时对 EVM 的 interpreter 进行了对应的升级。升级后就可以 EVM 就可以并行运行两套合约规则,一套 EOF contracts,一套 Legacy contracts。
⠀
有了 EOF 后,EVM 来说在进行迭代的时候,就不再受限于向前兼容的需求,升级难度变低了可能会导致未来以太坊 EVM 的升级可能更频繁。
⠀
EVM 迭代频繁可能会导致对 EVM 兼容的虚拟机有更高的要求,如 zkEVM,要想保持始终能跟上版本,可能需要其他 EVM 兼容的 VM 有自动转化 EOF 更新到自己的 VM 的能力。
⠀
具体每个 EIP 分别做了什么
⠀
EIP-3540: EVM Object Format (EOF) v1
⠀
从前链上部署的 EVM 字节码都是没有一种预先定义的同一结构的,代码只有在客户端中被运行前才会被验证,这既是一种间接成本,也会阻碍开发者引入新功能或弃用老功能。此 EIP 为 EVM 引入一种可以拓展和版本控制的 container,并且声明了 EOF 合约的格式(如下图),以此为基础就可以实现在部署 EOF 合约的时候对代码进行验证,即 creation time validation,意味着可以防止不符合 EOF 格式的合约被部署,这种改动实现了 EOF 版本控制,会有助于未来停用 EVM 已有的指令或者引入大型功能(如账户抽象)
⠀
这个 EIP 提供的第一个 tangible feature 是对数据和代码进行了区分,这种区分非常有助于 on-chain code validators,这会节省它们的 gas 消耗
⠀
EIP-3670: EOF - Code Validation
⠀
EIP-3670 基于 EIP-3540 ,目的是确保 EOF 合约的代码是符合格式有效的,对于不符合格式的合约会阻止其部署,不会影响 Legacy bytecode。
⠀
EIP-4200: EOF - Static relative jumps
⠀
EIP-4200 引入了第一个 EOF 专用的 opcode:RJUMP、RJUMPI 和 RJUMPV,它们 encode destinations as signed immediate values。编译器可以使用这些新的 JUMP 操作码来优化部署和执行 JUMP 时的 gas 成本,因为它们消除了现有 JUMP 和 JUMPI 操作码在做 jumpdest analysis 时所需的运行时间。这个 EIP 是对 dynamic jump 的补充。
⠀
和传统的 JUMP 操作比,区别在于 RJUMP 等操作不是指定一个具体的 offset 位置,而是指定一个相对的 offset 位置(从 dynamic jumps -> static jumps),因为很多时候 static jumps 就够了
⠀
EIP-4750: EOF - Functions
⠀
EIP-4750 将 4200 的功能更进一步:通过引入 `CALLF` and `RETF` 两个新的 opcode 是,为无法用 RJUMP、RJUMPI 和 RJUMPV 代替的情况实现了替代方案,以此实现了在 EOF 合约中再也不需要 JUMPDEST 了,也就因此禁止了 dynamic jump。
⠀
EIP-5450: EOF - Stack Validation
⠀
EIP-5450 为 EOF 合约添加了另一个有效性检查,这次是围绕堆栈(stack)。这个 EIP 可防止 EOF 合约部署可能导致堆栈下溢或溢出的情况(stack underflows / overflows)。这样,客户端可以减少他们在执行 EOF 合约期间进行的有效性检查的数量。
⠀
背景仍然是以太坊的合约现在在部署的时候是不检查的,只有在运行的时候才会进行一系列的检查,栈有没有溢出(上限 1024),gas 够不够之类的。EOF 有一大改进就是让这些执行的时候才发生的检查尽可能的少,更多的检查都在合约部署的时候就发生。
⠀
其他小升级
⠀
EIP-3651: Warm COINBASE
⠀
要理解 EIP-3651 首先要理解 EIP-2929,因为 EIP-3651 其实是解决一个 EIP-2929 造成的问题。
⠀
那么什么是 EIP-2929?
⠀
EIP-2929 全称 State Assess Lists,简单来说,EIP-2929 让一些交易在第一次触发的时候更贵了(根据 access storage 的类型不同 gas 费用不一样),因为这些交易的地址访问需要一个从 Cold 到 Warm 的过程,首次触发后,这个地址会变为 Warm 状态,Warm 状态意味着后续访问同一个地址的时候会更便宜,因此如果同一笔交易内对如果要执行同一个 Opcode 多次,那么会比更便宜,而有些 accounts 是默认 warm 的。EIP-2929 当时默认了 sending address 和 receiving address 是 warm 的。其实 EIP-2929 并没有降低平均的 gas 消耗,甚至略有增加(上升了 0.3% - 0.4%),因为 EIP-2929 的主要目的是为了提高 DoS 攻击的成本,所以要提高 state access opcode 的 gas 消耗,同时为了平衡实际中用户发起交易要用到的 Gas,就将一些使用频率高的 account 默认 warm 了。
⠀
EIP-3651 则是要将 `COINBASE` address 也会默认 warm,`COINBASE` address a.k.a feeRecipient address。这个改动主要是为了解决 EIP-2929 导致 `COINBASE` 初始为「Cold」状态导致涉及 COINBASE 地址的交易费用变贵的问题。具体的改动方式就是将 COINBASE 的地址加入到 EIP-2929 提出的 Access List Framework 中,让`COINBASE` 的地址也默认是 Warm 状态的,这样和 COINBASE 地址交互就不会比 Access list 中其他地址交互消耗更多费用。
⠀
EIP-3651 带来的影响是 MEV extractors, Block builders 和 Vailidators 会在涉及到 COINBASE 地址的交易中降低成本,因为 COINBASE 在 contional payments 中被大量 block builders 使用,根据 William Morriss 所说,EIP-3651 实施后,和 COINBASE Address 交互的大概费用会降低 26 倍,以前 State access includes accounts 大概需要 2600 gas,warm 后只需要 100。
⠀
注:什么是 COINBASE Address
⠀
此处的 COINBASE 指的是 Block builders 用来在网络中接受新 token 的 Software。Block builder 通常将交易从 mempool 中打包成区块发送给 Validator 进行排序,并从中收取利润。而在每一笔交易中都需要和 COINBASE Software 进行多次交互,而第一笔交互通常会比较贵,因为目前 COINBASE Address 需要 Warm up,然后交互费用会随着交互数量上升慢慢下降,而 EIP-3651 可以让 COINBASE 一开始就是 Warm up 的状态,这样会降低转账给 COINBASE 的费用
⠀
conditional payments:EIP-1559 使 conditional payments 成为了可能,大量 flashbots 使用了这个方法,即将 MaxPriorityFeePerGas 设为 0,这样在交易失败的时候就不会收取 Gas Fee。同时这些失败的交易也具有良好的抗审查性,因为他们失败了,block builder 没有收取 Gas 也就不会将他们的信息保存。但是要使用 conditional payments 需要接入 COINBASE Account
⠀
EIP-3855: PUSH0 instruction
⠀
引入一种新的 opcode 来把 0 值 push 到 stack 里。PUSH 0 是 EVM 中一种常见情况(有 11.5% 的 PUSH* 指令都用来 PUSH 0 值到 stack 里了),这个 EIP 会提供一种更高效更便宜的方式来实现这一点(现在是通过 `PUSH1 0` 等方式),同时为所有需要把 0 值放入 Stack 的情况提供了一种统一标准的用法
⠀
EIP-3860: Limit and meter initcode
⠀
This EIP adds a maximum size for `initcode` and introduces gas metering based on its length. The size limit adds an invariant to the EVM which will make it easier to reason about and propose changes to.
⠀
A 2 gas/32 byte cost for `initcode` is introduced to account for the jumpdest-analysis clients must do prior to execution, which previously was not accounted for in the gas schedule.
⠀
如果本文有任何事实上的错误,若能批评指正万分感激,如果有意见不同的地方,也欢迎讨论,另外本文毫无投资建议,纯纯的好奇心驱使。





