菜单

核心概念

相关源文件

本文档解释了节点、账户、交易、区块等基本概念,以及 geth 在以太坊生态系统中的作用。它提供了以太坊执行层核心数据结构和机制的技术概述,将概念理解与 go-ethereum 中的实际代码实现联系起来。有关系统级架构信息,请参阅架构

Geth 和以太坊节点

Geth(Go Ethereum)是以太坊执行客户端的完整实现。以太坊节点是运行以太坊客户端软件的计算机,通过验证交易、执行智能合约和维护区块链状态来参与以太坊网络。

节点类型和同步

来源:cmd/geth/main.go276-312 cmd/utils/flags.go256-261 eth/backend.go90-125 eth/downloader/downloader.go p2p/server.go

Geth 可以作为不同类型的节点运行

  • 完整节点:存储最近的区块和状态,验证所有交易
  • 存档节点:存储完整的历史状态和区块数据
  • 轻节点:仅下载区块头(由于外部轻客户端的出现已弃用)

Geth 在以太坊中的作用

来源:eth/backend.go90-125 cmd/geth/main.go314-329 eth/ethconfig/config.go76-166

Geth 负责以太坊的执行层,负责

  • 通过 EVM 处理交易和执行智能合约
  • 维护世界状态和账户余额
  • 处理点对点网络和数据同步
  • 为外部应用程序提供 JSON-RPC API
  • 与共识层客户端协调以进行区块验证

区块链数据结构

以太坊区块链由一系列区块组成,每个区块都包含修改全局状态的交易。此结构通过几个关键数据类型实现。

区块

以太坊中的区块由 types.Block 结构表示,它封装了区块头和区块体。

来源:core/types/block.go core/blockchain.go core/genesis.go452-459

区块头包含有关区块的元数据,包括

  • ParentHash:父区块的哈希,构成区块链的“链”
  • Root:执行此区块后状态树的根哈希
  • TxHash:区块交易的 Merkle 根哈希
  • ReceiptHash:收据树的哈希
  • Number:区块编号(链中的高度)
  • Time:区块创建时间戳

区块体包含

  • Transactions:区块中包含的交易列表
  • Uncles:叔块(ommer)区块头的列表
  • Withdrawals:验证者提款列表(在上海升级中添加)

事务

交易是以太坊中状态转换的机制。types.Transaction 结构是不同交易类型的容器。

来源:core/types/transaction.go core/types/tx_legacy.go core/types/tx_dynamic_fee.go core/txpool/txpool.go

关键交易组成部分

  • Type:交易类型(Legacy, AccessList, DynamicFee, Blob)
  • To:收款方地址(合约创建时为 nil)
  • Value:转移的 ETH 数量
  • Data:输入数据(简单转账时为空,包含合约部署代码或函数调用数据)
  • Gas:交易可消耗的最大 Gas 单位
  • GasPrice / GasFeeCap / GasTipCap:Gas 定价机制

状态管理

以太坊的状态代表所有账户和合约的当前状态。状态通过称为 StateDB 的结构进行管理。

StateDB

state.StateDB 是在区块执行过程中跟踪和修改世界状态的核心组件。

来源:core/state/statedb.go core/state/state_object.go core/types/state_account.go core/blockchain.go

StateDB 提供用于以下操作的方法:

  • 检索和修改账户余额、代码和存储
  • 跟踪自毁的合约
  • 将更改提交到状态树
  • 计算状态根哈希

在交易执行期间,更改会被应用到内存中的 stateObjects 中,并通过日志记录以备回滚。在区块结束时,更改会被提交到树结构。

状态转换和日志记录

状态可以通过交易进行修改,并且这些修改会通过日志机制进行跟踪。

来源:core/state/journal.go core/state/statedb.go core/state_processor.go

对于每个交易,StateDB

  1. 在日志中记录更改
  2. 允许通过 Snapshot() 创建快照
  3. 启用通过 RevertToSnapshot() 恢复到快照
  4. 在交易边界使用 Finalise() 完成更改
  5. 使用 IntermediateRoot() 计算中间状态根
  6. 将所有更改提交到持久存储,使用 Commit()

Merkle Patricia Tries (默克尔帕特里夏树)

以太坊使用改进型默克尔帕特里夏树 (MPT) 来存储状态、交易、收据和存储数据。这种数据结构提供了高效的数据完整性验证。

