先说一个很多人都遇到过的尴尬:钱包里躺着几百 USDC,想转一点给朋友,界面却弹出一行字——“ETH 余额不足,无法支付 gas”。你明明有钱,却连手续费都交不起,像揣着一沓现金站在只收硬币的售货机前。更绝望的是另一种场景:抄助记词的那张纸丢了。没有”忘记密码”,没有客服,没有申诉入口,链上资产从此变成一座纪念碑。
这些尴尬不怪钱包 App 做得烂,怪以太坊账户模型的”出厂设置”。《Web3 的入口 - 区块链钱包》里介绍过的私钥账户叫 EOA(Externally Owned Account,外部账户),你可以把它理解成一把钥匙管一切的旧式机械门锁:一把钥匙就是全部,丢了就完了,没有挂失,没有备用方案。而账户抽象(Account Abstraction,AA)想干的事,说白了就一件:把这把旧门锁换成智能门锁——账户从”一把私钥”升级成”一段可编程的合约”,”怎么验身份、怎么付 gas、怎么执行”,全由代码说了算。
熟悉我的朋友应该知道,我经常从零实现一些东西帮助理解,本文照例代码驱动:先用 Python 模拟 ERC-4337 里一个 UserOperation 从提交到结算的完整生命周期,再模拟社交恢复与 guardian 串通攻击,中间穿插 EIP-7702 的机制讲解,所有输出均为真实运行结果,纯标准库,复制即可跑。
EOA:一把钥匙管一切的旧门锁
EOA 就是”一把私钥对应一个地址”,链上最常见的账户形态,也是绝大多数 web3 事故的案发现场。它到底哪里不行?拿你家那把老式机械门锁对比一下,你立刻就懂了。三宗罪:
罪一:钥匙丢了,家就没了。 现实里银行卡丢了能挂失补办,门锁钥匙丢了能找师傅换锁芯。EOA 没有这套服务——地址是由私钥推导出来的,换钥匙等于换账户、等于搬家。所以私钥一丢,资产永久冻结;一被偷,瞬间搬空。谁捡到钥匙谁就是主人,进门无声、不可逆,连”改密码”这个选项都不存在。
罪二:交物业费只收现金。 协议规定,手续费只能从交易发起者自己的 ETH 余额里扣,gas 的来龙去脉见《Gas:链上一切行为的价格标签》。就像一个只收现金、还不收人民币以外任何东西的物业——你手机里有的是余额,没用,人家不认。所以”一堆 USDC 加零 ETH”在链上等于寸步难行,微信代缴?没这功能。
罪三:进门规则只有一种。 EOA 的验证逻辑就一条:签名对,放行。你想加一条”每天最多转 100””只许转白名单地址””小孩只能进书房”?没地方写,这把锁出厂时就没留这个接口。
三宗罪的病根是同一个:EOA 的账户逻辑焊死在协议层,谁也改不了。而智能合约的逻辑是代码,想怎么写就怎么写。把账户从”一把私钥”变成”一段合约”,上面这些限制就都变成了”几行代码的事”——这就是智能合约账户。两边摆在一起看更直观:

