← COMP5565 全部讲次
L02 · 第 2 周

L02 Ethereum:一台全村共用的计费电脑

账户怎么来、状态怎么存、gas 怎么算、出块权怎么分。

一句话版

以太坊是一台全网共跑的状态机:账户是键,交易是状态转移,gas 是计费器。

新手入口:先懂“私钥签、公钥验”。第一遍只看账户、状态和 gas;MPT 编码与 PoS 参数可第二遍读。学完应能用英文解释“交易失败”为什么要分情况。

一个类比:一台全村共用的计费电脑

村里有一台电脑,谁都能用,用之前先投币。电脑上有两种目录:一种归某个人,凭钥匙开(EOA);一种是装好的程序,自己不会动,得有人去点它才跑(合约账户)。程序目录没有钥匙——它不是”钥匙丢了”,是从设计上就没配过,所以村里任何一次运行的源头必然是某个拿钥匙的人。

硬盘上的总目录表就是世界状态,记着账户余额、计数器和存储位置。运行按步数计费:顶层执行耗尽 gas 时,回滚执行产生的状态变化,但照付费用;未通过基础有效性检查则根本不执行。轮值管理员从质押者中选出。

类比在哪里失效:真实网络由许多节点各自执行、校验,不能靠管理员任意改账。EIP-1559 的 base fee 被销毁,不归提议者。合约也不能直接上网取数据,外部信息需要通过交易等机制引入。

概念卡

1. 两类账户(EOA / Contract Account)

人话定义:本讲基本模型里,EOA 是私钥控制的账户;合约账户由部署的代码控制,没有对应的私钥。

英文注意|account / address / wallet:account 是账户,address 是标识账户的地址,wallet 是管理密钥、发起交互的工具;EOA = Externally Owned Account答题句:A wallet manages keys; an address identifies an account.

英文注意|account nonce:EOA 的 nonce 是交易计数器,不是随机数;不要套用猜拳承诺中 random nonce 的含义(p.21)。 答题句:An EOA nonce orders its transactions and helps prevent replay.

例子:创建成本上 EOA 免费(离线生成,不上链),合约账户要花钱(占网络存储)。主动性上只有 EOA 能主动发交易,合约可以调合约,但整条调用链的源头一定是 EOA(p.17、p.18)。钱包的定义比日常用法窄:钱包 = 一个或多个 EOA 的集合,它不上链也不持有资产,只是管私钥的软件(p.11)。两边的字段摆一起看(p.21、p.22):

EOA 与合约账户的四个字段并排对照:两边都是 Nonce、Balance、storageRoot、codeHash,格式一字不差;EOA 的 storageRoot 是空树的根、codeHash 是空字符串的哈希这个恒定常量,合约账户的后两格分别指向自己的存储树和部署上去的字节码;只有 EOA 能主动发起交易

常见误解

以为合约账户是”特殊的 EOA”或者”私钥被销毁了” → 两类账户的数据结构完全相同,区别只在合约账户的后两格真的指向了东西(p.21、p.22)。

2. 世界状态与 Merkle Patricia Trie

人话定义:世界状态是「地址 → 账户状态」的映射,写作 σ_t;把这张表组织成一棵 Merkle Patricia Trie,根哈希就是区块头里的 stateRoot。

英文注意|state / transaction:state 是当前状态,transaction 请求状态转移;stateRoot 是状态摘要,不是完整状态内容。 答题句:The state root commits to the resulting world state, while the transaction root commits to the transactions in one block.

例子:MPT 三类节点——Extension 压掉多个 key 的公共前缀,Branch 有 16 个槽按下一个 nibble 选路,Leaf 存剩下没走完的 key-end 加 value。沿「根扩展 a7 → 分支槽 7 → 扩展 d3 → 分支槽 9 → 叶子 key-end 7」走一遍,拼回来是 a77d397,value 0.12 ETH(p.32):

Merkle Patricia Trie 的分层结构:根部是 Extension 节点 a7,往下进 Branch 节点走第 7 号槽,再经 Extension 节点 d3、Branch 节点第 9 号槽,最后落到 key-end 为 7、value 为 0.12 ETH 的 Leaf 节点;图右侧还列着 prefix 取值 0、1、2、3 的含义和简化版世界状态表
图片来源:COMP5565 Lecture2.pdf, p.32

