以太坊提案7702
以太坊改进提案 EIP-7702:EOA 账户代码委托
EIP-7702 是一项以太坊改进提案,它允许外部拥有账户(EOA) 将其代码委托给另一个合约地址,从而使 EOA 能够像智能合约一样执行代码。这项提案为以太坊生态系统带来了新的可能性,让用户账户能够拥有更多的功能性。
EIP-7702 的核心概念
EIP-7702 引入了一种新的交易类型(0x4),它扩展了现有的 EIP-1559 交易格式,增加了一个authorization_list
字段。这个字段包含了授权信息,允许 EOA 账户将其代码委托给指定的合约地址。
授权列表结构
授权信息的结构包含以下字段:
chain_id
: 链 IDaddress
: 委托的合约地址nonce
: 账户的 nonce 值y_parity
,r
,s
: 签名信息
Gas 成本
EIP-7702 的 gas 成本计算遵循以下规则:
- 基础 gas 成本继承自 EIP-1559
- 授权列表中的每个授权项需要额外支付 25000gas
- 如果在授权时 EOA 账户已经在 access_list 中,则返还一半的 gas
代码委托机制
当 EOA 账户委托其代码给另一个合约地址时:
- EOA 账户的代码会被设置为
委托指示器
:0xef0100
+ 委托合约地址 - 当对 EOA 账户进行 call 调用时,会加载委托合约的代码作为 EOA 账户的代码执行
- CODESIZE 和 CODECOPY 指令使用的是委托合约的代码
- EXTCODESIZE 和 EXTCODECOPY 指令使用的是 EOA 账户的代码(23 字节)
特殊情况处理
EIP-7702 对一些特殊情况有明确的处理规则:
- 如果委托地址为零地址,则 EOA 账户的代码会被置空
- 如果委托形成循环(委托指示器指向另一个委托),则使用第一个委托的代码
- 如果委托地址为预编译合约,则相当于使用空代码,不会调用预编译合约函数
交易执行流程
EIP-7702 交易的执行流程如下:
- 交易检查和 gas 预付
- 发送账户的 nonce 增加
- 处理授权列表(在交易开始执行之前,增加 EOA 的 nonce,设置 EOA 账户的代码为
委托指示器
) - 执行交易的 call 调用
需要注意的是:
- 如果设置 EOA 账户代码的交易执行失败(开始执行前就已经设置 code 了),则已经成功设置的账户代码不会被撤销
- 如果处理某个授权时失败,则停止处理当前的授权,并继续处理下一个授权
- 处理失败的授权不会退还 gas 费
实际应用场景
EIP-7702 为以太坊生态系统带来了多种新的应用场景:
1. EOA 账户功能扩展
通过代码委托,EOA 账户可以拥有智能合约的功能,同时保持 EOA 的特性。这使得用户可以在不创建新合约的情况下,为自己的账户添加自定义逻辑。
2. 账户抽象
EIP-7702 为账户抽象提供了新的可能性,允许用户自定义其账户的行为,例如实现多签名验证、社交恢复等功能。
3. 资产托管
在正确设置委托代码的之后,允许其他账户在授权的情况下代表 EOA 执行资产转账等操作。
技术实现细节
EIP-7702 的实现涉及以太坊客户端的多个组件:
- 交易处理:增加新的交易类型,并在交易执行前处理授权列表(nonce 增加之后)
- 代码加载:修改 EVM 以支持代码委托机制,并在 call 类调用时加载委托合约的代码
签名验证是 EIP-7702 的关键部分,每个委托授权都需要对应的 EOA 亲自签署,授权信息的签名消息格式为:
msg = (0x05 || rlp([chain_id, address, nonce]))
而交易的签名消息格式为:
msg = (0x04 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list, authorization_list]))