跳到正文

基于账户的状态模型

通过账户字段、状态根与存储根、有序交易执行、Gas 与回滚、代币存储、EIP-7702 委托、访问列表、执行轨迹和最终性,理解以太坊的账户模型。

更新于

仅供教育参考,不构成投资建议;投资可能产生损失。

直接答案

基于账户的模型把执行状态表示为以地址为键的数据。在以太坊执行层中,一个账户叶节点包含 [nonce, balance, storageRoot, codeHash]。原生 balance 以 wei 计价;合约数据位于该账户 storageRoot 所指向的存储中;区块执行后的 stateRoot 则承诺最终形成的世界状态。钱包、RPC 服务商或区块浏览器只负责读取并解释这些状态,并不替用户保存规范账本上的余额。

ERC-20 余额、授权额度、借贷债务和抵押品通常是合约存储中的值,不是持有人协议账户上的额外字段。同样,浏览器所称的“内部交易”通常是通过执行轨迹还原的 EVM 消息调用,并不是拥有独立交易哈希和发送方 nonce 的另行签名以太坊交易。

传统的外部拥有账户(EOA)与合约账户之分仍然有用,但在启用 EIP-7702 的链上,“EOA 一定没有代码”已不再绝对。EOA 可以带有委托指示符 0xef0100 || address,在保留 EOA 交易发起权限的同时执行受托代码。因此,分类应依据链规则和实际账户代码,而不是沿用旧的界面标签。

七步状态转换审计

  1. 固定观察口径:网络、chainId、分叉规则、区块号和区块哈希、时间戳,以及 pendinglatestsafefinalized 等区块标签。链头附近的状态可能因重组改变;不同区块的事实不得在未标注的情况下合并。
  2. 读取协议账户字段:nonce、原生 balancestorageRootcodeHash。如果代码是 EIP-7702 委托指示符,应按该分叉规则解析受托地址。对于代理和委托账户,还要分别识别实现代码、升级控制和存储布局。
  3. 定位应用余额。ETH 会改变原生余额;ERC-20 余额通常改变代币合约存储中的映射;授权额度、债务、抵押品和奖励可能位于其他合约及存储槽。代币精度和日志有助于解释,但不是额外的账户叶字段。
  4. 解码并预检顶层交易:交易类型、链域、签名、发送方 nonce、接收方或合约创建、转移价值、输入数据、Gas 上限、费用上限,以及可选访问列表或 EIP-7702 授权。发送方必须能够支付转移价值和最高费用承诺。被拒绝的交易不会纳入区块,也不会消耗链上 Gas。
  5. 从前一状态开始,按区块顺序执行交易。EVM 处理嵌套消息调用和合约创建帧,每个帧各有调用方、被调用方、价值、calldata、Gas 和返回状态。共享读写使结果依赖执行顺序。EIP-2930 访问列表会预热列明的账户与存储槽并改变 Gas 核算,但既不禁止未声明访问,也不能证明可以安全并行。
  6. 应用提交与回滚边界。成功帧提交其状态与日志,除非父帧随后回滚。REVERT 会回滚失败帧的写入、价值转移和日志,同时返还未使用 Gas;外层合约可以捕获子调用失败后继续成功。已纳入区块的顶层失败,其回执为 status = 0,但发送方交易 nonce 仍增加,并须支付已消耗 Gas。即使之后的执行回滚,EIP-7702 授权处理也有其独立的持久化规则。
  7. 核对执行后状态。将原生及代币余额差额、存储变化、回执状态、Gas 使用量、有效 Gas 价格、日志和服务商执行轨迹,与区块承诺的根进行匹配。执行轨迹是服务商重建的视图,不是独立共识交易。达到所需最终性后,再明确处理替换交易、链重组、索引器修订、跨链桥、Rollup 和会计冲销。