prefix 同时编码节点类型和 nibble 奇偶:0 偶扩展、1□ 奇扩展、2 偶叶子、3□ 奇叶子,理由是奇数个 nibble 没法按字节对齐,补一位之后得让读的人知道补过(p.32)。

常见误解

以为每个区块都要重建整棵状态树 → 一次状态变更只重写从被改叶子到根的那条路径,其余子树原样指回上一个区块的节点:Dorothy 转给 Emily 0.01 ETH 之后,Alice 和 Bob 的叶子完全没重画(p.33)。还要注意 stateRoot 是「所有交易执行完之后」的状态根(p.32);新 key 若与已有 key 共享更长前缀,原叶子会裂成一个分支加两个更短的叶子(p.33)。

3. Gas 与 EIP-1559

人话定义:gas 衡量一笔交易要多少计算量,付费用 ETH、报价用 gwei。EIP-1559 把”拍卖出价”改成了”协议定底价 + 用户加小费 + 底价销毁”。

例子:总费用 = gas used × 实付单价。base fee 由协议确定并销毁,小费给验证者,max fee per gas 封顶。课件模型以 50% 利用率为目标调节 base fee(p.54、p.55)。

英文注意|gas limit / gas used / fee per gas:分别是额度、实际消耗、每单位价格。用量单位是 gas,价格单位是 gwei/gas,乘积才是费用。 答题句:The gas limit is a cap, not the amount of gas actually consumed.

补充:对有效的 EIP-1559 交易,实付小费 = min(maxPriorityFeePerGas, maxFeePerGas − baseFee);不能把小费上限直接当实付。普通转账例子如下。

英文注意|invalid / out of gas / revert:先区分“不满足入块条件”和“执行后失败”。REVERT 回滚执行效果,但不必耗尽剩余 gas。 答题句:A reverted transaction still pays for gas consumed; an invalid transaction is not executed in a valid block.

一笔标准转账的手续费拆分:gas limit 21,000,base fee 100 gwei,小费 10 gwei,合计 2,310,000 gwei 也就是 0.00231 ETH;横条按 100 比 10 分成两段,左边一大段 0.0021 ETH 是被协议直接销毁的 base fee,右边一小段 0.00021 ETH 是归验证者的小费

常见误解

以为销毁只为通缩 → 它还移除了提议者直接收取 base fee 的收益(p.60)。通胀还是通缩取决于发行量与销毁量之差;p.62 的约 +0.88% 是课件截图口径,不是实时数据

4. PoS 的时间骨架与随机性

人话定义:出块权不靠算力竞争,靠按质押加权的随机抽签。时间被切成固定长度的 slot 和 epoch,随机源是 RANDAO。

英文注意|slot / epoch / finality:slot 是时隙,epoch 是一组时隙;finality 是最终性,不等于刚被打包。参数和时间估计须注明协议条件。 答题句:Inclusion in a block does not by itself imply finality.

例子:1 slot = 12 秒,1 epoch = 32 slots = 6.4 分钟,这一讲所有时间数字都从这两个推出来(p.80)。RANDAO 累积更新为 mix_new = mix_old ⊕ Hash(randao_reveal)randao_reveal 本身是对 epoch number 签名根的 BLS 签名,不是签名的哈希(p.93,补充校订)。委员会目标规模是 128;活跃验证者充足时才保证至少这个数。一个 epoch 内每个活跃验证者分配到一个委员会(p.91)。

常见误解

以为 epoch N 攒的随机数当场就能用 → 要等到 epoch N+2,隔一整个 epoch。延迟本身就是防操纵设计:既给网络留同步时间,也让最后一个贡献者看不到”这个值会给我带来什么”(p.94)。签 epoch number 而不是自选内容同理——epoch 号确定、BLS 签名又是确定性的,同一个 epoch 里他只能产生唯一一个合法签名,没法试很多个挑对自己有利的。异或则保证只要有一个诚实贡献者结果就随机,残余攻击面只剩”拒绝出块”这种二选一(p.93)。

5. 罚没三种行为(Slashing)

人话定义:PoS 里投票不花钱,分叉时给所有分支都下注是自利策略,所以必须人为造出成本——罚的是质押本金,不是只扣奖励。