Trie 结构和目的

来源:trie/trie.go trie/node.go triedb/database.go

每个 Trie 由四种节点组成

  • 分支节点:最多有 16 个子节点,对应每个十六进制字符
  • 扩展节点:通过存储键的共享部分来优化路径
  • 叶子节点:存储实际的键值对
  • 哈希节点:引用数据库中存储的节点

Trie 提供

  • 数据的加密验证
  • 高效的更新和删除
  • 通过路径共享最小化存储

以太坊中的 Trie 类型

以太坊出于不同目的使用了多种 Trie

来源:trie/trie.go trie/secure_trie.go core/state/statedb.go

  1. 状态 Trie:将地址映射到账户数据(余额、nonce、代码哈希、存储根)
  2. 存储 Trie:每个合约账户都有自己的存储 Trie
  3. 交易 Trie:组织块内的交易
  4. 收据 Trie:存储交易收据

Trie 操作

Trie 上的关键操作包括

  • Get:检索键对应的值
  • Update:插入或修改键值对
  • Delete:删除键值对
  • Commit:将更改持久化到数据库
  • Hash:计算 Merkle 根

来源:trie/trie.go core/state/statedb.go triedb/database.go

StateTrieTrie 提供了安全的包装器,可以自动对键进行哈希处理,从而防止可能导致深层 Trie 和性能问题的恶意键构造。

交易处理

交易处理是一个多阶段的过程,会改变系统状态。

交易流程

来源:core/state_processor.go core/state_transition.go core/types/transaction.go

关键阶段包括

  1. 签名验证:确保交易已获得发件人授权
  2. 预检查:验证 nonce、gas、value 和余额
  3. 执行:
    • 对于价值转移:更新发送方和接收方的余额
    • 对于合约调用:调用 EVM 执行代码
  4. 状态更新:对账户和存储的任何更改都将应用于状态
  5. 收据生成:创建包含执行结果的收据

交易类型

以太坊支持多种交易类型

  1. 旧版交易 (Type 0):原始以太坊交易
  2. 访问列表交易 (Type 1):在柏林硬分叉中引入,允许指定访问的地址/存储槽
  3. 动态费用交易 (Type 2):在伦敦硬分叉中引入,支持 EIP-1559 费用模型
  4. Blob 交易 (Type 3):在 Cancun 中添加,用于第 2 层数据可用性
  5. SetCode 交易 (Type 4):在 Prague 中引入,用于优化合约部署

来源:core/types/transaction.go core/types/tx_legacy.go core/types/tx_dynamic_fee.go params/config.go

账户结构

以太坊有两种类型的账户,都由 StateAccount 结构表示。

来源:core/state/state_object.go core/state/statedb.go core/types/state_account.go

  1. 外部拥有账户 (E O A):
    • 由私钥控制
    • 可以发送交易
    • 没有代码或内部存储
  2. 合约账户:
    • 由代码控制
    • 由 EVM 在触发时执行
    • 可以将其数据存储在其存储 Trie 中
    • 可以调用其他合约

两种账户类型在状态 Trie 中共享相同的结构,但合约账户具有非空的 code 并且可能有非空的 storage Trie。

状态同步

以太坊节点需要高效的机制来同步状态。

来源:eth/downloader/downloader.go eth/downloader/statesync.go eth/handler.go eth/ethconfig/config.go52-53

以太坊支持不同的同步策略

  1. 完整同步:下载并处理创世区块以来的每个区块
  2. 快照同步:直接下载最近的状态,然后像完整同步一样继续
    • 更高效,因为它避免了处理所有历史交易
    • 使用 Trie 节点而不是逐块处理

同步包括

  • 下载账户和存储 Trie 节点
  • 检索合约代码
  • 将所有数据与状态根哈希进行验证

结论

本页面涵盖了 go-ethereum 的基本概念,重点关注

  • 具有区块和交易的区块链数据结构
  • 通过 StateDB 进行的状态管理
  • 用于高效状态存储的 Merkle Patricia Tries
  • 交易处理和账户类型
  • 状态同步方法

这些概念构成了以太坊执行层的基础,在 go-ethereum 代码库中实现。理解这些组件对于使用或贡献代码库至关重要。