# 从EIP-101到EIP-4337，账户抽象的前世今生

By [CYNIC](https://paragraph.com/@cynicsong) · 2023-07-12

---

> _2023年3月2日，以太坊声明ERC-4337合约已在主网部署，遂成此文。_

![](https://storage.googleapis.com/papyrus_images/17ae27007f1785ed56cef0387e487d7e5b80f8e2e09fe01904a947c8698319ab.webp)

Generated by DALL·E

当我们谈论账户，我们在谈论什么？
----------------

以太坊当前有两种账户类型：外部拥有账户(Externally Owned Accounts, EOA)和合约账户(Contract Account, CA)。

EOA是大家平常认知的钱包，通过密码学算法随机生成**私钥和公钥**密钥对，公钥用于他人验证，私钥用于账户签名。**控制了私钥，也就控制了EOA**。Not your keys, not your coins。这里的keys说的就是私钥。

CA是部署到网络上的智能合约，**由代码控制**，合约账户的地址通常在部署成功后给出，由创建人地址和nonce产生。

两种账户类型都能：

*   接收、持有和发送 ETH 和 token
    
*   与已部署的智能合约进行交互
    

两种账户类型的区别：

**EOA**

*   创建帐户是免费的
    
*   可以发起交易（**主动发起**）
    
*   外部所有的帐户之间只能进行以太币和代币交易
    
*   由一对加密密钥组成：控制帐户活动的公钥和私钥
    

**CA**

*   创建合约存在成本，因为需要使用网络存储空间
    
*   只能在收到交易时发送交易（**被动触发**）
    
*   从外部帐户向合约帐户发起的交易能触发可执行多种操作的代码，例如转移代币甚至创建新合约
    
*   合约帐户没有私钥。 相反，它们由智能合约代码逻辑控制
    

以太坊帐户有四个字段：

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

可以看出EOA和CA两者各有利弊，EOA能主动发起，但CA具有可编程性，账户抽象(Account Abstraction, AA)其实就是希望将两种账户的优势进行融合，让用户能够使用任意验证逻辑、可编程性地发起交易。

滚滚长江东逝水，浪花淘尽英雄
--------------

账户抽象的发展，经历了多种方案的讨论和改进。

![](https://storage.googleapis.com/papyrus_images/b32e21f07914263d3af565ca40b6b2e220e734f6970ec2c85b67b02918af11c8.webp)

幽暗的树林里分出两条路
-----------

经过社区近两年的讨论，关于账户抽象问题大致形成了两个解决思路：**让EOA更像CA** — — EIP-3074、**让CA更像EOA** — — EIP-4337。

![](https://storage.googleapis.com/papyrus_images/c7dd22873f0845937710042972b32100e42591f94e58c47d308e1205727cade2.png)

与其将gas代付、批处理等能力庄严写入交易有效性的需求，EIP-3074允许用户将自己EOA的控制权委托给CA，这给了开发者灵活的框架来开发EOA的交易模式。简而言之，EIP-3074让EOA像CA一样运作而不需要部署合约。

使用EIP-3074，用户使用私钥签署消息。然后，该消息被包含在invoker的链上交易中。invoker将签名消息与AUTH操作码一起使用以获得对用户帐户的控制，并且使用AUTHCALL它可以代表用户执行操作。值得注意的是，包含用户签名消息的交易不一定要从该用户的账户发送，这使得用户不需要依赖ETH发送交易，而可以使用如ERC-20代币。

考虑安全性，用户依然是自己保管注记词和私钥，这方面的安全性不会减弱。但是invoker可能被授予了过高的权限，可能导致毁灭性的打击。

![](https://storage.googleapis.com/papyrus_images/4ec1ff3ef6ff46c5cbd5e4d004e882f894bdc872aeb9e77d42cc654aa65d6603.png)

EIP-4337在不改变共识层协议的前提下，试图实现以下目标：

*   允许用户使用包含任意验证逻辑的智能合约钱包而不是EOA作为主账户，完全移除对EOA的需求
    
*   维持去中心化，bundler打包者作为uo的block builder，无需信任；直接和公开内存池通信，用户不需要知道任何参与者的地址；
    
*   支持以下用例：隐私保护、原子多操作、ERC20支付gas、聚合签名(e.g. BLS)
    

EIP-4337工作逻辑如下：

1.  用户使用私钥对UserOperation签名（自定义签名逻辑、不需要ECDSA），将签名后的UserOperation发送至UserOperation mempool
    
2.  bundler挑选、验证UserOperation后（调用entry point的**simulateValidation**函数来验证签名正确且支付了fees），将验证通过的**打包**进bundle transaction中，实际是通过调用entry point合约的**handlerOps方法**。
    
3.  bundler由于负责发送bundle transaction，所以需要使用**ETH支付gas fee**，后续会从每个UserOperation的执行中**得到补偿**。
    
4.  entry point是一个确保安全的智能合约，将部分本来由wallet合约实现的部分复杂逻辑放到了entry point中。如果账户未创建，entry point需要使用UserOperation中提供的initcode创建账户，否则调用失效。
    
5.  entry point需要调用wallet合约的validateUserOp来验证UserOperation的有效性，并且从wallet中获取gas的refund（如果wallet认为该UserOperation有效）。如果验证不通过，handleOps必须跳过执行，可能需要全部撤销。
    
6.  对每个通过验证的UserOperation，handleOps会用UserOperation的**calldata调用wallet**。
    

注意，simulateValidation模拟过程需要确保UserOperation是有效的，且用户或者paymaster有能力支付gas fee。此外，还需要确保UserOperation在链上执行的时候这些条件还是有效的。所以，UserOperation禁止获取任何可能在模拟和执行之间改变的状态。如果sender发起了一个状态变化，需要支付高昂的Gas，该机制用于抵御DoS攻击。

革命尚未成功，同志还须努力
-------------

为了避免核心层的改动导致硬分叉，EIP-4337最终赢得了这场账户抽象的比赛。

EIP-4337的优势如下：

*   去中心化，无中心化角色（对比EIP-3074的invoker）
    
*   验证逻辑可编程性
    
*   执行逻辑可变，例如原子多操作
    
*   执行层量子安全，可以根据情况改变验证逻辑
    
*   钱包可升级性，可以更新wallet合约代码
    
*   DoS安全，除非sender状态改变（而这种攻击需要7500+的gas），不然UserOperation在模拟和执行时的一致性是相同的
    
*   不需要复杂的用户端设置，由entry point负责处理wallet创建的事宜
    
*   完全支持EIP-1559
    
*   支持replace-by-fee，发送一个更高premium的UserOperation可以自动替换掉之前的，或者让其更快执行。
    

然而，EIP-4337同样具备不足：

*   **Gas开销**，由于钱包是智能合约形式，所以创建账户就需要gas来部署钱包合约，导致额外的gas开销。此外，智能合约的调用也比EOA的转账等操作gas更高。尤其是在当前ETH主网上，高昂的gas fee会劝退很多用户。
    
*   **每次只能单交易**，由于UserOperation要求user的状态不能改变，所以没法排队送入多个交易到内存池中，不过由于可以支持原子多操作，这个问题显得不那么重要了。
    

目前最大的问题当然是高昂的gas开销，这也就是为什么在以太坊的路线图中，vitalik将EIP-4337纳入**The Splurge阶段**（目前规划的最后阶段）来实施。在可见的未来中，**ZK Rollup**的大规模使用应该能显著缓解gas开销问题，为EIP-4337的使用打开突破口。

![](https://storage.googleapis.com/papyrus_images/c26bfbe8b2e73fdc885cb0208a113d68b858b80693f726abeb462af1a75b5600.webp)

参考文献：

[https://camiinthisthang.substack.com/p/account-abstraction-for-everyone](https://camiinthisthang.substack.com/p/account-abstraction-for-everyone)

---

*Originally published on [CYNIC](https://paragraph.com/@cynicsong/eip-101-eip-4337)*
