从0到深入理解以太坊 · 第二篇 / 第二章 / 第二课

一枚区块两个世界

现代以太坊的区块,不只是一只“装交易的盒子”。它同时横跨共识层与执行层, 把交易顺序、执行结果、时间位置与上一段历史,压缩成一组人人都能重新核验的承诺。

  • 02 · 02第二章 · 第二课
  • ≈ 60 MIN建议学习时间
  • 10 VISUALS含三组互动实验

Block specimenNot to scale

01 / CONSENSUS LAYER Signed Beacon Block
slotparent_rootstate_rootsignature
└─ body
02 / EXECUTION CORE Execution Payload
parent_hashtimestampstate_rootgas
03 / ORDERED DATA tx₀ · tx₁ · tx₂ · …
外层决定顺序与最终性,内层重放交易并承诺执行结果

先记住这一句

区块不是一袋交易,而是被共识选中的有序状态转换, 加上对父区块、交易、执行结果和共识状态的一组密码学承诺。
展开本课目录
  1. 01 · 为什么需要区块
  2. 02 · 一枚区块的两层
  3. 03 · 执行区块头
  4. 04 · 时间戳与 slot
  5. 05 · 交易数据
  6. 06 · 三个关键根
  7. 07 · 区块哈希
  8. 08 · 节点怎样验证
  9. 09 · 结构如何演化
  10. 10 · 误解与收束
  11. 11 · 理解检查
  12. 12 · 术语与资料
01 / WHY BLOCKS EXIST

网络为什么不直接逐笔确认交易?

因为“有人广播了一笔交易”与“全网同意这笔交易排在历史的哪里”,是两件完全不同的事。

钱包签名后,交易会在点对点网络中传播。不同节点收到交易的时间、顺序和集合都可能不同; 因此每个节点眼里的交易池,只是候选请求,不是已经确定的公共历史。

假设 Alice 的账户只有 5 ETH,她几乎同时广播“给 Bob 5 ETH”和“给 Carol 5 ETH”。 两笔签名都可能是真的,但它们不可能都成功。节点必须先同意执行顺序,才能得到唯一结果。 区块的第一项工作,就是把一批候选交易变成严格有序的序列

区块的第二项工作,是给状态转换划出清晰边界。节点从同一个旧状态出发, 按区块内顺序重放交易和协议级操作,得到新状态,再把关键结果写成根哈希。 这使别人无需相信打包者的口头保证:任何执行节点都能自己复算。

Sₙ + [ tx₀, tx₁, …, txₖ ] + 协议操作 Sₙ₊₁ 旧状态 + 严格有序的输入,经协议规则执行,得到下一个状态。
Candidate requests

交易池

各节点看到的候选集合可能不完全相同,也没有全网唯一顺序。

Fixed proposed order

区块批次

被提议的交易按索引固定顺序;位置也是被承诺的数据。

State boundary

可验证的新状态

所有执行节点按同一规则重放,比较状态根、收据根与 Gas 等结果。

图 01 · 区块把“请求”变成“历史候选” 进入区块仍不等于立刻最终确定。该区块还要通过有效性验证、分叉选择与最终性过程。
02 / TWO LAYERS, ONE ETHEREUM

现代以太坊的一枚区块,为什么有两层?

合并之后,共识客户端与执行客户端分工协作。理解区块结构,必须先把外层与内层分开。

日常说“以太坊区块”时,人们可能指信标区块,也可能指区块浏览器展示的 执行区块。它们不是两条互不相干的链,而是同一个以太坊的两个协议视角。

共识层回答:“这是哪个 slot、谁提议、接在哪个父信标块后、验证者认可哪条分支?” 执行层回答:“这些交易按什么顺序执行、消耗多少 Gas、最终账户和合约状态是什么?” 信标块的 body 中携带 execution_payload,把两者扣在一起。

Outer / Consensus layer

信标块

使用 SSZ 编码并通过 hash_tree_root 进行 Merkleization;由提议者签名,承载共识操作和执行载荷。

  • slot协议时间位置
  • proposer_index本 slot 的提议验证者
  • parent_root父信标块根
  • state_root共识状态根
  • body证明、签名、执行载荷、blob 承诺等
Inner / Execution layer

执行载荷

映射为执行区块;包含头部字段、完整有序交易、提款等执行数据。

  • parent_hash父执行区块哈希
  • timestamp由 slot 推导的 Unix 时间
  • transactions完整、签名、严格有序的交易
  • state_rootEVM 世界状态根
  • receipts_root执行收据根
