00 · Orientation
先不要背字段。先分清四层对象
钱包、原始交易、收据和区块浏览器展示的并不是同一份数据。
第六章第二课 · 主线讨论以太坊执行层交易字段
以太坊交易是由外部账户发起、带有密码学授权、希望改变网络状态的指令。 你在钱包里看到的是人类界面;节点接收的是规范编码后的已签名字节。 交易被执行以后,网络才会产生收据,并把它放进某个区块上下文。[1]
应用意图
“给 Alice 0.1 ETH”
“用 25 USDC 交换代币”
钱包请求对象
from / to / value / data / gas…
已签名交易
type || encoded payload
收据与区块
status / gasUsed / logs / block…
本课所说的“交易字段”,首先指被编码进原始交易并受签名保护的字段;
from、交易哈希、执行状态、实际 Gas、区块高度等虽然常与交易一起显示,
但它们的来源并不相同。
同一个浏览器页面,可能混合四种来源
交易本体
nonce、to、value、data、Gas 与费用上限、类型扩展字段、签名。
节点派生
from 由签名恢复;hash 由规范已签名交易编码计算。二者都不是签名交易本体里单独写入的字段。
执行收据
status、gasUsed、logs 和合约创建地址要等执行之后才知道。
区块上下文
blockNumber、transactionIndex、区块时间和当块 baseFee 由入块位置决定。
01 · Anatomy
把一笔交易放上解剖台
先看最常见的 Type 2,再切换四种真实用途,观察哪些字段会改变。
下面默认展示一笔 EIP-1559 Type 2 代币调用。点击任一字段,会看到它由谁提供、 节点如何解释、常见误区是什么。所有地址和数值都是固定教学数据,不连接钱包,也不会广播。
- 0x02
- 1 · Ethereum mainnet
- 42
- 1.5 gwei
- 35 gwei
- 65,000 gas
- 0x2222…2222 · token contract
- 0 wei
- 0xa9059cbb…017d7840
- []
- —
- yParity · r · s
from
钱包请求对象需要它来选择签名账户;节点则从签名恢复发送者,不把 from 再编码一遍。
transactionHash
签完以后,对完整已签名字节做 Keccak-256 得到;所以签名前还没有最终交易哈希。
status / gasUsed
只有执行过才知道,属于收据;钱包可以模拟估计,但估计值不是最终事实。
02 · Order
nonce:账户顺序号为什么不能跳?
它是发送账户的顺序闸门,不是时间戳,也不是全网流水号。
对普通 EOA 交易,账户状态里保存“下一笔应使用的 nonce”。如果当前值是 42, 节点只会把 nonce 42 当作下一笔可执行交易;nonce 43 即使先到,也要等待缺口补上。 同一发送账户、同一 nonce 最终只能执行一笔。[2]
nonce 42 与账户下一值一致。交易若通过其他有效性检查,就可以进入执行;纳入后账户 nonce 前进到 43。
防止重复执行
旧的已签交易再次广播时,发送账户 nonce 已前进,节点不会把它当作一笔新授权再执行。
约束账户内顺序
nonce 不是全网顺序;不同账户都可以同时有 nonce 42。它只排列同一发送账户的交易。
允许候选替换
用户可用同一 nonce 广播另一个候选,钱包常称“加速”或“取消”;是否接受替换属于交易池策略。
回滚也会消耗
交易若已上链但 EVM 执行 revert,状态操作回滚,发送者 nonce 与已花 Gas 不回滚。
四种同名 nonce,职责完全不同
| 名称 | 存在位置 | 作用 | 本课关系 |
|---|---|---|---|
| 交易 nonce | 发送账户状态 + 交易字段 | 账户内排序、防止同一授权重复执行 | 本节主角 |
ECDSA 临时值 k |
签名器内部 | 生成安全签名,绝不能复用或泄露 | 不是交易字段 |
| 区块 nonce | 历史执行层区块头 | PoW 时代挖矿字段;PoS 后不再承担挖矿搜索 | 不是账户顺序 |
| 授权 nonce | Permit、EIP-7702 等授权结构 | 约束另一份授权的重放 | 可能嵌套在扩展字段里 |
03 · Action
to 与 value:先到哪里,带多少 ETH
顶层目的地不一定是资产最终受益人;value 也永远不是代币数量。
to = 无代码账户没有代码可执行;value 按余额转移to = 有代码账户执行合约或 EIP-7702 委托代码;可同时发送 ETHto = 空顶层合约创建;data 是 initcode
to 是顶层执行首先抵达的 20 字节地址,或在合约创建时为空;
value 是随这次顶层执行发送的原生 ETH 数量,以 wei 计。
零地址是一个真实的 20 字节地址,不等于“空 to”。
| 用户意图 | to |
value |
data |
|---|---|---|---|
| 给 Bob 0.1 ETH | Bob 的地址 | 10¹⁷ wei |
0x |
| 给 Bob 25 枚 ERC-20 | 代币合约地址 | 0 wei |
Bob 地址与 25 枚的原始单位 |
| 向质押合约存入 32 ETH | 存款合约地址 | 32 × 10¹⁸ wei |
验证者公钥等参数 |
| 部署新合约 | 空字节串 / RPC null | 可为 0,也可随部署发送 ETH | initcode + 构造参数 |
04 · Payload
calldata:让合约做什么
协议只看到字节;“转账”“授权”“交换”是 ABI、合约代码与界面共同给出的解释。
交易格式把这段字节称为 data;JSON-RPC 常称 input;
当它进入合约的顶层消息调用时,EVM 把它暴露为 calldata。三种名字经常指向同一段原始字节,
但所处语境不同。
ABI microscope
拆解 transfer(address,uint256)
FUNCTION SELECTOR
0xa9059cbb
按常见 ERC-20 ABI,它是 keccak256("transfer(address,uint256)")
的前 4 字节。协议本身不保证这四字节一定代表该函数;仍需结合目标合约代码与 ABI。
data = 0x
最简单 ETH 转账通常没有额外数据;意图主要由 to 与 value 表达。
selector + 参数槽
Solidity ABI 通常以 4 字节函数选择器开头,再用 32 字节槽位编码参数。动态类型还会用偏移量。
initcode + 构造参数
空 to 时,这段字节会作为初始化代码执行;其返回值才成为合约的运行时代码。
只是不透明字节
ABI 是生态约定,不是交易层强制语义;任意合约都可以按自己的方式解释输入。
05 · Resource bound
gasLimit:允许这次执行最多做多少工作
它是 Gas 单位上限,不是费用金额,也不是预测出来的最终 gasUsed。
实际消耗由执行路径决定,写进收据
未用余量只是上限空间,不会被当作已消耗 Gas 收费
gasUsed ≤ gasLimit
若执行需要超过上限,会 Out of Gas;顶层状态变更回滚,但已消耗 Gas 与 nonce 不退回。Gas 是工作量单位
每条 EVM 操作、calldata 字节、状态访问等有协议规定的成本;Gas 不是 ETH,也没有市场价格本身。
上限保护发送者与网络
它给单次执行设硬边界;过低会 Out of Gas,过高不等于一定花完,只会提高最大资金预留。
估算不是承诺
eth_estimateGas 在某个状态上模拟。状态、分支或并发条件变化,实际路径可能不同。
gas 常指 gasLimit
JSON-RPC 交易对象里常写 gas;区块浏览器界面常写 Gas Limit。不要与 gasUsed 混淆。
06 · Price caps
费用字段:给每单位 Gas 设价格边界
Type 2 写的是两个上限;当块 base fee 和执行后的实际费用并不是预先签下的常数。
maxFeePerGas
每单位 Gas 愿意支付的总价格上限,包含 base fee 与 priority fee。
baseFeePerGas
由区块规则决定,不是 Type 2 交易字段;若高于 max fee,这笔交易当下不能被纳入。
maxPriorityFeePerGas
愿意给区块提议者的每 Gas 小费上限;实际小费还受 max fee 剩余空间约束。
Type 2 effective price
effectiveGasPrice = min(maxFeePerGas, baseFeePerGas + maxPriorityFeePerGas)
actual execution fee = gasUsed × effectiveGasPrice
At this block
max fee 覆盖当前 base fee,这笔交易在费用条件上具备入块资格。
| 值 | 何时确定 | 属于哪里 |
|---|---|---|
gasLimit | 签名前 | 交易字段 · Gas 单位上限 |
maxFeePerGas | 签名前 | Type 2/3/4 交易字段 · 总单价上限 |
baseFeePerGas | 由入块区块确定 | 区块字段 · 不是交易字段 |
gasUsed | 执行后 | RPC 收据上下文 · 实际 Gas |
effectiveGasPrice | 入块并执行后 | RPC 收据字段 · 实际每 Gas 价格 |
07 · Domain & proof
chainId、签名摘要、发送者与交易哈希
四个经常被叫作“hash”的东西,必须按生成顺序分开。
签名不是只盖在金额上,而是覆盖该类型规定的整组未签名字段。
改动 nonce、to、data 或费用上限中的任意一项,
签名摘要都会改变,原签名不再对应。
type · chainId · nonce
fees · to · value · data…
类型字节 + 规范字段顺序
Keccak-256 · 32 bytes
yParity · r · s
可广播的完整字节
from
Type 2 · 精确签名对象
keccak256(0x02 || rlp([chainId, nonce, maxPriorityFeePerGas, maxFeePerGas, gasLimit, to, value, data, accessList]))
yParity / r / s 不在自己的签名摘要里;它们随后被加入完整 payload。[6]
“我要签什么”
由类型域、chainId 和未签名字段计算。签名器用它生成证明。
keccak(type || unsigned payload)
“这份签名交易是谁”
由完整已签名字节计算,包含签名。它在入块前就能确定。
keccak(type || signed payload)
chainId 到底保护什么?
chainId 把签名绑定到一条链的域,避免同一份签名交易被直接搬到另一条使用相同账户规则的链上重放。
Type 1–4 把它作为显式字段;Legacy 交易由 EIP-155 把 chainId 纳入签名前像,并编码进 v。
chainId 不是节点互联时使用的 network id。
chainId视类型Type 1–4 显式编码;Legacy 没有独立 chainId 字段,EIP-155 把它纳入签名前像并反映在 vyParity / r / sTyped 是Type 1–4 使用 yParity / r / s;Legacy 编码 v / r / sfrom否节点从摘要与签名恢复hash否完整已签名编码的 Keccak-25608 · Typed envelopes
Type 0–4:不是五种业务,而是五套信封
“转 ETH / 调合约 / 部署合约”描述动作;Type 描述字段格式。两条分类轴不要混在一起。
EIP-2718 定义了 TransactionType || TransactionPayload 的类型化信封。
新功能可以新增类型字节与字段列表,而不必继续挤进 Legacy 的 v。
截至 2026 年 7 月,以太坊主网现行协议交易是 Legacy 加 Type 1–4。[8][12]
LONDON · DEFAULT GENERAL-PURPOSE
Type 2 · EIP-1559 dynamic fee
把单一 gasPrice 拆成总价上限和小费上限,是普通钱包交易的主流格式。
0x02 || RLP([chainId, nonce, maxPriorityFeePerGas, maxFeePerGas, gasLimit, to, value, data, accessList, yParity, r, s])
- 可转 ETH、调用合约或创建合约
- accessList 可以为空
- baseFee 不是交易字段
| 类型 | 主要目的 | 费用字段 | 新增 / 特有字段 | 可否空 to 创建 |
|---|---|---|---|---|
| Legacy / RPC 0 | 原始格式 | gasPrice | wire 无显式 0x00 类型前缀 | 可以 |
| Type 1 | 预声明访问地址与存储槽 | gasPrice | chainId, accessList | 可以 |
| Type 2 | 动态费用通用交易 | maxPriorityFee + maxFee | 沿用 accessList | 可以 |
| Type 3 | 为 Rollup 发布 Blob 数据 | Type 2 + Blob 费上限 | maxFeePerBlobGas, blobVersionedHashes | 不可以 |
| Type 4 | 让 EOA 设置代码委托 | Type 2 费用字段 | authorizationList | 不可以 |
TYPE 3 · BLOB
交易签的是承诺哈希,不是把 Blob 字节塞进 calldata
maxFeePerBlobGas
cell proofs
PeerDAS sampling
Fusaka / PeerDAS 把入块后的 Blob 数据切成列并通过数据可用性采样传播;EVM 仍不能直接读取 Blob 内容。
Type 3 的签名字段只放 blobVersionedHashes 与 maxFeePerBlobGas。
交易哈希只覆盖规范签名 body,不覆盖交易池提交 wrapper 或入块后的 data-column sidecars。[9][13]
TYPE 4 · EIP-7702
一笔交易里有外层签名,也可能有多份授权签名
授权元组写的是目标代码地址,authority 由元组签名恢复;外层 sender 可以是另一账户。 授权列表先于外层 EVM 调用处理;即使随后的外层执行 revert,已处理的委托与 authority nonce 也不回滚。 委托会持续存在,直到后续授权改写或清除。[10]
09 · Provenance
区块浏览器上显示的,哪些是你签下的?
交易对象、收据、区块上下文与执行追踪常被放在同一页,但它们不是同一层协议对象。
交易本体
- type 与类型字段
- nonce / to / value / data
- Gas 与费用上限
- 类型扩展字段
- 签名
协议收据
- status
- cumulativeGasUsed
- logsBloom
- logs
补充显示
- from / transactionHash
- gasUsed / effectiveGasPrice
- blockHash / blockNumber
- transactionIndex
- decoded method / token transfers
| 显示项 | 用户签下? | 什么时候出现 | 精确含义 |
|---|---|---|---|
| Transaction Hash | 派生自签名结果 | 签名完成后 | 规范已签名交易编码的 Keccak-256 |
| From | 不单独编码 | 节点拿到交易后即可恢复 | 摘要与签名恢复出的外层发送者 |
| Status | 否 | 执行后 | 顶层执行是否成功;1 不必然等于业务目标实现 |
| Gas Used | 否 | 执行后 | 这笔交易的实际 Gas 消耗 |
| Logs / Token Transfers | 否 | 执行后 / 索引后 | 合约事件与索引器对事件的解释 |
| Block / Position / Time | 否 | 入块后 | 验证者把交易放入的区块上下文 |
| Confirmations | 否 | 后续区块与共识推进后 | 浏览器根据链头或最终性派生的状态 |
TRANSACTION
真正的协议交易
有发送者签名、nonce、费用字段与独立交易哈希;可进入交易池和区块,并产生收据。
ETH_CALL
节点本地模拟
在指定状态上执行 call object,状态改动不持久化,不消耗真实 nonce 或 ETH,不产生链上交易哈希与收据。
INTERNAL TRANSACTION
其实是执行追踪
合约内部 CALL / DELEGATECALL / CREATE 等执行帧没有自己的外层签名、nonce、独立交易哈希或收据。
10 · Synthesis
把一笔交易重新装回去
从“我要做什么”,到“协议究竟接受了哪组字节”。
签名前的八项字段检查
- 01
链对吗?核对 chainId 与钱包网络,尤其是跨链桥、测试网和同地址多链场景。
- 02
真正的 to 是谁?区分最终接收者、代币合约、路由合约与代理合约。
- 03
value 是多少 ETH?它与代币金额、最大手续费是三回事。
- 04
calldata 被可靠解码了吗?核对函数、recipient、spender、amount、min received 与 deadline。
- 05
nonce 是否符合你的 pending 队列?替换候选必须使用预期的同一 nonce。
- 06
gasLimit 合理吗?过低可能 Out of Gas;异常高值要结合模拟与调用复杂度判断。
- 07
费用上限能接受吗?看 max fee,而不是只看钱包估算的“预计费用”。
- 08
有没有类型扩展?Blob 或 EIP-7702 授权列表代表额外能力,不能当成普通 Type 2 略过。
Comprehension check
六道题,检验你是否真的分层了
已完成 0 / 6
1. 下列哪一项通常显示在交易对象里,却不是规范签名交易本体的序列化字段?
2. 一笔 ERC-20 转账里,代币数量通常写在哪里?
3. 交易已经入块,但合约执行 revert。哪项说法正确?
4. gasLimit = 65,000 最准确的意思是?
5. Type 3 的规范签名 body 会把完整 Blob 字节写进去吗?
6. 哪一项在签名完成、尚未入块时就可以确定?
先问一个值来自哪里:是用户签下的字段、节点从签名派生的身份、 EVM 执行后的收据,还是验证者决定的区块上下文?来源一分开,绝大多数交易概念就不会混。
11 · Sources & glossary
术语速查与一手资料
课程按 2026 年 7 月以太坊主网现行规则核对;协议变化时,以当前规范与已激活升级为准。
raw transaction 需结合类型判断的“原始交易”
工具常用 raw 泛指已签名字节。对普通类型,它通常就是可提交的规范签名交易编码;Type 3 则要区分计算交易哈希的 signed body,与提交时还携带 blobs、commitments、cell proofs 的网络 wrapper。
signing preimage / digest 签名前像 / 签名摘要
按类型和字段顺序构造、尚未加入外层签名的字节,以及对它做 Keccak-256 得到的 32 字节摘要。
calldata 调用数据
消息调用传给合约的只读输入字节。交易层字段常叫 data,RPC 常叫 input;ABI 是常见解释约定。
receipt 交易收据
交易执行后产生的协议结果对象,核心包含状态、累计 Gas、日志布隆过滤器和日志;RPC 会附加更多上下文。
access list 访问列表
预先列出将访问的地址与存储槽,使其以“已预热”成本计价;它不是访问白名单,未列资源仍可被访问。
internal transaction 内部交易
浏览器对合约内部调用或价值移动的通俗命名。协议上它们是执行帧或 trace,不是独立签名交易。
-
[1]
ethereum.org · Transactions
交易定义、基础字段、calldata、合约创建与类型化交易概览。
-
[2]
ethereum.org · Ethereum accounts
账户 nonce、EOA 与合约账户的协议语义。
-
[3]
EIP-2681 · Limit account nonce to 2⁶⁴−1
账户 nonce 的共识上限。
-
[4]
Solidity · Contract ABI Specification
函数选择器、静态与动态参数的规范编码。
-
[5]
EIP-7825 · Transaction Gas Limit Cap
Fusaka 激活的单笔交易 Gas Limit 上限。
-
[6]
EIP-1559 · Fee Market Change
Type 2 字段顺序、签名摘要与有效 Gas 价格规则。
-
[7]
EIP-155 · Simple Replay Attack Protection
Legacy 交易如何把 chainId 纳入签名前像与 v。
-
[8]
EIP-2718 · Typed Transaction Envelope
类型字节、payload 与 Legacy 兼容边界。
-
[9]
EIP-4844 · Shard Blob Transactions
Type 3 字段、Blob 费与 versioned hashes。
-
[10]
EIP-7702 · Set Code for EOAs
Type 4、authorizationList、双层签名与委托处理。
-
[11]
ethereum.org · JSON-RPC API
交易对象、eth_call、收据与执行上下文字段。
-
[12]
Ethereum Execution Specs · Transactions
当前 fork 的交易联合类型、编码、签名恢复与交易哈希参考实现。
-
[13]
EIP-7594 · PeerDAS
Fusaka 后 Blob 数据列、cell proofs、交易池 wrapper 与共识传播规则。