以太坊账⼾模型的理解,合约账⼾、EOA账⼾认识
以太坊使用账户模型(Account Model)而非比特币的UTXO模型。以太坊有两种类型的账户:
1. 外部账户(EOA - Externally Owned Account)
- 特点:
- 由私钥控制
- 可以发送交易
- 没有相关代码
- 存储以太币余额
type EOAccount struct {Nonce uint64 // 交易计数器Balance *big.Int // 账户余额Address common.Address // 账户地址
}
2. 合约账户(Contract Account)
- 特点:
- 由代码控制
- 能执行智能合约代码
- 有自己的存储空间
- 只能被外部账户触发
type ContractAccount struct {Nonce uint64 // 合约创建计数器Balance *big.Int // 合约余额Address common.Address // 合约地址Code []byte // 合约代码Storage StateDB // 合约存储CodeHash common.Hash // 代码哈希
}
两种账户的主要区别
特性 | EOA账户 | 合约账户 |
---|---|---|
私钥控制 | ✅ | ❌ |
可发起交易 | ✅ | ❌ |
包含代码 | ❌ | ✅ |
gas费用 | 支付 | 执行消耗 |
触发方式 | 主动发起 | 被动调用 |
账户状态
两种账户都包含以下4个基本字段:
type AccountState struct {Nonce uint64 // 交易序号/合约创建数Balance *big.Int // 以太币余额StorageRoot Hash // 存储树根哈希CodeHash Hash // 代码哈希(EOA为空哈希)
}
实际应用示例
以您的代码为例,监听代币转账事件时会涉及两种账户:
// 处理账户间转账
func handleTransfer(from common.Address, to common.Address, value *big.Int) {// from可能是EOA或合约账户if from.IsContract() {// 合约账户转账逻辑} else {// EOA账户转账逻辑 }// to可能是EOA或合约账户if to.IsContract() {// 触发接收方合约的回调to.Call(transferData)} else {// 直接转账到EOAto.Transfer(value)}
}
通过理解这两种账户模型,可以更好地开发以太坊应用并处理不同类型账户之间的交互。