同名 ≠ 同义
信标块 state_root 验证者、余额、证明、最终性检查点等共识状态的承诺。
执行区块 state_root 账户、ETH 余额、合约代码和合约存储等 EVM 状态的承诺。
图 02 · 两套结构,两种责任 信标块用 parent_root 连接共识历史;执行区块用 parent_hash 连接执行历史。本课下文说“区块头”时,除非特别注明,主要指执行层 RLP 区块头。

信标块头与完整信标块也要分开

用于轻量承诺的 BeaconBlockHeader 只有 slotproposer_indexparent_rootstate_rootbody_root。 完整 BeaconBlock 则直接携带 bodySignedBeaconBlock 再在消息外包一层提议者 BLS 签名。

通常所说的信标块根,是对区块消息计算 SSZ hash_tree_root; 外层签名不是这个根的一部分。与之相对,当前执行区块哈希来自对执行头 RLP 编码后的 Keccak-256。

04 / SLOT ≠ BLOCK NUMBER ≠ TIME

时间戳不是验证者随手写的“大概时间”

权益证明以太坊先有 12 秒一格的 slot,再从 slot 推导执行载荷时间戳;slot 允许为空。

共识层的信标块顶层没有 timestamp,而有 slot。 执行载荷中的时间戳必须与该 slot 对应的协议时间一致。

timestamp = genesis_time + slot × 12 秒 主网 GENESIS_SLOT 为 0;公式展示核心关系。验证者不能在允许范围内任意挑一个时间。

每 12 秒会进入一个新 slot,但某个 slot 的提议者可能离线、网络传播不及时,或区块未被接受, 因而该 slot 可以没有区块。下一次实际出块时,slot 和 timestamp 会跨过空位, 但执行区块号只比上一个实际区块增加 1。

slot / 时间戳 / 区块号实验

切换漏块情形,观察三个计数怎样各自前进。

Interactive 02
SLOT 800执行块
#21,000,000
SLOT 801执行块
#21,000,001
SLOT 802执行块
#21,000,002
SLOT 803执行块
#21,000,003
SLOT 804执行块
#21,000,004
相邻实际执行块的时间差12 秒
相邻实际执行块的高度差始终为 +1
图 04 · “每 12 秒一个 slot”不等于“保证每 12 秒一个区块” 区块号描述已经出现的执行区块次序;slot 描述共识协议中的时间位置;timestamp 是该 slot 对应的 Unix 时间。
05 / WHAT TRANSACTION DATA MEANS

区块里保存的不是“交易截图”,而是签名后的字节序列

区块浏览器展示的是便于人阅读的接口视图;真正进入执行区块的是可确定解析、可验证签名的序列化交易。

一笔交易通常表达:谁授权、要调用谁、转移多少价值、携带什么数据、最多使用多少 Gas、 愿意支付什么费用。具体字段取决于交易类型,但它们最终都必须变成确定的字节。

当前常见交易类型包括:类型 0 的 legacy 交易、类型 1 的 access-list 交易、类型 2 的 EIP-1559 交易、 类型 3 的 blob 交易,以及类型 4 的 EIP-7702 set-code 交易。 EIP-2718 给出的统一外壳心智模型是:

TransactionType || TransactionPayload 一个类型字节,加上该类型定义的载荷。类型 0 的旧式交易保留原有 RLP 形式。

同一笔交易的四个视图

浏览器 JSON、链上字节和人的意图不是同一层;切换视图看清哪些字段是派生结果。

Transaction microscope

“用 1 ETH 调用某个合约”

这是用户层意图。钱包会把网络、账户 nonce、Gas 与费用参数、目标地址、value、calldata 等组织起来,再请求私钥签名。

IntentAlice → Contract X · value 1 ETH · call deposit()

JSON-RPC / 区块浏览器视图

接口会把二进制数据转成字段,并可能补充方便查询的派生值。from 和交易哈希很重要,但并不是类型 2 交易载荷里普通排列的独立字段。

{ "type": "0x2", "hash": "0xa91e…d240", "from": "0xAlice…", "to": "0xContractX…", "value": "0x0de0b6b3a7640000", "input": "0xd0e30db0", "nonce": "0x17", "maxFeePerGas": "0x…", "yParity": "0x1", "r": "0x…", "s": "0x…" }

类型化、签名后的序列化字节

节点承诺和传播的是规范编码,不是带缩进的 JSON。类型 2 交易以类型字节 0x02 开头,其后是该类型定义的 RLP 载荷。

0x02 || rlp([ chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list, signature_y_parity, signature_r, signature_s ])

完整 blob 不在 execution payload 里