例子:三种行为分别长这样(p.109、p.110):

三种罚没条件:同一 slot 双重提议;同一 target epoch 的两个不同证明;证明 A 的 source/target epoch 为 1 到 4,严格包围证明 B 的 2 到 3

判断口诀是看两次证明的 [source, target] 区间,一个严格包含另一个就是 surround。

常见误解

需要提交可验证的违规证据,协议验证后罚没并强制退出。处罚包括初始罚金、退出等待期间的处罚及相关性罚金;许多验证者一同被罚时,损失可更大。补充:课件跨越多个协议版本,奖励分母、余额上限等不能混用;罚没不是只针对持续作恶,一次可证明的违规也可触发(p.112–116)。

把它们串起来

这一讲一次讲完了”以太坊是什么”的四大块,抓两条线就不会散。数据线:账户 → 账户状态四字段 → 状态树 → stateRoot → 区块头。每一环都在做同一件事——把庞大的数据换成一个定长哈希塞进上一层,所以区块本身不装账户数据,只装那个根。上一讲的 Merkle 证明在这里直接兑现成了轻节点的工作方式。

经济线:交易消耗 gas → 用户付费 → 底价销毁、小费给验证者。供应量变化还要合并计算协议发行量,不能从“有销毁”直接推出“必定通缩”。

两条线在共识处合上:提议者组织区块,其他节点按协议校验。课件合并后的简图省略旧 PoW 字段,不代表真实数据结构把所有旧字段都删除了。

课件里的坑

  • [补充核验] p.57 的 20,000 gas 例子不能用于解释执行耗尽:它低于普通转账的 intrinsic gas,不能执行入块。REVERT 与耗尽 gas 也不同。依据:EIP-1559Geth 检查EIP-140

  • [补充核验] CREATE 也能预计算地址;CREATE2 的区别是不依赖 nonce,且使用 init_code 的哈希。依据:EIP-1014

  • [页码提醒] 整份课件的页脚编号和实际页序不一致,p.41 和 p.84 两处跳号:1–40 相同、41–83 是页序加 1、84–128 是页序加 2。按页脚翻页越往后差得越多(p.11)

  • [排印勘误] p.15 的 Keccak256(pk) 印了 104 个十六进制字符,超过 256 位摘要应有的 64 个,后 40 个重复地址。本轮确认的是长度与重复问题,未完整重算公钥派生摘要;地址规则是在正确的 64 字符摘要中取后 40 个。

  • [历史口径] p.45–48 的 12.5M/25M 与 p.56 的 15M/30M 是不同数值示例,都体现目标为上限一半。不能仅凭不同判错,也不要将其中一页当作当前或永久的网络参数。

  • [课件有误] p.49 的费用图纵轴标成 “ETH per Gas”,实际读数是 Gwei,差 10⁹ 倍;同页还标了 “(GWei)” 去指 gas 单位数,也是错的(p.49、p.56)

  • [读图提醒] p.114–115 的原始 PDF 印有分母的平方根,只是纯文本提取可能漏掉。余额按 Gwei 代入,课件连续近似约为 12,034.57 Gwei;不要把提取遗漏误判成课件漏印。

  • [课件有误] p.84 和 p.113 标题写的 “Post-Petra” 应为 Pectra,p.85 自己的截图里就显示着 “Pectra.info”(p.84、p.113)

课后 10 分钟:考点复习

这 10 分钟怎么用:合上页面,先默写三条——两类账户与 EOA 地址生成四步、总费用 = gas × (base fee + 小费)、slot 与 epoch 的时间骨架;再把下面的「变式题」做一遍;最后回查两个最容易错的地方——以为烧 base fee 只是个通缩故事、以为交易失败就不用付 gas。三步做完再往下看答案。

