以太坊帐户

一个以太坊帐户是一个具有以太币 (ETH) 余额的实体,可以在以太坊上发送交易。 帐户可以由用户控制,也可以作为智能合约部署。

帐户类型

以太坊有两种帐户类型:

  1. 外部账户 (External Owned Accout, EOA): 私钥的所有者控制
    • 接收、持有和发送 ETH 和 token
  2. 合约账户 (Contract Account, CA): 一种由代码控制,部署在网络上的智能合约。
    • 与已部署的智能合约进行交互

外部和合约账户使用相同的数据结构,只是使用的字段不同。

1
2
3
4
5
6
7
8
// StateAccount is the Ethereum consensus representation of accounts.
// These objects are stored in the main account trie.
type StateAccount struct {
Nonce uint64
Balance *big.Int
Root common.Hash // merkle root of the storage trie
CodeHash []byte
}

外部账户 EOA

特点:

  1. 有私钥
  2. 用于确定每笔交易只能被处理一次的计数器(nonce)。
  3. 发送交易(以太币转账、发布合约、调用智能合约)
  4. 拥有以太币余额(以太币存放的地方,与比特币的UTXO模式不同)的balance。
  5. 没有相关联的代码

关键字段

外部账户和智能合约使用的数据给构是一样的,只是外部账户只用两个字段有用:

  • Nonce – 显示从帐户发送的交易数量的计数器。 这将确保交易只处理一次。 在合约帐户中,这个数字代表该帐户创建的合约数量
  • Balance – 这个地址拥有的 Wei 数量。 Wei 是以太币的计数单位,每个 ETH 有 1e+18 Wei。

注意,因此外部账户数据中 StateRootHashCodeHash 默认值是!!!!

合约账户

存储智能合约的账户,合约代码可供调用,执行合约逻辑。

特点:

  1. 没有私钥
    仅有公开的地址,它的行为由合约自身包含的代码逻辑来控制
  2. 拥有余额
  3. 有合约代码
  4. 能够被其它合约调用
    合约代码能够被交易或者其他合约消息调用,通过地址
  5. 能够调用其他合约
    合约代码被执行时可再调用其他合约代码。
  6. 能够改变数据存储
    合约代码被执行时可执行复杂运算,可永久地改变合约内部的数据存储。

智能合约账户的地址创建并非由外部促成,而是在创建合约时候由代码自动生成的。

关键字段

  • Nonce – 显示从帐户发送的交易数量的计数器。 这将确保交易只处理一次。 在合约帐户中,这个数字代表该帐户创建的合约数量
  • Balance – 这个地址拥有的 Wei 数量。 Wei 是以太币的计数单位,每个 ETH 有 1e+18 Wei。
  • CodeHash - 该哈希表示以太坊虚拟机 (EVM) 上的帐户代码。 合约帐户具有编程的代码片段,可以执行不同的操作。 如果帐户收到消息调用,则执行此 EVM 代码。 与其他帐户字段不同,不能更改。 所有代码片段都被保存在状态数据库的相应哈希下,供后续检索。 此哈希值称为 codeHash。 对于外部所有的帐户,codeHash 字段是空字符串的哈希。
  • Root – 有时被称为存储哈希。 Merkle Patricia trie 根节点的 256 位哈希已编码了帐户的存储内容(256 位整数值映射),并编码为 Trie,作为来自 256 的 Keccak 256 位哈希的映射位整数键,用于 RLP 编码的 256 位整数值。 此 Trie 对此帐户存储内容的哈希进行编码,默认情况下为空。

每个账户在世界状态树中的呈现

账户模型

这还没完,账户每笔交易形成的树

账户的storageRoot.png

多个区块的MPT树共享了账户状态,子块状态树和父块状态树的差别在于它指向了在子区块中被改变了的账户。这样节省了总的存储空间,方便了块的回滚操作。

账户状态是被共享的.png

总结

账户模型跟世界状态关联比较紧密,需要了解清楚,对构建世界状态的了解有帮助。