Ethereum learning path · 04.01

同一笔付款,为什么有两种账本?

比特币保存一组尚未花掉的输出; 以太坊保存一张持续更新的账户状态表。 理解这一区别,是进入地址、nonce、Gas、合约与世界状态的第一把钥匙。

约 45 分钟 9 个知识段 3 组可操作图解

UTXO set

离散的可花费凭证
9f…21 : 00.70 u
c4…8a : 20.50 u

钱包显示 1.20,是把能解锁的输出相加;协议里没有“Alice.balance”这一格。

00 · Orientation

先别问“哪一种更先进”

先问:一条链要用什么最小数据,证明价值没有被凭空复制?

“UTXO 模型”和“账户模型”不是两种界面,也不是钱包的两种皮肤。 它们是协议对当前状态是什么一笔交易改了什么的两种回答。

一条价值网络至少要连续回答四个问题:现在谁有权花什么?一笔新请求是否得到授权? 同一份价值有没有被用过?按确定顺序处理后,新状态是什么? 比特币把答案组织成“仍未被花掉的交易输出”;以太坊把答案组织成“地址映射到的账户状态”。

01 / Ownership

谁能动用价值?

UTXO 看某个输出的解锁条件是否满足;以太坊通常从签名恢复交易发送者,再查该地址的账户状态。

02 / Uniqueness

怎样阻止重复使用?

UTXO 一经消费就从可花集合移除;账户交易必须使用发送者当前期待的 nonce。

03 / Conservation

价值从哪里到哪里?

UTXO 检查输入总额与输出总额;账户模型直接修改发送者、接收者及费用相关账户的状态。

04 / Commitment

节点如何核对结果?

节点按协议重算状态并核对区块承诺;模型不同,“相信提议者给答案”都不是验证。

本课的唯一主线

UTXO 模型管理的是可花费对象的集合; 账户模型管理的是持久对象的当前状态。 后面所有差异,都可以从这句话推出来。

01 · UTXO model

比特币没有“从余额里扣一点”

它消费旧输出,再创建一组全新的输出。

UTXO 是 Unspent Transaction Output,即“未花费交易输出”。 一个输出包含价值数量与花费条件;它由上一笔交易的 txid 和输出序号 vout 唯一定位。 输入引用旧输出,并提供满足其锁定条件的数据。[1]

如果钱包说“你有 1.20”,协议并没有保存一行 Alice = 1.20。 钱包找到所有由你的密钥或脚本条件可以解锁的 UTXO,再把数额相加。 所谓“余额”是钱包从可花输出集合推导出的视图。

一笔 UTXO 交易的骨架

Inputs · 消费旧输出

9f…21 : 0引用 0.70 u 的旧输出,并满足它的解锁条件
c4…8a : 2引用 0.50 u 的旧输出,并满足它的解锁条件

Outputs · 创建新输出

to Bob · 0.80 u新锁定条件:未来由 Bob 提供相应解锁数据
change · 0.39 u找零不是退款;它与付款一样,是本交易创建的新输出

Σ inputs 1.20 u Σ explicit outputs 1.19 u= fee 0.01 u

图 01 费用是输入总额减去显式输出总额的差,不是一枚新 UTXO。示例统一使用抽象单位 u,只比较数据模型。
U′ = ( U − Inputs ) ∪ Outputs 新 UTXO 集合 = 旧集合移除本次消费的输出,再加入本次新建的输出。

为什么必须“整张花掉”?

一个 UTXO 是不可拆分地被引用和消费的对象。假设你只有一张 1.00 u 的输出,要付 0.60 u, 交易会消费整张 1.00 u,再创建“给对方 0.60 u”和“给自己找零(扣除费用后)”两个新输出。 原来的 1.00 u 输出不再可花;找零拥有新的 txid:vout

  1. 输入必须指向当前仍存在的 UTXO。如果它已在规范历史中被消费,新交易就不能再次消费它。

  2. 解锁数据必须满足旧输出的花费条件。“控制地址”只是钱包层的简写,协议真正检查的是脚本条件。

  3. 普通交易不能让输出总额超过输入总额。输入减去输出的差额构成交易费。[2]

  4. 钱包要做 coin selection。它选择哪些 UTXO 作为输入,会影响费用、找零、隐私与以后可花输出的形状。

不要把 UTXO 当成“账户里的零钱格”

UTXO 不属于某个协议级账户对象。它是带花费条件的离散输出。 地址复用、钱包标签和“我的总余额”都是在这组输出之上的组织方式。

02 · Account model

以太坊保存的是一张“地址 → 状态”映射

账户会持续存在,交易直接更新它的当前字段。

以太坊执行层把世界状态抽象为 σ。给定一个地址 aσ[a] 返回该地址当前的账户状态。 经典账户记录由 nonce、balance、storageRoot、codeHash 四个字段组成。[3]