换上智能门锁,日子能过成什么样
先别急着看机制,看看换锁之后的具体好处——每一条,都对应旧锁的一宗罪:
- 社交恢复:钥匙丢了?让几个你信任的人投票,配一把新的,资产原地不动。丢钥匙 ≠ 丢钱,怎么做到的下一节细讲。
- 批量调用:approve + swap 一次签名、原子执行,成则全成,败则全败。还记得《Web3 中的授权与撤销授权》里那笔单独的 approve 交易吗?没了——进门、开灯、撤防盗一个动作全办完。
- gas 代付:应用方替你垫 ETH,你用 USDC 结账,甚至完全免费——物业费有人代缴,新用户零门槛入场。
- 消费限额 / 白名单:单日限额、大额延迟到账、只许调用指定合约。”小孩只能进书房”这句话,终于可以写进锁里了。私钥就算被钓鱼,损失也被框死。
- session key:给游戏发一把”临时小钥匙”:只能调用这个游戏合约、最多花 5 USDC、两小时后自动过期——像给钟点工办的临时门禁卡,到点自动作废。再也不用每砍一刀怪就签一次名。
好,愿景画完了。问题是怎么实现——这就引出了本文的主角之一。
ERC-4337:不改协议,先点一份外卖
最直接的思路是改协议,让合约账户也能发起交易。这条路社区从 2017 年就开始铺(Vitalik 的 EIP-86,后来的 EIP-2938 等一批提案),但全部阵亡——动共识层就是硬分叉,所有客户端一起改,协调成本高到没人敢接盘。
2021 年提出的 ERC-4337 换了个思路:协议一行不改,在应用层再造一套”交易系统”。它不依赖任何硬分叉,靠部署一组合约实现,2023 年 3 月在主网生效。
这套系统一共五个角色,第一次读文档的人十个有九个绕晕。别慌,用点外卖串一遍,五分钟记牢:
- UserOperation(UserOp)=你写的订单。它不是交易,是一张”意图单”:sender 是你家门牌号(你的账户合约地址),callData 写着”要一份鱼香肉丝”(想执行的调用),nonce 是订单号、防重复下单,signature 是你的亲笔签名。
- Bundler =跑腿小哥。蹲在接单大厅(专用内存池 alt mempool)里抢单,把一批订单合并成一次配送,塞进一笔真正的交易上链。小哥先垫配送费(gas),事后报销——他自己就是个普通 EOA。
- EntryPoint =外卖平台。全局唯一的入口合约,整套系统的裁判。平台负责核验订单真伪:逐单验签、查订单号防重放、确认付得起配送费,然后调度你家门锁开工。
- Account =你家的智能门锁。订单送到后,门锁自己判断”这单是不是主人下的”——判断逻辑写在你的合约里(
validateUserOp函数),单签、多签、passkey、社交恢复,随便你定义。 - Paymaster =会员免运费。可选角色,声明”这单配送费我出”;平台核验时还会问它一句”这单你认吗”,事后再向用户收 USDC 当运费——相当于代金券抵扣。
一张订单的一生
一张 UserOp 从提交到结算,就是一次外卖的旅程:
- 钱包构造订单(UserOp),你签字,扔进接单大厅 alt mempool——它独立于普通交易池,带严格的准入规则(限制验证阶段可访问的状态和操作码),防止有人用”模拟通过、上链必挂”的订单白嫖小哥,也就是防 DoS。
- 跑腿小哥抢单,先在本地把每张订单模拟跑一遍,会失败或亏本的一律丢掉,剩下的打包成一笔交易,调用
EntryPoint.handleOps送单。 - 平台核验订单:EntryPoint 逐个调用账户的
validateUserOp(验签、检查 nonce 防重放、确认付得起 gas);带了 Paymaster 的,再问它一句”这单你认吗”。 - 门锁收货开工:EntryPoint 逐个把 callData 交给账户合约执行,真正的转账、swap 在这一步发生。
- 结账:有 Paymaster 的调用它的
postOp做事后结算(比如向你收 USDC);EntryPoint 从账户或 Paymaster 的预存款里扣掉实际 gas 付给小哥,并发出事件回执。
两个细节值得记住:第一,Paymaster(以及多数账户)的 gas 钱是预存在 EntryPoint 合约里的,所以你的”ETH 余额”可以一直是零——运费早就在平台充值过了;第二,验证失败会让整笔 bundle 回滚、小哥白付 gas——这就是小哥抢单前必须先模拟的原因,赔本的配送他不接。