必背

  1. EOA 地址生成四步:ECDSA 生成私钥 sk → 推出公钥 pk → keccak256(pk) → 取这 64 个十六进制字符里的最后 40 个(160 bit)。
  2. CREATE 由部署者和 nonce 决定地址;CREATE2 由部署者、salt、init_code 哈希决定地址;两者均可预计算,后者不依赖部署者 nonce。
  3. 账户状态四字段 Nonce / Balance / storageRoot / codeHash,后两个存的是哈希不是数据;本讲无代码委托的普通 EOA,其 codeHash 是空字符串的 keccak256,不是全零。
  4. 本讲普通交易模型中 EOA 发起交易;to 留空表示创建合约;标准 ABI 调用的 Data 是函数选择器加编码参数,函数签名不等于数字签名。
  5. 总费用 = gas used ×(base fee + 实付 priority fee);普通 ETH 转账消耗 21,000 gas;base fee 销毁,小费归验证者;max fee per gas 是封顶,课件区块目标 15M、上限 30M 是示例参数。
  6. 先区分无效交易、执行耗尽 gas 与 REVERT;低于 intrinsic gas 的交易不执行入块,执行失败仍按规则付 gas,REVERT 不必耗尽剩余 gas。
  7. 1 slot = 12 秒,1 epoch = 32 slots = 6.4 分钟;最终性 = 2 epochs ≈ 13 分钟;成为验证者要押 32 ETH。
  8. 三种可罚没行为:Double proposal(同一 slot 出两个块)、Double vote(同一 target epoch 作出两个不同的证明)、Surround vote(一次证明的 [source, target] 区间严格包含另一次)。

完整例题

题面(据课件 p.58–59,补足条件):Jordan 向 Taylor 成功转账 1 ETH,无额外 calldata,实际消耗 gas used = 21,000,base fee 100 gwei,实付小费 effective priority fee 10 gwei。求手续费及分配。这里 gas limit 也为 21,000,但一般交易不能把 limit 直接当 used。

  1. 套公式:总费用 = 消耗的 gas 单位数 ×(base fee + priority fee)。
  2. 每单位 gas 的实付单价 = 100 + 10 = 110 gwei
  3. 总手续费 = 21,000 × 110 = 2,310,000 gwei
  4. 换回 ETH:gwei 除以 10⁹,得 0.00231 ETH。这步是最常见的失分点,别停在 gwei 上。
  5. Jordan 账户共扣 1 + 0.00231 = 1.00231 ETH(本金加手续费)。
  6. Taylor 收到 1.0000 ETH,收款方不承担手续费。
  7. 拆手续费的去向。给验证者的小费 = 21,000 × 10 gwei = 210,000 gwei = 0.00021 ETH
  8. 被销毁的底价 = 21,000 × 100 gwei = 2,100,000 gwei = 0.0021 ETH,退出流通。
  9. 回验:0.00021 + 0.0021 = 0.00231 ✓ 等于第 4 步的总手续费。销毁那份是小费的十倍,绝大部分手续费被烧掉了

变式题(先自己做)

English question(自编练习):Morgan sends 2 ETH to Riley. The transaction uses 21,000 gas. The base fee is 25 gwei per gas and the effective priority fee is 5 gwei per gas.

Calculate the fee in ETH and its split. Compare the burned proportion with the worked example.

提示

读题:calculate 要算金额,compare 要比较比例;effective 表示实付。本题已给 gas used,不能拿 gas limit 替代它。费用求出后由 gwei 换成 ETH。

建议得分点与答案(非官方评分细则)

Suggested answer: The fee is 0.00063 ETH: 0.000525 ETH is burned and 0.000105 ETH goes to the validator. The burned proportion decreases from about 90.9% to 83.3%, because the tip is larger relative to the base fee.

自检点:按题意换成 ETH;核对两份之和;说明比例变化原因。以下中文演算用于核对。

  1. 实付单价 = 25 + 5 = 30 gwei;总手续费 = 21,000 × 30 = 630,000 gwei = 0.00063 ETH
  2. 销毁 = 21,000 × 25 = 525,000 gwei = 0.000525 ETH;小费 = 21,000 × 5 = 105,000 gwei = 0.000105 ETH。相加 630,000 ✓。
  3. Morgan 共扣 2.00063 ETH,Riley 收到整 2 ETH。
  4. 销毁占比 = base ÷ (base + tip):100/110 ≈ 90.9%,25/30 ≈ 83.3%。同一笔交易的 gas used 在分子分母中约掉,比例由实付价格的拆分决定。

闪卡自测

1. 为什么说链上一切执行的源头都是 EOA?