对一个地址做“状态 X 光”

图 02 这里只画逻辑模型。客户端怎样把数据放进本地数据库,可以不同;节点必须对协议状态与根承诺得到一致结果。

Interactive · account x-ray

点一个字段,看它解决什么问题

n

nonce · 账户顺序计数器

对普通外部账户,它约束下一笔可执行交易的序号。某个 nonce 在一条规范状态序列中只能被使用一次,因此旧签名不能无限重放。

最简单的 ETH 转账改了什么?

先忽略 Gas 的精确结算:发送者余额减少,接收者余额增加,发送者 nonce 增加。 它不是消费一张“2.10 ETH 输出”再创造找零;它是在同一张状态映射里更新几个账户记录。 真实交易还会检查签名、链标识、nonce、费用上限与余额,并按执行结果结算 Gas。 这些字段将在第 6、7 章完整展开。[4]

PRE-STATEσ
Alice.balance
2.10
Alice.nonce
7
Bob.balance
0.35
POST-STATEσ′
Alice.balance
1.29
Alice.nonce
8
Bob.balance
1.15
σ′ = Υ( σ, T ) 新世界状态 = 协议状态转换函数 Υ 对旧状态 σ 和有序交易 T 的执行结果。图中费用固定为 0.01 u,仅为对照模型。
钱包不等于账户

账户是链上状态实体;钱包是生成密钥、签名和展示资产的工具或界面。 一个钱包可以管理多个外部账户,也可以操作智能账户。把两者分开,后面理解助记词与合约钱包会更清楚。

2026 年的进阶注脚

Pectra 升级中的 EIP-7702 允许由密钥控制的账户把关联代码设置为一个委托指示器; 当目标地址存在代码时,调用可按该目标代码执行。 所以“EOA 的 codeHash 永远为空”已不再是绝对规则。它扩展的是账户执行能力, 并没有把以太坊改成 UTXO 模型;授权与安全边界留到本章后续账户课程再展开。 [7]

03 · Payment lab

拖动金额,看两种模型各自改哪里

最终可用价值可以相同,状态转换的路径完全不同。

Alice 起初有三枚可花 UTXO:0.40、0.70、1.00 u;在账户模型里,她的余额是 2.10 u。 Bob 起初有 0.35 u。每次实验把费用固定为 0.01 u,只隔离观察状态模型。

实验中的教学钱包先选择输入枚数最少的组合,再选择总额最接近付款需求的组合。 真实钱包的选币策略并不由比特币协议统一规定,还会权衡实际字节费用、隐私、确认状态与 UTXO 碎片。

Interactive · one payment, two states

Alice 向 Bob 支付

u 是教学单位。实际 BTC 以 satoshi、ETH 以 wei 记账;两条链的费用机制也不同。

0.80 u

UTXO · 选择并消费输出

input 1.00
0.40 u
5a…:0
0.70 u
91…:1
1.00 u
c8…:0
消费 → 新建
Bob 的新输出0.80 u
Alice 的找零输出0.19 u
支付 0.80 u:UTXO 钱包选择 1.00 u 的输出,创建 0.80 u 付款和 0.19 u 找零;账户模型把 Alice 改为 1.29、Bob 改为 1.15,并把 Alice.nonce 从 7 改为 8。

你应该从实验里看见三件事

  1. UTXO 会留下交易图。新输出明确引用旧输出形成的输入;价值沿 outpoint 关系流动。

  2. 账户模型会留下状态序列。同一个地址的余额与 nonce 随有序交易持续变化。

  3. 总额相同不代表数据相同。Alice 最终可用 1.29 u;一边由三枚 UTXO 的剩余集合推导,一边直接是账户余额字段。

04 · Validity

一个检查 outpoint,一个检查 nonce 与账户状态

两者都拒绝相互冲突的状态转换,但有效性条件不是一一对应。

双花不是“链上出现负余额”这么简单。它是两份候选交易试图让同一份旧授权产生两次有效后果。 UTXO 模型让冲突聚焦于同一个 outpoint;账户模型让冲突聚焦于同一发送者状态下的 nonce 与余额。

Interactive · collision

先执行 A,还是先执行 B?

UTXO conflict · 同一 outpoint

A花费 9f…21:0 → Bobaccepted
B花费 9f…21:0 → Carolrejected
A 先进入规范状态后,9f…21:0 已不在 UTXO 集合中,Alice 的下一期待 nonce 也变成 8;候选 B 不能再接着执行。

现实网络里,两份冲突交易可能暂时存在于不同节点的交易池、发生替换,或落在竞争分支。 关键不是“第二份永远不会传播”,而是同一条规范状态序列不能让它们依次都成功。 UTXO 被消费后不再存在;账户 nonce 前进后,旧 nonce 不再匹配。