类型 3 交易在执行载荷中承诺 blob versioned hashes;信标块携带 KZG commitments。Fusaka 后,实际 blob 数据通过 PeerDAS data-column sidecars 传播与抽样。

Execution payload类型 3 交易 + blobVersionedHashes
Data-column sidecars实际数据列 + KZG 证明,经独立旁路传播
图 05 · 同一交易,四种表达层 RPC 可以只返回交易哈希,也可以展开完整对象;这是查询接口的选择,不代表区块体只保存了哈希。

顺序为什么也是数据?

执行区块的交易列表有严格顺序。节点用交易在区块中的索引作为键的一部分, 构造交易 Merkle-Patricia Trie;因此即使两笔交易内容完全不变,只要交换位置, transactions_root 就会改变。

顺序也影响语义。两笔调用可能竞争同一余额、同一 nonce、同一市场价格或同一 NFT。 交易根承诺“有哪些输入以及以什么顺序输入”;EVM 再按这个顺序计算结果。

06 / INPUT, OUTCOME, STATE

三个根哈希,分别承诺输入、结果与新世界

它们都长得像 32 字节十六进制字符串,却回答三个不同问题。

INPUT

transactionsRoot

承诺完整、有序的交易序列。换一笔、改一字节或调换顺序,根都会改变。

OUTCOME

receiptsRoot

承诺执行状态、累计 Gas、日志 Bloom 与事件日志等交易收据结果。

WORLD

stateRoot

承诺全部账户、余额、nonce、代码与合约存储组成的执行后世界状态。

节点收到区块后,不只是检查“交易根看起来像哈希”。它会按照规范重建交易 trie, 重放每笔交易,生成收据并更新状态,然后将自己算出的三个根与头部字段逐一比较。 任意一个不相等,区块就无效。

transactionsRoot0x8b31…e907
branch Ahash(node 00 + 01)
branch Bhash(node 02 + 03)
rlp(0) → tx₀Alice → Bob
rlp(1) → tx₁Carol → Contract
rlp(2) → tx₂Dave → Erin
rlp(3) → tx₃Frank → DAO
图 06 · 教学简化的交易承诺路径 真实执行层使用 Merkle-Patricia Trie,而不是这棵整齐的二叉树。关键关系不变:叶子或索引变化会向上传播,最终改变根。

logsBloom 为什么不是第四个“精确根”?

logs_bloom 是 2048 位的快速筛选器,用来判断某个地址或事件主题“可能出现”。 它可以出现假阳性,所以只能帮助缩小搜索范围;要确认真实日志,仍需查看并验证交易收据。 receipts_root 才是对完整收据集合的密码学承诺。

根哈希不是把原文加密

哈希不会隐藏交易内容。公开节点仍能读取交易字节;根哈希的作用是提供紧凑的内容承诺, 让任何差异都极易被发现,并允许构造成员证明。隐私与承诺是两个不同问题。

07 / THE FINGERPRINT CHAIN

区块哈希怎样把一次改动传到后面的历史?

当前执行区块哈希是整个 RLP 区块头的 Keccak-256 指纹;下一块再把它写进 parent_hash。

execution_block_hash = Keccak-256( RLP( execution_header ) ) 这是截至 2026-07 当前主网执行层规则;未来协议升级仍可能改变编码方式。

改动一笔交易,至少会改变 transactions_root;重新执行通常还会改变 receipts_rootstate_rootgas_used 与日志。 头部一变,区块哈希就变;下一块记录的旧 parent_hash 随即失配。

篡改传播实验

修改第一笔交易的金额或交换顺序,看“交易 → 根 → 区块哈希 → 下一块父哈希”如何逐层变化。

Interactive 03
Ordered transactions tx₀: A→B 2 ETH
tx₁: C→D 1 ETH
transactionsRoot 0x4f21…7b8c
blockHash 0xa903…12ef
next.parentHash 0xa903…12ef

教学指纹:当前显示值是便于观察传播关系的确定性缩写,不是真实 Keccak-256 计算器。

图 07 · 改动传播链 即使两种顺序偶然得到相同最终余额,交易根仍会因为输入序列不同而变化。

“哈希一变”为什么还不等于“历史绝对不可改”?

攻击者当然可以修改旧交易、重算该区块以及所有后继区块的哈希。 真正的困难在于:诚实节点已经保存原历史,共识规则决定哪条分支是规范链, 验证者投票与经济惩罚提高重写成本,最终性再让已确认检查点难以回滚。

因此要把四层判断分开:哈希自洽只说明内容与指纹匹配; 区块有效说明它符合协议并能正确执行; 当前规范说明分叉选择暂时选择了它; 最终确定才表示正常协议条件下不会再被另一条分支替换。