钥匙丢了怎么办:五个保管人里三个点头
智能合约账户最有杀伤力的能力,值得单独拆开讲。
先想一个现实场景:手机丢了,你不会崩溃——去运营商门店验个身份,补一张卡,原来的号码照用。社交恢复干的就是这件事,只不过运营商换成了你自己的亲友团。用家门钥匙的语言说:账户合约里除了 owner(你天天揣着的签名钥匙),还登记一组 guardian(守护人)和一个阈值,比如 3-of-5——家门钥匙丢了,5 个保管人里 3 个点头,就能给你配把新钥匙。
但这里有一层精妙的设计,画个重点:保管人凑再多人,也只能帮你换锁,进不了你家门。转账入口只认 owner 的签名,guardian 的签名在那里一文不值——5 个保管人加起来,也搬不走你家一台电视。
恢复流程走一遍:钥匙丢了 → 生成一把新钥匙 → 请 guardian 对”把 owner 换成新地址”这件事签名 → 凑够 3 个 → 合约进入宽限期(timelock) → 到期生效,旧钥匙作废。全程资产不动、地址不变,变的只是”谁有权签名”。常见的实现还会给现任 owner 一个否决权,防止 guardian 趁你失联时偷换。
guardian 怎么选?原则是分散、类型混合:亲友可能被社工,自己的另一台设备可能和手机一起丢,机构服务可能倒闭,各有各的失效模式,混着配才不会一锅端。全选同一类,等于把鸡蛋放回同一个篮子。
那 guardian 串通怎么办?对比一下两条路的”作案体验”就明白了。guardian 想摸钱,必须先走”换 owner”这条路,而这条路是公开的(链上可见)、慢的(有宽限期)、可否决的(现任 owner 能取消);私钥被盗呢?瞬间、无声、不可逆。但也别把这读成”guardian 串通无害”——如果宽限期内没人发现,多数 guardian 确实能夺走账户,所以阈值、宽限期、异常提醒三样缺一不可。这套取舍,下面的代码会完整演示。