UTXO 与账户交易的有效性检查
验证问题比特币 UTXO以太坊账户
授权对象被输入引用的旧输出及其锁定条件发送者地址恢复出的账户与交易签名
防重复outpoint 必须仍在 UTXO 集合中nonce 必须等于发送者当前期待值
余额检查输入总额必须覆盖输出总额发送者余额必须覆盖价值与协议要求的费用边界
失败后的对象无效交易不会消费输入已被区块纳入且执行回滚的交易通常仍消耗 Gas,发送者 nonce 仍前进
依赖关系显式写在输入引用的 outpoint 上隐含在账户 nonce、余额与合约读写状态中
nonce 不是时间戳

它不表示交易几点发生,也不保证全球交易按地址排序。 它只在相关账户的同链状态转换中提供顺序与一次性约束;区块内的全局交易顺序仍由区块明确给出。 防止普通签名交易跨链重放还需要 chain ID,不能把所有重放保护都归功于 nonce。

05 · Contracts

账户模型为什么适合“持久程序”

合约地址像一个长期存在的对象:代码与存储可以被下一次调用继续读取。

以太坊不只转移 ETH。一个合约账户可以在地址上关联代码与持久存储; 交易调用它时,EVM 读取当前世界状态,执行代码,再把余额、存储、日志等结果写入新的世界状态。

这让“调用 A 合约,A 再调用 B,B 读取 C 的余额”可以在同一笔交易的原子执行里发生。 所有对象共享同一个执行状态语境,成功则一起提交,异常则按 EVM 规则回滚相应状态。 账户模型因此很自然地表达可组合的持久对象。

EOA 签名交易 调用 Router Router 调用 Pool 读取账户与 storage 一次提交新状态

但不要得出“UTXO 不能有合约”

比特币输出本身就带脚本化花费条件;其他系统还发展出扩展 UTXO 等不同合约设计。 真正差异不是“能不能编程”,而是程序的状态放在哪里、下一次执行引用什么对象、 多个程序怎样组合。账户模型以持久地址和共享可变状态为中心;UTXO 风格以显式消费旧状态、创建新状态为中心。

从本课通向后面的课程

第 8 章讲 EVM 时,你会看到代码如何操作 Stack、Memory 与 Storage; 第 9 章讲合约生命周期;第 11 章再拆世界状态与 trie。 本课只先回答:为什么这些持久状态天然被组织到“账户”上。

06 · Trade-offs

不是优劣榜,是一组工程取舍

对象边界、并行性、隐私、钱包复杂度与合约表达能力相互牵动。

UTXO 的自然优势

  • 依赖显式:输入直接指出要消费哪些旧输出,互不重叠的交易更容易看出独立性。
  • 局部证明清楚:验证焦点是特定 outpoint 是否存在、脚本是否满足、总额是否守恒。
  • 可换地址:钱包可以把新输出发往新地址,减少长期复用单一地址;但交易图仍可能被聚类分析。
  • 状态是一次性的:旧输出被消费后退出集合,不存在“原地修改同一枚输出”。

账户的自然优势

  • 余额直观:协议状态直接记录地址的当前余额,简单转账不需要 coin selection 与找零输出。
  • 持久对象自然:合约代码与存储附着在地址上,下一次调用可继续使用同一状态。
  • 同步可组合:多个合约在同一交易中读写共享状态,易于表达 DeFi 等原子流程。
  • 代价是争用:同一账户 nonce 和热门合约状态会形成顺序依赖,需要执行层精确管理读写冲突。
UTXO 与账户模型的八个核心差异
维度UTXO 模型账户模型
当前状态所有仍未花费输出的集合地址映射到的账户及合约存储
“余额”钱包对可控制 UTXO 求和得出账户记录中的协议字段
付款动作消费整枚旧输出,创建付款与找零输出更新发送者、接收者和费用相关状态
顺序约束输入必须引用尚未消费的 outpoint发送者交易 nonce 必须连续匹配
并行边界不相交输入让独立性更显式,但不自动等于更高吞吐不相交状态访问也可并行,但共享账户与存储带来冲突分析
隐私形态新地址有帮助;找零与交易图启发式仍可关联长期地址活动容易聚合;新地址也不自动切断资金图谱
合约状态通常通过消费旧状态输出、创建新状态输出表达代码与可变 storage 持久附着在地址上
钱包工作UTXO 发现、选币、找零、费用与碎片管理nonce 管理、Gas 估算、授权与合约交互
“UTXO 天生可以无限并行。”

不准确。互不引用同一输出让依赖更显式,但区块验证、脚本成本、父子交易与共识规则仍形成边界;模型本身不赠送无限吞吐。

“账户模型一定只能串行执行。”