合约账户”只能在收到一笔交易时作出响应”,自己不会主动动。合约可以调用另一个合约,但整条调用链往回追,第一笔交易必然由某个 EOA 签发(p.17、p.18、p.36)。

2. EOA 的 codeHash 是什么?为什么不用全零?

在本讲无代码委托的普通 EOA 模型中,是空字符串的 keccak256,一个固定常量 c5d2460186f7233c…。用它而不用全零,是为了让所有账户的字段格式统一,不必给 EOA 开特例(p.21)。

3. CREATE 和 CREATE2 都能预计算地址,差别是什么?

已知部署者与所用 nonce 时,CREATE 也能预计算。CREATE2 使用部署者、salt 与 init_code 哈希,不受部署者 nonce 变化影响。不要把“可预计算”误当成 CREATE2 独有(p.24,补充核验见上)。

4. State Root 和 Transaction Root 分别是哪棵树的根?哪个跨区块累积?

State Root 是所有账户构成的树,覆盖全链当前状态,跨区块累积;Transaction Root 是本区块内所有交易构成的树,每块各有一棵、互不相干。前者是状态快照,后者是操作清单(p.29)。

5. MPT 里 key-end 为 `1355` 的叶子 prefix 是 `2`,key-end 为 `7` 的却是 `3□`,为什么?

prefix 同时编码节点类型和 nibble 个数的奇偶:0 偶扩展、1□ 奇扩展、2 偶叶子、3□ 奇叶子。1355 是 4 个 nibble(偶)加叶子 → 27 是 1 个(奇)加叶子 → 3□。存在的理由是奇数个 nibble 无法按字节对齐,补一位后必须让读的人知道补过(p.32)。

6. 一笔交易的 to 为空、Data 里是一大段字节码,这是哪类交易?

创建合约,Data 携带初始化代码。标准 ABI 函数调用则放函数选择器与编码参数;给合约发送空 Data 仍可能触发其接收逻辑,不能一概当作无代码执行的纯转账(p.41,补充)。

7. gas limit 设成 20,000 去做一笔标准转账会怎样?

低于 intrinsic gas,交易不满足有效性条件,不能在有效区块中执行,不会先烧掉 20,000 gas。这与执行后 out of gas 不同。设 50,000 而实际用 21,000,则不用为未消耗的 29,000 gas 付执行费(p.57,补充核验见上)。

8. 为什么 EIP-1559 要烧掉 base fee 而不是给矿工?

它使提议者不能直接收取底价,也影响 ETH 的净供应变化。是否通缩要比较发行与销毁,不能只凭“烧 base fee”判断;课件截图不代表当前读数(p.60、p.62)。

9. 一个委员会有 150 人,105 人投了赞成,区块一定被接受吗?

不一定。2/3 多数是按存款总额算的,不是按人数算的——要看这 105 个人的质押总额是否达到该委员会全体的 2/3。这是 PoS 与”一人一票”的根本区别(p.101)。

10. 全网至少 16,384 个验证者这个下限是怎么论证的?

论证是:即使攻击者控制了全部 16,384 个验证者中的三分之一,他也极不可能在一个随机选出的 128 人委员会里控制超过三分之二。三个支点缺一不可——委员会由 RANDAO 加洗牌随机抽样、攻击者要在具体小组里凑到 2/3 属于极端抽样偏差、样本量 128 足够大使这种偏差概率可忽略(p.102)。

11. 以太坊的最终性要多久?和比特币"等六个确认"有什么本质不同?

网络健康且投票条件满足时,课程估算约 2 个 epoch、约 13 分钟;不是每笔交易的固定等待上限。性质上是经济最终性——要推翻一个已 finalize 的区块,攻击者必须让至少 1/3 的质押被罚没销毁;而”六个确认”只是概率保证,PoW 里没有任何高度是真正不可逆的(p.122)。

下一讲

下一讲把这台机器上真正跑的东西拆开:合约怎么写、代币标准长什么样、私钥又是怎么从一串助记词里长出来的。带着”这一讲的账户和地址,到了钱包那层是怎么被批量生成的”这个问题去听。

下一讲 →
L03 L03 Smart Contract and Wallet:一台不能退货的自动售货机

个人整理的学习笔记,不是官方材料;数字与结论以课件和讲师为准。