08 / VERIFY, DO NOT TRUST

节点收到一枚区块后,究竟重新检查什么?

现代以太坊不是“看到签名就收下”,而是共识客户端和执行客户端各自完成一整套本地验证。

打包者提供的是候选答案。节点要把区块结构、父关系、交易签名、执行过程和根哈希全部重新核对, 任一关键承诺不一致,整块都会被判无效。

收到信标块与 sidecars解析签名区块、共识操作和所需数据列。
检查共识外壳核对 slot、提议者、BLS 签名、parent_root 与共识状态转换。
交给执行客户端传入 execution payload、父信标根、blob 哈希与执行请求。
检查头部约束父哈希、区块号、时间戳、Gas、基础费和 PoS 固定字段。
检查每笔交易规范编码、签名、chain ID、nonce、余额和费用上限。
按顺序重放执行运行 EVM,处理系统调用、提款和请求,累计 Gas 与日志。
重算全部承诺交易根、收据根、状态根、Bloom、提款根、请求哈希和区块哈希。
进入共识判断本地有效后,分叉选择决定 head,最终性过程决定何时稳定。
图 08 · 验证不是下载后“相信一遍” 不同客户端实现同一规范,应当对相同输入得出相同结果。这是多客户端网络能够互相校验的基础。
LEVEL 01

有效 Valid

结构、签名、执行和所有承诺符合协议。可能同时存在多个有效分支。

LEVEL 02

规范 Canonical

分叉选择当前把该分支视为链头;靠近头部的区块仍可能短暂重组。

LEVEL 03

最终 Finalized

检查点获得足够权益证明支持;正常协议条件下不会回滚。

09 / A LIVING DATA STRUCTURE

区块结构不是石刻,而是一份会升级的协议

今天的 21 字段不是创世时就全部存在。每次升级都在为新的验证责任增加承诺或重定义旧字段。

  1. 基础费 加入 base_fee_per_gas,让费用市场按区块拥堵自动调整。
  2. 转向 PoS difficulty 与 nonce 固定;ommers 为空;mixHash 变为 prev_randao。
  3. 验证者提款 区块体加入 withdrawals,头部加入 withdrawals_root。
  4. Blob 与跨层根 加入 blob gas 字段与 parent_beacon_block_root。
  5. 执行请求 加入 requests_hash;共识 body 承载 execution_requests。
  6. PeerDAS 改变 blob 数据传播与抽样,当前执行头仍为 21 字段。
图 09 · 字段是协议历史的年轮 截至 2026-07,Glamsterdam 仍是计划中的后续升级;尚未上线的 block access list 字段不属于当前主网头部。

为什么课程不能只背一个字段清单?

因为字段会随着硬分叉演化,名称也会因为兼容性保留历史痕迹。 更稳固的理解方式是按责任分类:连接历史、承诺内容、承诺执行结果、约束资源、连接两层、保留兼容。 即使未来增加字段,你也能先问它属于哪种责任。

执行层 RLP 与共识层 SSZ 为什么同时存在?

以太坊执行层继承了早期的 RLP 与 Merkle-Patricia Trie 体系; 信标链从设计之初采用 SSZ 与 SSZ Merkleization。两者通过 Engine API 与执行载荷交界。 这也是为什么“哈希”不能只背一句统一公式:对象、编码和哈希树规则不同,根的含义就不同。

10 / THE COMPLETE MENTAL MODEL

先拆掉六个误解,再把全课压回一张图

真正理解结构,不是会背字段,而是能阻止自己在相似概念之间滑动。

误解 01

“区块头里直接放着所有交易”

错。执行区块体保存完整交易;头部用 transactions_root 承诺交易及顺序。

误解 02

“blockHash 是头部里的一个字段”

错。当前执行区块哈希是对 RLP 头部计算出的结果,不能作为自身输入。

误解 03

“以太坊严格每 12 秒出一个块”

错。每 12 秒进入一个 slot;slot 可空,实际区块之间可能相隔 24 秒或更久。

误解 04

“timestamp 由验证者大概填写”

错。PoS 执行载荷时间戳由 genesis_time 和当前 slot 精确推导。

误解 05

“stateRoot 只有一种含义”

错。信标块承诺共识状态;执行头承诺 EVM 世界状态,二者不是同一棵树。

误解 06

“哈希正确就等于最终确定”

错。还要分别通过有效性验证、分叉选择与最终性过程。