也不准确。没有状态冲突的交易可以被并行化研究或实现;困难在于预先识别动态合约调用的真实读写集合,并保持与规范顺序完全相同的结果。

“UTXO 就匿名,账户就实名。”

两者通常都是假名系统。UTXO 的找零识别、共同输入等启发式会暴露关联;账户地址复用会聚合活动。隐私取决于完整使用方式,不取决于一个标签。

“账户余额简单,所以钱包安全也简单。”

账户模型省去了找零与选币心智负担,却引入 nonce、Gas、代币授权、合约调用与签名语义等新风险。界面简单不等于授权边界简单。

07 · Recap

把整课压缩成两句话

先抓住对象,再抓住状态转换。

UTXO:哪些输出还可花? 账户:每个地址现在是什么状态?
  1. 01

    UTXO 是一次性对象。输入消费旧输出,交易创建付款与找零等新输出。

  2. 02

    UTXO 余额是推导值。钱包把自己能解锁的未花输出求和。

  3. 03

    以太坊账户是持久状态。地址映射到 nonce、余额、存储根与代码哈希等字段。

  4. 04

    账户交易原地更新逻辑记录。简单付款改变余额与发送者 nonce,不创建“找零账户”。

  5. 05

    两者都防重复授权。UTXO 检查 outpoint 仍未花费;账户检查 nonce 与当前状态匹配。

  6. 06

    账户模型利于持久合约组合。代码与 storage 附着于地址,可在同一原子交易中跨合约读写。

  7. 07

    模型不是性能或隐私的单变量答案。真实结果还取决于执行、共识、钱包策略和使用习惯。

  8. 08

    执行回滚不等于交易没发生。已纳入区块的有效账户交易即使调用回滚,发送者 nonce 通常仍前进并支付实际 Gas。

现在检查你的理解

1. 比特币钱包显示 1.20 BTC,协议层最准确的解释是什么?

2. 用 1.00 u 的 UTXO 支付 0.60 u 时,剩余价值通常怎样处理?

3. 账户交易的 nonce 主要解决什么?

4. 账户模型为什么自然适合以太坊合约?

5. “UTXO 依赖显式”能直接推出什么?

6. 一笔以太坊交易被区块纳入,但合约执行随后回滚,通常会怎样?

08 · Sources

术语与一手资料

先建立可靠心智模型,再进入地址、签名、交易与 Gas 的实现细节。

核心术语

UTXO UNSPENT TRANSACTION OUTPUT

尚未被任何规范交易输入消费的交易输出;包含价值数量与未来花费条件。

Outpoint TXID + VOUT

由交易标识与输出序号组成,唯一指向某笔旧交易里的具体输出。

找零输出 CHANGE OUTPUT

消费的 UTXO 超过付款与费用时,交易为付款者创建的新输出;它不是原 UTXO 的“剩余余额”。

世界状态 WORLD STATE

以太坊执行层在某一时刻的全部账户状态逻辑集合,包括余额、nonce、代码与合约存储承诺等。

Nonce ACCOUNT SEQUENCE

账户状态中的计数器。对普通 EOA,它约束下一笔可执行交易的序号并帮助防止签名交易被重复执行。

状态转换 STATE TRANSITION

节点按协议规则,从旧状态和有序交易输入计算新状态的过程。

官方一手资料

  1. 01
    Bitcoin Developer Guide — Transactions 输入如何引用旧输出、输出怎样成为 UTXO,以及找零输出的基本机制。 核对:2026-07-25
  2. 02
    Bitcoin Developer Guide — Block Chain UTXO / 已花输出分类、输入输出价值约束与费用差额。 核对:2026-07-25
  3. 03
    ethereum.org — Ethereum accounts 账户类型、nonce、balance、storageRoot、codeHash 与钱包/账户边界。 页面更新:2026-04-13
  4. 04
    ethereum.org — Transactions 签名交易字段、nonce、价值、费用参数与交易生命周期。 页面更新:2026-03-12
  5. 05
    Ethereum Yellow Paper 账户状态四字段、交易有效性与执行状态转换的形式化基线;分叉细节应同时核对当前执行规范。 持续维护的形式化说明
  6. 06
    Ethereum Execution Layer Specification 当前执行层分叉规则与状态转换的可执行规范来源。 持续更新的协议仓库
  7. 07
    EIP-7702 — Set Code for EOAs 进阶注脚:为什么 Pectra 后不能再绝对假设密钥控制账户的代码字段为空。 本课不展开授权与执行细节
下一步

本章下一课将把“外部账户 EOA:由谁控制、怎样主动发起交易”单独拆开。 到那时再深入私钥、签名恢复、地址与交易发起权;现在先确保你能用自己的话解释 “消费输出”与“更新账户”究竟差在哪里。