EIP-7702:老房子不动产权证,请个专业管家
4337 很优雅,但有个尴尬:它的账户是一个新的合约地址。你用了五年的 EOA,上面的资产、授权、NFT、链上履历,全得搬家。让存量用户换地址,就像让用户换手机号,阻力巨大。
EIP-7702 专治这个,2025 年 5 月随 Pectra 升级上线主网。打个比方:老房子不动产权证不变,给房子请了个专业管家。它新增了一种交易类型(0x04),交易里带一个授权列表:EOA 的主人用私钥签一条授权——“把我的账户代码指向合约 X”。授权生效后,EOA 的代码位置会被写入一个委托标记:0xef0100 || 合约地址(共 23 字节)。此后任何人调用这个 EOA,跑的都是合约 X 的代码,但读写的是 EOA 自己的存储和余额——门牌号没变,房子还是你的房子,只是日常打理换成了专业管家。
再强调一遍我在 approve 那篇里特别指出的事实:这个管家是长期聘用,不是干一单就走人的钟点工。”交易期间临时获得合约能力、用完自动恢复”这种流传甚广的说法,与最终上线的行为不符——委托在交易结束后持久存在,会一直挂在账户上,直到你再签一笔 7702 授权把它改掉或清空(指向零地址)。所以签 7702 授权 ≈ 把账户的执行逻辑长期交给那个合约,委托给恶意合约等同于把家门钥匙连同规章制度一起交出去,钱包对这类签名必须给出醒目提示。
还有个容易被忽略的事实:原私钥依然有效,而且权限最高——它随时可以换管家、发普通交易。所以 7702 给了你批量调用、gas 代付、限额这些功能,却治不了私钥单点的病根:钥匙被偷,小偷照样能把管家换掉。想根治,终点站还是带社交恢复的合约账户。
7702 与 4337 不是竞争关系,而是上下游:委托指向的合约完全可以是一个兼容 4337 的账户实现,于是老 EOA 也能发订单、用免运费。一句话:7702 解决”存量房子怎么请管家”,4337 提供”请来管家之后的基础设施”。
4337 vs 7702:一张表看懂怎么选
机制都讲完了,选型是道送分题:
| 维度 | ERC-4337 | EIP-7702 |
|---|---|---|
| 账户形态 | 独立的合约账户 | EOA 上挂一个委托标记 |
| 要不要换地址 | 要,新账户是新合约地址 | 不要,原地址原地升级 |
| 初始成本 | 要部署账户合约(可用工厂延迟到第一笔 UserOp) | 一笔带授权的交易,委托到已部署的合约,无需部署 |
| 私钥单点 | 可消除:owner 可换,旧钥匙作废 | 治不了:原私钥始终是最高权限 |
| 与现有钱包生态兼容性 | 合约地址,部分 DApp 需适配(如签名验证走 ERC-1271) | 最好:地址、资产、历史授权全部保留 |
| 适合场景 | 新用户、应用内嵌钱包、需要社交恢复与多因子 | 存量 EOA 想要批量调用、代付、限额 |
我的粗暴总结:新开户直接上 4337 合约账户;老账户想尝鲜用 7702;但只要”私钥绝对不能丢”还是你的第一诉求,终点站都是带社交恢复的合约账户。
AA vs MPC:拆钥匙片和换门锁是两码事
讲到”解决私钥单点”,你可能会想起《更加安全的区块链钱包:MPC 钱包》。MPC 和 AA 常被放在一起比,其实根本不在一个维度:
- MPC 是密码学手段:把一把钥匙拆成三片,三方各藏一片,签名时三方各算各的、凑出一个完整签名——完整私钥从头到尾没出现过。但你琢磨一下就发现:锁没换。链上看到的仍是一个普通 EOA 的普通签名,账户还是那个”笨”账户,不能批量、不能代付、不能限额。
- AA 是账户形态升级:钥匙还是一把(或者几把),但锁换成智能的了,规则写在合约里,由链上强制执行。
所以二者解决的是不同层的问题:MPC 管”钥匙怎么保管“,AA 管”门锁怎么运作“,完全可以叠加——用 MPC 保管合约账户的 owner 钥匙,钥匙层没有单点,锁上还有限额和恢复兜底。顺带一提,MPC 那篇里讲的多签钱包,本质上就是智能合约账户的老前辈。
Python 模拟
老规矩,代码说话。两段都只用标准库;为了不引第三方依赖,签名用”私钥拼消息再哈希”来模拟(真实链上是 ECDSA 验签,且链上从不保存私钥,代码里的 PRIVATE_KEYS 字典纯属模拟道具)。第一段模拟 UserOperation 的一生,第二段模拟社交恢复与 guardian 串通攻击。
模拟一:UserOperation 的一生
还是外卖那个局:Alice、Bob、Carol 各有 1000 USDC、0 ETH——搁旧门锁时代,这仨人谁也别想动账。现在每人都装了智能门锁(部署了自己的账户合约):Alice 和 Carol 想转账,勾选了会员免运费,请 Paymaster 代付;Bob 想 approve + swap 批量执行,走自费通道,用自己的预存款付 gas;另外还有个 Mallory 伪造 Alice 的签名,想浑水摸鱼下一单。
1 | # ERC-4337 UserOperation 生命周期模拟(纯标准库):UserOp -> alt mempool -> bundler |
运行结果:
1 | [bundler] Bundler-01 预检 alt mempool 中的 4 个 UserOp: |
对着外卖把几个看点串起来:
- 4 张订单进接单大厅,跑腿小哥预检时把伪造签名的那张丢了——真实世界里小哥不做赔本买卖,恶意订单根本进不了配送箱。
- 运费流对得上账:Paymaster 垫付 2 × 0.0000586 ETH,Bob 自付 0.0000575 ETH,合计 0.0001747 ETH,正好是跑腿小哥收到的报销;Paymaster 另收了 1 USDC”运费”。
- 最关键的还是那句:三个用户的 ETH 自始至终是 0,事全办成了——“用 USDC 付 gas”,”只收现金”的死规矩就这么破掉了。
- 诚实的简化说明:gas 模型和 0.5 USDC 费率是随手定的;迷你 EVM 里的 approve 和 swap 只返回描述、不真动余额(所以 Bob 的 USDC 没少 100);真实的 EntryPoint 是两个循环——先跑完所有 UserOp 的验证、再统一执行——这里为了好读合成了一个循环。
模拟二:社交恢复与 guardian 串通
换到门锁视角:Alice 的账户有 5 个 guardian(闺蜜、弟弟、旧手机备份、两家机构),阈值 3/5,宽限期 3 天。三个场景:日常转账;钥匙丢了走补钥匙流程;Mallory 串通 3 个 guardian 发起攻击——看看”只能换锁、搬不走东西”这条设计是不是真的扛得住。
1 | # 社交恢复模拟(纯标准库) |
运行结果:
1 | 账户部署完成:owner = Alice,资产 = 1000 USDC(挂在账户合约名下) |
三个场景对应三个结论:
- 场景 2:3 个 guardian 点头,把 owner 换成新钥匙,宽限期过后生效,旧钥匙连”垂死挣扎”的机会都没有——丢钥匙从”家没了”降级成”跑一趟补卡”,补完照用。
- 场景 3 前半:3 个串通的 guardian 各签一次想直接搬走 900 USDC,3/3 全被拒。guardian 的签名只对”换锁”有效,搬家通道根本不看它——保管人凑再多人,也进不了你家门。
- 场景 3 后半:他们只能改走”换锁”这条合法路径,而这会进入 3 天公开宽限期,现任 owner 一票否决,攻击失败。慢、公开、可撤销——这就是智能门锁对”串通攻击”的降维打击。
- 泼盆冷水:如果宽限期内 Alice 没看链上记录、没设提醒,3 个串通的 guardian 是真能夺走账户的。社交恢复把”钥匙丢了”从绝症治成了感冒,但没把人性变成防弹衣。
总结
把这一篇用一把锁、一份外卖收个尾:
- 账户抽象 = 把账户的验证、付费、执行逻辑从协议层挪到合约层——把”一把钥匙管一切的旧门锁”换成可编程的智能门锁;
- ERC-4337 不改协议,在应用层点了一份外卖:你写订单(UserOperation)、跑腿小哥抢单合并(Bundler)、平台核验验签(EntryPoint)、会员免运费(Paymaster)、智能门锁收货执行(Account),2023 年 3 月上线主网;
- EIP-7702 随 2025 年 5 月的 Pectra 上线:老房子不动产权证,签一条授权请来长期管家(
0xef0100 || 地址的持久委托标记,不换人就一直聘着),原地址直接获得合约能力;但原私钥仍是最高权限,私钥单点没有被根治; - 社交恢复是 AA 最杀手级的应用:guardian 只能换锁、不能搬东西,配合宽限期和否决权,把单点故障变成多人治理——钥匙丢了等于跑一趟补卡,而不是家没了;
- MPC 与 AA 正交:一个管钥匙怎么保管(拆成三片)、一个管门锁怎么运作(换智能锁),可以组合使用。
旧门锁用了十年,早就该换了。以太坊的账户升级就是一场全网的”换锁工程”,4337 和 7702 是两把不同型号的智能锁——至于装了智能锁之后还能玩出什么花样(批量、限额、无 gas、passkey),你自己就是产品经理。
相关阅读
- 《Web3 中的授权与撤销授权》:EIP-7702 在那篇只讲了授权切片,本文是全景
- 《Web3 的入口 - 区块链钱包》:EOA 与钱包的关系
- 《更加安全的区块链钱包:MPC 钱包》:密钥拆分路线 vs 账户升级路线
- 《Gas:链上一切行为的价格标签》:理解 paymaster 代付的前提是懂 gas
- 《从零开始构建区块链》:EOA/合约账户的底层是交易与合约调用