四个算例

  • EIP-1559 ETH 转账。 A 初始有 5 ETH、nonce 为 12;B 初始有 1 ETH。A 转出 1 ETH,使用 21,000 gas,基础费为 20 gwei,优先费上限为 3 gwei,最高费用为 40 gwei。有效 Gas 价格为 min(40, 20 + 3) = 23 gwei;总费用为 21,000 × 23 gwei = 0.000483 ETH,其中基础费销毁 0.000420 ETH,优先费为 0.000063 ETH。签名时所需最高金额为 1 ETH + 21,000 × 40 gwei = 1.000840 ETH。最终 A 余额为 3.999517 ETH,B 为 2 ETH,A 的 nonce 为 13
  • 已纳入但回滚的交易。 A 初始有 2 ETH、nonce 为 7。A 携带 0.50 ETH 调用合约;顶层执行在消耗 80,000 gas 后回滚,有效 Gas 价格为 25 gwei,所以费用为 80,000 × 25 gwei = 0.002000 ETH。合约存储写入、日志和 0.50 ETH 转移均被回滚,而 A 最终余额为 1.998000 ETH、nonce 为 8,回执为 status = 0。如果子调用失败被外层捕获,外层回执也可能为 status = 1
  • 代币余额属于合约存储。 某代币合约记录 Alice 有 1,000 units、Bob 有 200 units。成功转移 250 units 后,Alice 有 750 units,Bob 有 450 units,总量仍为 1,200 units。如果 Alice 的顶层交易消耗 60,000 gas × 20 gwei = 0.001200 ETH,她的原生 ETH 余额会另行减少这笔费用。代币账户的 storageRoot 和全局 stateRoot 都会改变;代币本金从未成为 Alice 的原生账户余额。
  • EIP-7702 持久化边界。 赞助方提交一笔 set-code 交易,其中包含账户 A 在 nonce 5 时向实现 D 发出的授权。协议写入 23-byte 指示符 0xef0100 || 20-byte address,并将 A 的授权 nonce 增至 6。如果该顶层交易随后的执行回滚,已经处理的委托指示符和授权 nonce 仍然保留。这与失败调用写入普通 EVM 存储时的回滚边界不同。

风险与控制

  • 读取错误的链、分叉、区块哈希或区块标签,会产生内部不一致的状态快照。
  • 过时或不可信的 RPC 可能遗漏、滞后或误报链头状态。
  • 待处理 nonce 竞争、断档和替换可能使排队假设失效。
  • 钱包中的“取消”通常是替换交易,而不是协议层删除。
  • 余额不足以覆盖价值和最高费用,会阻止交易纳入。
  • 基础费变化或费用上限错误可能延迟纳入或改变成本。
  • EIP-7702 代码可能使旧式账户启发法误判 EOA。
  • 恶意受托代码、初始化缺陷或授权重放可能危及 EIP-7702 账户。
  • 代理升级和委托调用可能使代码及存储解释随时间改变。
  • 密钥、签名域或链 ID 错误可能授权盗窃或重放。
  • 重入和共享状态排序可能在一次执行内改变余额。
  • 子调用失败可被捕获,而外层交易仍显示成功。
  • 顶层回滚或 Gas 耗尽仍会消耗 Gas 并增加发送方 nonce。
  • 代币精度、转账收费、再定基和钩子可能使简单余额算术失效。
  • 仅核对钱包余额可能遗漏授权额度、债务、抵押品和奖励。
  • 日志可能缺失、被回滚、具有误导性,或不足以证明最终状态。
  • 浏览器“内部交易”和服务商执行轨迹可能因其均为重建视图而不同。
  • 访问列表可能不完整、重复或不经济,也不会锁定读写集。
  • 共享状态排序、优先费和 MEV 可能改变执行结果。
  • 链重组、数据裁剪、证明不可用、L2 系统转换和跨链桥最终性可能冲销或遮蔽会计记录。

常见误区

  • “钱包保存链上余额。”钱包保存凭证,并展示从网络取得的状态。
  • “每个地址都永久属于无代码 EOA 或普通合约。”EIP-7702 委托改变了这种代码判断方法。
  • “每一笔显示的转账都是独立以太坊交易。”代币事件和内部消息调用轨迹不是顶层签名交易。
  • “失败交易什么都不改变,也没有成本。”已纳入的失败可能消耗 Gas 并推进发送方 nonce。
  • “账户模型或访问列表保证比 UTXO 更快地并行执行。”性能和冲突取决于完整协议与工作负载。

相关主题

来源

导航

搜索知识库...