EIP-4337 之前:EIP-2938 想让以太坊协议直接接纳账户抽象 图 1
EIP-4337 之前:EIP-2938 想让以太坊协议直接接纳账户抽象 · 图 1

交易合法性曾经是四条硬规则

2020 年 9 月 4 日,维塔利克与另外四位作者把 EIP-2938 提交进 EIP 仓库。当时以太坊对一笔交易是否合法的定义非常刚性:ECDSA 签名有效、序列号匹配、账户余额足够,三样都对才进块。任何钱包想用别的签名方案、让别人代付手续费,都要在协议之外搭一层中间人。这份提案想做的,是把”合约可以成为顶层付款账户”直接写进协议:一种新型交易不带天然签名,验证与付费由一段合约代码在执行开头说了算。提案目前的正式状态是 Withdrawn(已撤回),仓库里给出的撤回理由很直白——内容严重过时,需要重写。

EIP-4337 之前:EIP-2938 想让以太坊协议直接接纳账户抽象 图 2
EIP-4337 之前:EIP-2938 想让以太坊协议直接接纳账户抽象 · 图 2

一个没有主人的入口地址

2938 定义了一个常量 AA_ENTRY_POINT,取值为全 F 的地址 0xffffffffffffffffffffffffffffffffffffffff。这个地址永远不会对应任何真实私钥,作用与后来的 把老地址直接升级成智能钱包:EIP-7377 迁移交易的一次性设计 里那个特殊入口类似:新交易类型的执行都从一段固定的入口逻辑开始,由它再调用你真正的账户合约。配套的是一个新的 EIP-2718 交易类型,载荷只有三个字段:noncetargetdata——没有签名字段,没有金额字段,因为”谁能代表这个账户”完全交给了目标合约的字节码。基础 Gas 成本从 21000 降到 15000,省掉的正是本来就不存在的签名验证开销。

PAYGAS:合约举手的瞬间

这份提案最独特的零件是名为 PAYGAS 的新操作码,编号 0x49。执行流跑到这条指令时,合约从内存里交出两个数:愿意支付的 Gas 单价与 Gas 上限。协议检查三件事——账户余额够不够付这笔上限、本笔交易的费用是否还没人认领、当前是否处于顶层执行帧——全部满足才把账户余额扣减、把这两个 Gas 参数登记为全局交易变量,后续执行就按这套参数计费。若顶层帧在 PAYGAS 之后回滚,只回退到 PAYGAS 之后那一刻,合约照样付账。提案还加了 NONCE(0x48)操作码,让合约能读到本次交易的序列号。整套设计的意图是:费用认领必须显式、且每笔交易只发生一次。

为什么撤回而不是否决

2938 的命运值得单独说:它不是被社区投票否决的技术方案。仓库元数据给出的撤回理由写得很直白——“非常过时,需要重写”(Very out of date; needs rewrite),属于提案因长期跟不上协议演进而退场;撤回记录没有注明具体经手人,但理由本身已经说明问题。它引用的前置提案 EIP-2718(带类型前缀的交易信封)早已生效,但 2938 依赖的整套协议改动始终没有排进任何一次主网升级。两年后风向彻底改变:社区选择了另一条路线——不改交易格式,而是在链上部署一套入口合约与打包服务,让任何人写的验证合约都能通过ERC-4337账户抽象是什么?的框架接入。两条路线的分野在于改谁:2938 改的是每个节点的协议代码,4337 改的是链上的一段合约。后者不需要硬分叉协调,这是它胜出的工程原因。

编号彩蛋:类型 2 曾经姓什么

细读 2938 会撞上一个有趣的脚注:提案给新交易类型分配的类型编号是 2(常量 AA_TX_TYPE 取 2)。而熟悉以太坊的朋友都知道,如今类型 2 属于 EIP-1559 的费用市场交易——因为 2938 从未进入任何分叉,这个编号在实际主网里从未被它用过,后来被 1559 拿走。同类故事在提案考古里并不罕见:一个停滞或撤回的提案留下的”预留位”,最终由完全不同的提案兑现。读旧提案时先核对状态字段,再下”以太坊曾经规定过”的结论,是避免张冠李戴的基本功。

今天回看这份提案的价值

对普通用户来说,2938 的直接遗产是零——没有一条主网规则来自它。但它把后来几年争论的议题清单完整地写在了 Motivation 一节:非 ECDSA 签名(Schnorr、BLS、抗量子方案)、多签与社交恢复、用代币而非 ETH 付手续费、隐私应用的批量接入。今天你在智能钱包里用到的每一样,几乎都能在那一节找到对应条目。判断一个账户抽象方案属于哪条路线,方法还是老一套:看它是否需要全网升级节点。需要的是 2938 式协议层路线,今天基本只剩研究价值;不需要的是 4337 式链上路线,也是你手里那个智能钱包大概率所在的层。风险提示:本文是提案历史分析,不构成投资建议;智能账户的恢复规则以你所用产品当期文档为准。