BATCH
区块固定一组输入和它们的严格顺序。交易池只是候选集合;被排序后才能产生唯一执行结果。
OUTER
信标块提供共识外壳。slot、提议者、父根、共识状态和签名回答“网络认哪一段历史”。
INNER
execution payload 提供执行内核。有序交易、提款与头部上下文回答“状态怎样改变”。
ROOTS
交易根、收据根与状态根分别承诺输入、结果和新世界。节点重建结构并重放交易,而不是信任打包者。
LINK
区块哈希与父哈希把执行历史首尾相接。旧内容一变,指纹差异会沿后继 parent_hash 暴露。
FINAL
密码学承诺负责暴露差异,共识负责选择并最终确定历史。有效、规范与最终是三种不同状态。
11 / CHECK YOUR MODEL

现在检查你的理解

每题都针对一个常见概念滑移。先作答,再看解释。

1. 两笔内容完全不变的交易交换区块内顺序,最确定会改变什么?

答案 B。交易 trie 以区块内索引组织交易;交换位置会改变键值对应关系。执行结果也可能随顺序变化。

2. 中间漏了一个 12 秒 slot,下一枚实际执行区块与上一枚相比会怎样?

答案 C。slot 时间位置继续前进;没有实际区块就不会消耗执行区块号。

3. 下列哪句话最准确地描述 blockHash?

答案 A。区块哈希标识并承诺执行头;它不在 RLP 头部自身字段中,也不证明链外事实为真。

4. 信标块 state_root 与执行头 state_root 的关系是什么?

答案 C。它们属于不同层、不同状态对象和不同承诺结构。

5. 一个区块的所有根和哈希都内部自洽,能否直接断定它已经最终确定?

答案 B。哈希自洽只是必要条件之一;有效、规范、最终必须分层判断。

12 / TERMS & PRIMARY SOURCES

术语与一手资料

协议会升级,最可靠的学习习惯是保留清晰心智模型,并回到当前规范核对字段与边界。

区块体 BLOCK BODY

执行层中承载完整有序交易、提款以及固定为空的 ommers 列表;共识层 BeaconBlockBody 则还承载证明、惩罚、执行载荷、blob 承诺和执行请求等。

区块头 BLOCK HEADER

对父历史、内容、执行结果、资源与协议上下文的紧凑摘要。执行层 RLP 头与信标块头不是同一对象。

根哈希 ROOT COMMITMENT

对一整套结构化数据的紧凑密码学承诺。改变底层数据或位置,重新计算的根通常完全不同。

Slot CONSENSUS TIME UNIT

权益证明共识的离散时间位置。主网当前每个 slot 为 12 秒;slot 可以没有区块。

RLP RECURSIVE-LENGTH PREFIX

执行层广泛使用的确定性字节编码方式。当前执行区块哈希对 RLP 编码后的执行头取 Keccak-256。

SSZ SIMPLE SERIALIZE

共识层使用的序列化与 Merkleization 体系。信标区块根通过 SSZ hash_tree_root 计算。

继续阅读

  1. ethereum.org — Blocks区块为什么批处理交易、slot、空 slot,以及信标块和执行载荷的入门结构。
  2. Ethereum Execution Specs — BPO2 Block and Header截至本课日期的当前执行区块体与 21 字段头部规范。
  3. Ethereum Consensus Specs — Fulu Beacon Chain当前共识结构、execution payload、slot 时间和验证条件。
  4. ethereum.org — Recursive-length prefix serialization执行层 RLP 编码规则与确定性表示。
  5. ethereum.org — Simple Serialize共识层 SSZ 编码与 hash_tree_root
  6. ethereum.org — Merkle Patricia Trie执行层状态根、交易根与收据根所依赖的数据结构。
  7. EIP-2718 — Typed Transaction Envelope类型化交易外壳,以及交易与收据进入 trie 的规则。
  8. EIP-3675 — Upgrade consensus to Proof-of-StakePoS 后 ommers、difficulty、nonce 与执行层奖励语义的变化。
  9. EIP-4399 — PREVRANDAO旧 mixHash 字段如何在 PoS 后承载信标链随机性。
  10. EIP-4895 — Beacon chain push withdrawals提款列表与 withdrawals_root。
  11. EIP-4844 — Shard Blob Transactionsblob gas 头部字段、versioned hashes 与 sidecar 边界。
  12. EIP-4788 — Beacon block root in the EVMparent_beacon_block_root 如何进入执行头。
  13. EIP-7685 — General purpose execution layer requestsrequests_hash 的加入与执行请求承诺。
  14. ethereum.org — Fusaka当前升级的 PeerDAS、数据可用性与执行区块大小边界。