# 论账户抽象(2022)

By [freeyao](https://paragraph.com/@freeyao) · 2022-07-08

---

近来，以太坊『账户抽象』的议题再次引发讨论。在 5 月份的 EthShanghai 活动上，我向 Vitalik 询问 ERC-4337 的提出是否意味着以太坊协议层的账户抽象会暂时停滞。他解释道核心开发者正忙于合并大业，一时半会顾不过来，而 ERC-4337 不是一个协议层的更新，无需硬分叉，推动的难度会小很多。

本文不会分析 ERC-4337 做了什么，可阅读[提案](https://eips.ethereum.org/EIPS/eip-4337)或[中文解读](https://www.notion.so/plancker/EIP-4337-0baad80755eb498c81d4651ccb527eb2)。本文希望在尽可能少引入专业术语的情况下把账户抽象讲明白。

直观理解账户抽象
--------

### 账户是什么

什么是账户？本文不想引用会计学上的定义，而是用更直白的说法。以太坊是去中心的账本，客户在账本上的数字映射及对应的资产、交易记录共同构成了客户的账户。

以太坊的账户包含哪些要素呢？其实并不复杂——账户标识符、验证方式、状态。默认存在的账户称为外部账户(EOA)，它的标识符(地址)为 0x前缀连接 40 位的十六进制数。如何计算地址呢？首先，你拥有基于椭圆曲线secp256k1的一个公私钥对，并对公钥进行 **Keccak-256** 哈希运算，取其最后 20 字节即可。外部账户的验证方式是什么呢？进行任何链上操作时，你需要提交与其公钥对应的签名，此外还得包含一个特定的一次性数值(nonce)，以防止被别人利用(重放)。除了外部账户以外还有什么账户类型呢？这就是智能合约账户，其标识符(地址)也是同样的格式和长度，仅从标识符无法区分两种账户类型。智能合约账户是如何验证权限的？很简单，由代码决定。而对于两种账户来说，状态都是指关联该账户标识符的数据信息。

接下来这段话很重要，这是大多数讨论中容易忽视的部分，它决定你是否能真正理解『账户抽象』的动机。

『账户』抽象中的『账户』，与『外部账户』、『智能合约账户』中的『账户』并非完全重合。回到定义，『账户』意味着其对应着客户，是从需求角度出发的。而『外部账户』和『智能合约账户』则反映的则是『存在』，是从供给角度出发的。几个简单的问题或许可以帮助理解，『黑洞地址』是『账户』么？『统计选票的智能合约地址』是『账户』吗？做出否定的答案并不困难。

本文讨论的是需求角度而非供给角度的『账户』，这意味着我们只关心『客户』的需求，因此在接下来的描述中，我会使用『外部地址』和『智能合约地址』来描述非『账户』的以太坊地址。

### 抽象是什么

什么是抽象？『抽象』这个词就挺『抽象』的，不得不借助专业的定义。

『维基百科』：

> 是指以缩减一个概念或是一个现象的资讯含量来将其广义化的过程，主要是为了只保存和一特定目的有关的资讯。

我们不妨打个比方，地址 **0xb9b8981856851ca455bfbe65ed488621a9b70862** 是一个**外部地址**，发送过 56 笔交易，内有 **0.636 ETH 和其它若干资产**。如何对这些描述进行抽象化呢？（账户标识符，验证方式，状态）三元组即可。账户抽象就是对这三个属性进行广义化。

### 账户抽象到底在抽象什么

*   账户标识符的广义化
    

以太坊的账户标识符是特化的，你无法使用任意长度的任意字符来作为账户标识符。换言之，你没法用自己的名字作为账户标识符。核心开发者并没有对账户标识符广义化的计划，[将地址扩展到 32 字节](https://ethereum-magicians.org/t/increasing-address-size-from-20-to-32-bytes/5485)的讨论是从更丰富的功能角度出发的。包括 ENS 在内的大量域名项目在应用层试图满足客户的此类需求，并没有看到想在协议层解决这个问题的方案。

*   账户验证方式的广义化
    

以太坊的账户验证方式按照其类型是不同的，外部账户是特化的，智能合约账户则是广义化的。那是否智能合约钱包就解决了账户验证方式的抽象问题呢？这里还遗留的问题是——需要一条交易携带在 EVM 中检验智能合约账户有效性的数据，而这条交易必须由**外部地址**发起。以太坊上交易有效性的判定与外部账户的验证方式是一致的，简单来说，除了需要提交包含指定 nonce 的签名外，还需要提供一定数量的 Ether。在大部分语境中，『账户抽象』和『智能钱包』的区别就在于是否需要对交易有效性进行抽象，包括检验『数据有效性』和『资产有效性』的方式（这里我们把 Ether 看作一种资产，而非一般意义的数据）。

*   状态的广义化
    

以太坊账户状态是更加复杂的问题，在这篇文章不展开。

综上所述，我们讨论的账户抽象，主要是指账户验证方式的广义化，特别需要指出的是，这里隐含了交易有效性的广义化问题。

特化真的不好吗？
--------

如果外部地址不好，为什么以太坊一直沿用至今呢？显然，它有某些难以替换的优势，主要体现在以下方面。

### 交易池安全

以太坊是一个无许可的网络，交易在网络中的传播是无需支付费用的，直到它被纳入区块。这意味着攻击者可以无需花费实际的成本而消耗节点的计算资源，但只有完成交易有效性判定后才会进行转发，也才会消耗所有的全节点(e.g. 以太坊网络)的计算资源。以太坊交易有效性验证是避免无效交易消耗全网资源的重要手段，而特化则更将这种影响降到最低。第一个原因是 ECDSA 签名的验证成本相对较低，且除了读取地址 nonce 以外，所有操作都是节点本地完成的。第二个原因是交易一旦有效，永远有效。进入内存池的交易不会因为其它交易的执行成功而失效，这意味着节点总能收取交易发起方『质押』的费用（除非用相同 nonce 的交易替换原交易，但仍然需要支付费用）。这里『质押』的费用，就是该账户为此交易愿意支付的最大金额(= gasLimit \* gasPrice)。有关这部分，可参考我[此前的文章](https://mp.weixin.qq.com/s/ZGzw3VE-8KEQE5xu7Jw_8A)。

### 世界状态精简

以太坊的状态爆炸问题由来已久，而特化则缓解了状态膨胀的增长速度。每个外部账户所占有的存储空间仅有标识符与 nonce，共占用 20 + 32 = **52** 字节，而智能合约账户呢？以 Argent 为例，存储密钥和守护者至少需要占用 7 \* 32 = 224 字节，总结占用空间为 224 + 20 = 244 字节，约为外部账户的 4.7 倍。考虑到 nonce 存在大量优化空间，一旦 EIP-2681 实施，nonce 占用的空间将降到 16 字节。则该倍数将扩大到 244/(20+16)= 6.8 倍。

影响有多大呢？假设按照 Argent 宣称的要让 10 亿客户使用以太坊，仅账户存储一项，Argent 智能合约账户至少占用 227 GB，而外部账户则只需要 48 GB。需要注意的是，修改交易有效性规则与状态数据大小关系不大，但稍有区别的是，目前的外部账户没有为存储空间显性付费，智能合约账户则支付了手续费。假设在协议层实现账户抽象，如何为存储收费呢？

需要在以太坊协议层做账户抽象吗
---------------

### 智能钱包做得足够好

『智能钱包』可以实现任意的账户权限控制逻辑，EIP-2938 的核心论点在于，智能合约账户与外部账户是不平等的，无法直接作为交易发起者，因此要给他们平等的权力。然而，在协议层做账户抽象意味着提高了交易池的风险，也增加了世界状态的计费迷思。假设如外部账户一样，不向客户收取存储费用，则世界状态会加速膨胀，而假设收取存储费用，恐怕是提高而非降低以太坊的使用门槛。

本文的核心论点是，智能钱包的运营者可以用中继者的方案来解决这个问题，正如 ENS 解决账户标识符广义化的问题一样，构建系统外的商业共识。而即使运营者不提供服务，用户永远可以使用自己的外部账户操作智能合约账户。

### ERC-4337: 解决问题还是创造问题？

Flashbots 提供了一种体系外协商手续费的方式，因此让链上 0 费用的交易成为合理的选择。Vitalik 在看到 Flashbots 拯救密钥泄漏账户中的 ERC-20 代币后萌生了 ERC-4337 的雏形。本文无意评价 ERC-4337 的利弊，只想提两个问题与大家讨论。

1.  是否所有功能都要通过系统内共识完成，即使它带来极大的缺点和不确定性？
    
2.  建立在特定 MEV 解决方案基础上的账户抽象是否稳健，假设 Flashbots 的方案最终被淘汰，用户需要直接和矿工/验证者打交道？

---

*Originally published on [freeyao](https://paragraph.com/@freeyao/2022)*
