以太坊,作为一个全球去中心化的计算平台,其核心在于能够安全、可靠地执行用户发起的交易,并更新整个网络的状态,而驱动这一切动态变化的核心机制,便是“账户状态转换”,理解这一概念,如同理解了以太坊引擎每一次跳动的脉搏,是掌握其工作原理的关键。

什么是状态?

在以太坊中,“状态”指的是在特定时间点,整个以太坊网络中所有账户信息的总和,你可以将其想象成一张巨大的、分布式的电子表格,记录了网络中每一个账户的实时数据,这张“表格”存储在以太坊的底层——以太坊虚拟机(EVM)所能访问的数据库中,即世界状态树(World State Tree)

每个账户在以太坊中都有四种基本属性:

  1. 余额(Balance):账户拥有的以太币(ETH)数量,以“wei”为单位(1 ETH = 10^18 wei)。
  2. Nonce:一个递增的计数器,对于外部账户(EOA),它代表该账户已发送的交易数量;对于合约账户,它代表该账户已创建的合约数量。
  3. 代码(Code):仅合约账户拥有,是一段智能合约的字节码,定义了合约的行为逻辑。
  4. 存储(Storage):仅合约账户拥有,是一个持久化的键值对数据库,用于存储合约运行过程中需要持久化的数据。

什么是状态转换?

“状态转换”指的是当一笔交易被网络确认并执行后,以太坊的世界状态如何从一种状态(S_old)转变为另一种新状态(S_new),这个过程是确定性的——给定相同的初始状态(S_old)和相同的交易,无论在哪个节点上执行,最终得到的新状态(S_new)都将完全一致。

状态转换函数可以抽象地表示为:S_new = U(S_old, T)

  • S_old 是交易执行前的世界状态。
  • T 是被执行的交易。
  • U 是状态转换函数,即EVM执行交易的过程。
  • S_new 是交易执行后的世界状态。

状态转换的详细步骤:一笔交易的旅程

一笔交易从被创建到最终导致状态转换,主要经历以下几个关键步骤:

  1. 交易广播与验证

    • 交易由发送者的外部账户(EOA)创建,并通过节点广播到以太坊网络。
    • 网络中的每个节点在将其纳入内存池(mempool)待处理前,会进行基本验证,包括:
      • 签名是否有效。
      • 发送者的Nonce是否与当前状态中的Nonce匹配。
      • 发送者的余额是否足够支付交易费用(Gas Fee)。
      • Gas Limit是否合理等。
  2. 交易执行(EVM的核心作用)

    • 当一个区块被挖出后,区块中的交易按顺序被挑选出来,由每个节点的EVM逐个执行。

    • EVM会根据交易类型(如转账、合约部署、合约调用)执行相应的操作,以下是几种常见交易类型导致的状态转换:

    • a. 转账交易(发送ETH)

      1. 更新发送者账户
        • 发送者的余额减少(发送者余额 = 发送者余额 - 交易金额 - Gas费用)。
        • 发送者的Nonce增加1(发送者Nonce = 发送者Nonce 1)。
      2. 更新接收者账户
        • 接收者的余额增加(接收者余额 = 接收者余额 交易金额)。
        • 接收者的Nonce保持不变(除非接收者也是合约账户且该转账触发了fallback函数,但这属于更复杂的情况)。
    • b. 部署合约交易

      1. 更新发送者账户
        • 发送者的余额减少支付Gas费用。
        • 发送者的Nonce增加1。
      2. 创建新的合约账户
        • 在世界状态树中创建一个新的合约账户。
        • 该合约账户的初始余额通常为0(除非在构造函数中接收ETH)。
        • 该合约账户的Nonce初始值为1。
        • 该合约账户的Code字段被设置为编译后的智能合约字节码。
        • 合约账户的存储初始为空。
        • 合约的创建者地址被记录。
    • c. 调用合约交易

      1. 更新发送者账户
        • 发送者的余额减少支付Gas费用。
        • 发送者的Nonce增加1。
      2. 执行合约代码
        • EVM根据交易中指定的合约地址,找到对应的合约代码和存储。
        • EVM从合约代码的指定入口点(通常是0)开始执行,并将交易数据作为输入参数。
        • 在执行过程中,合约可能会读取和修改自身的存储,甚至创建新的合约(这将进一步触发状态转换)。
        • 执行过程中会消耗Gas,如果Gas耗尽,交易会回滚,状态不会改变(除了扣除发送者已消耗的Gas费用)。
      3. 更新合约账户
        • 如果合约执行成功,合约的存储可能被修改。
        • 合约的余额可能发生变化(如果发送了ETH或合约转发了ETH)。
        • 合约的Nonce保持不变(除非是创建新合约)。
  3. 状态提交与区块确认

    • 当一个区块中的所有交易都执行完毕后,该区块中的所有状态变更(即S_new相对于S_old的差异)会被打包,并通过共识机制(如工作量证明PoW或权益证明PoS)得到网络共识。
    • 一旦区块被确认,它就被永久添加到区块链上,其对应的新状态(S_new)就成为以太坊网络最新的、公认的全球状态。

状态树与Merkle Patricia Trie

为了高效地存储和验证庞大的状态数据,以太坊使用了Merkle Patricia Trie(MPT)数据结构,特别是世界状态树、交易树和收据树。

  • 世界状态树:根节点包含了所有账户状态的哈希值。
  • Merkle Proof:由于所有数据都组织成Merkle树,任何节点都可以提供一个“证明”(Proof),来验证某个特定账户的状态是否包含在当前的全球状态中,而无需下载整个状态数据库,这极大地提高了轻客户端的效率和安全性。