返回论坛
EVM 深度探索 Part 4
查找币:余老师
|
学术研究
|
2025-11-02 18:05
|
10 次浏览
|
0 条回复
查找币
学术研究
安全研究
Web3安全
区块链安全
查找币 - 专业Web3安全服务
🔐 钱包恢复服务 | 💰 加密货币找回 | 🛡️ 区块链安全审计
专业团队,安全可靠,成功率高 | Professional Team, Secure & Reliable, High Success Rate
**作者:Flush**
## 导言
欢迎阅读 “EVM 深度探讨” 系列的第四部分。在前面的第三部分中,我们深入了解了合约存储的相关知识。本期我们将探讨单个合约的存储如何融入到以太坊链更广泛的 “世界状态” 中。我们将深入了解以太坊链的架构、数据结构,以及 "Go Ethereum"(Geth)客户端的内部结构。
让我们从以太坊区块中包含的数据开始,逐步深入一个特定合约的存储,最终探究 Geth 中 SSTORE 和 SLOAD 操作码的实现。
本文将介绍 Geth 代码库,帮助读者更好地理解以太坊的 “世界状态”,从而加深对 EVM 的整体理解。
## 以太坊架构
首先,让我们从以下架构图开始,不要被图中复杂的结构所吓倒。在本文结束时,我们将会对这一架构有一个全面的认识。这张图展示了以太坊的架构以及以太坊链中所包含的数据。

接下来,我们将逐个分析图中的内容。首先,我们将关注第 N 个区块头及其包含的字段。
### 区块头
区块头包含了一个以太坊区块的关键信息。以下是第 N 个区块头划分出的区块数据字段。让我们看一下 Etherscan 上的区块 14698834,看看是否能找到图中所示的一些字段。
- Prev Hash:父区块的 Keccak 哈希
- Nonce:用于满足 PoW 的随机值
- Timestamp:写入当前区块的 UNIX 时间戳
- Uncles Hash:叔块 Keccak 哈希
- Beneficiary:收款人地址,矿工费接收者
- LogsBloom:Bloom 过滤器,提取自 receipt,由可索引信息(日志地址和日志主题)组成
- Difficulty:当前出块的难度,设置产生单位工作量证明需要消耗多少算力
- Extra Data:与该区块相关的 32 个字节的数据,由矿工自定义
- Block Num:区块高度
- Gas Limit:一个区块允许消耗的最大 gas 量
- Gas Used:此区块内交易所消耗的总 gas 量
- Mix Hash:256 位的值与 nonce 一起使用,以证明工作证明的计算,代表区块不含 nonce 时的哈希值
- State Root:执行完此区块中的所有交易后以太坊中,所有账户状态的默克尔树根 Keccak 哈希值
- Transaction Root:交易生成的默克尔树的根节点哈希值
- Receipt Root:交易回执生成的默克尔树的根节点哈希值
以上字段与 Geth 客户端代码库中定义的 "Header" 结构体相对应。代码库中的值与概念图中的内容匹配。我们的目标是从区块头开始追溯,直到找到单个合约的存储区。为了实现这一目标,我们需要关注块头的 State Root 字段。
### 状态根(State Root)
状态根类似于默克尔根,因为它是一个哈希值,取决于其下所有数据块。如果任何数据块发生变化,根也会发生变化。在 “状态根” 下的数据结构是一个 Merkle Patricia Trie,为网络上的每个以太坊账户存储一个键值对结构,其中 key 是一个以太坊地址,value 是以太坊账户对象。
Merkle Patricia Trie 是一个复杂的数据结构,它为每个以太坊账户存储了一个键值对结构。实际上,key 是以太坊地址的哈希值,value 是 RLP 编码的以太坊账户。在以太坊体系结构图中,Merkle Patricia Trie 表示了 “状态根”。
如果你对 Merkle Patricia Trie 感兴趣,推荐阅读这篇优秀的介绍性文章。
接下来,让我们看看以太坊账户信息是如何映射到地址的。
### 以太坊账户
以太坊账户是一个以太坊地址的共识代表,由 4 个字段组成:
1. Nonce:显示从帐户发送的交易数量的计数器,确保交易只处理一次
2. Balance:账户余额
3. StorageRoot:指向账户存储的根哈希
4. CodeHash:合约代码的哈希值
[...内容已精简...]
7. 如果上述方法都没有返回,就检索 originStorage 并返回值。
函数首先返回 dirtyStorage,然后是 pendingStorage,最后是 originStorage。这是合理的,因为在执行过程中,dirtyStorage 是最新的存储映射,其次是 pending,最后是 originStorage。一笔交易可以多次操作同一个插槽的数据,因此我们需要确保获取的是最新的值。
假设在同一笔交易中,在 SLOAD 之前发生了 SSTORE 操作,dirtyStorage 将在 SSTORE 中被更新,在 SLOAD 中被返回。
通过对 Geth 层面的 SSTORE 和 SLOAD 实现有了一定了解。它们如何与状态和存储对象进行交互,以及更新插槽与更广泛的以太坊 “世界状态” 的关系。
这篇文章内容较为深入,能坚持读完已经很不错了,这也是我们探索加密世界的乐趣所在。下一篇文章让我们一起学习探讨操作码 CALL & DELEGATECALL。
## 往期回顾
- 查找币出品 | 2022 区块链安全及反洗钱分析年度回顾
- 智能合约安全审计入门篇 —— 移花接木
- 查找币:朝鲜 APT 组织对 NFT 用户大规模钓鱼分析
- 查找币:警惕 TransferFrom 零转账骗局
- 引介|EVM 深入探讨 Part 3
## 查找币导航
- [查找币科技官网](https://www.查找币.com/)
- [查找币区官网](https://查找币.io/)
- [查找币 GitHub](https://github.com/查找币)
- [Telegram](https://t.me/查找币team)
- [Twitter](https://twitter.com/@查找币_team)
- [Medium](https://medium.com/@查找币)
- [知识星球](https://t.zsxq.com/Q3zNvvF)
---
本文由查找币安全团队整理发布。