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”或者”私钥被销毁了” → 两类账户的数据结构完全相同,区别只在合约账户的后两格真的指向了东西(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):
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.
常见误解
以为销毁只为通缩 → 它还移除了提议者直接收取 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):
判断口诀是看两次证明的 [source, target] 区间,一个严格包含另一个就是 surround。
常见误解
需要提交可验证的违规证据,协议验证后罚没并强制退出。处罚包括初始罚金、退出等待期间的处罚及相关性罚金;许多验证者一同被罚时,损失可更大。补充:课件跨越多个协议版本,奖励分母、余额上限等不能混用;罚没不是只针对持续作恶,一次可证明的违规也可触发(p.112–116)。
把它们串起来
这一讲一次讲完了”以太坊是什么”的四大块,抓两条线就不会散。数据线:账户 → 账户状态四字段 → 状态树 → stateRoot → 区块头。每一环都在做同一件事——把庞大的数据换成一个定长哈希塞进上一层,所以区块本身不装账户数据,只装那个根。上一讲的 Merkle 证明在这里直接兑现成了轻节点的工作方式。
经济线:交易消耗 gas → 用户付费 → 底价销毁、小费给验证者。供应量变化还要合并计算协议发行量,不能从“有销毁”直接推出“必定通缩”。
两条线在共识处合上:提议者组织区块,其他节点按协议校验。课件合并后的简图省略旧 PoW 字段,不代表真实数据结构把所有旧字段都删除了。
课件里的坑
-
[补充核验] p.57 的 20,000 gas 例子不能用于解释执行耗尽:它低于普通转账的 intrinsic gas,不能执行入块。REVERT 与耗尽 gas 也不同。依据:EIP-1559、Geth 检查、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。三步做完再往下看答案。
必背
- EOA 地址生成四步:ECDSA 生成私钥 sk → 推出公钥 pk → keccak256(pk) → 取这 64 个十六进制字符里的最后 40 个(160 bit)。
- CREATE 由部署者和 nonce 决定地址;CREATE2 由部署者、salt、init_code 哈希决定地址;两者均可预计算,后者不依赖部署者 nonce。
- 账户状态四字段 Nonce / Balance / storageRoot / codeHash,后两个存的是哈希不是数据;本讲无代码委托的普通 EOA,其 codeHash 是空字符串的 keccak256,不是全零。
- 本讲普通交易模型中 EOA 发起交易;to 留空表示创建合约;标准 ABI 调用的 Data 是函数选择器加编码参数,函数签名不等于数字签名。
- 总费用 = gas used ×(base fee + 实付 priority fee);普通 ETH 转账消耗 21,000 gas;base fee 销毁,小费归验证者;max fee per gas 是封顶,课件区块目标 15M、上限 30M 是示例参数。
- 先区分无效交易、执行耗尽 gas 与 REVERT;低于 intrinsic gas 的交易不执行入块,执行失败仍按规则付 gas,REVERT 不必耗尽剩余 gas。
- 1 slot = 12 秒,1 epoch = 32 slots = 6.4 分钟;最终性 = 2 epochs ≈ 13 分钟;成为验证者要押 32 ETH。
- 三种可罚没行为: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。
- 套公式:总费用 = 消耗的 gas 单位数 ×(base fee + priority fee)。
- 每单位 gas 的实付单价 = 100 + 10 = 110 gwei。
- 总手续费 = 21,000 × 110 = 2,310,000 gwei。
- 换回 ETH:gwei 除以 10⁹,得 0.00231 ETH。这步是最常见的失分点,别停在 gwei 上。
- Jordan 账户共扣 1 + 0.00231 = 1.00231 ETH(本金加手续费)。
- Taylor 收到 1.0000 ETH,收款方不承担手续费。
- 拆手续费的去向。给验证者的小费 = 21,000 × 10 gwei = 210,000 gwei = 0.00021 ETH。
- 被销毁的底价 = 21,000 × 100 gwei = 2,100,000 gwei = 0.0021 ETH,退出流通。
- 回验: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;核对两份之和;说明比例变化原因。以下中文演算用于核对。
- 实付单价 = 25 + 5 = 30 gwei;总手续费 = 21,000 × 30 = 630,000 gwei = 0.00063 ETH。
- 销毁 = 21,000 × 25 = 525,000 gwei = 0.000525 ETH;小费 = 21,000 × 5 = 105,000 gwei = 0.000105 ETH。相加 630,000 ✓。
- Morgan 共扣 2.00063 ETH,Riley 收到整 2 ETH。
- 销毁占比 = 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(偶)加叶子 → 2;7 是 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)。
下一讲
下一讲把这台机器上真正跑的东西拆开:合约怎么写、代币标准长什么样、私钥又是怎么从一串助记词里长出来的。带着”这一讲的账户和地址,到了钱包那层是怎么被批量生成的”这个问题去听。
个人整理的学习笔记,不是官方材料;数字与结论以课件和讲师为准。