Appearance
L2-3: Social Recovery(社交恢复钱包) #
1. 问题 #
创建智能合约钱包,支持社交恢复:当 owner 丢失私钥时,一组预先指定的「守护人」可以通过全票同意来更换 owner。
2. 原因 #
传统 EOA 钱包的最大风险:私钥丢失 = 资产永久丢失。
社交恢复通过信任一组「守护人」(朋友、家人、机构)来解决:
- 正常情况下:owner 控制一切
- 丢失私钥时:联系守护人投票更换 owner
- 恢复条件:所有守护人同意
Vitalik 曾多次推崇社交恢复钱包作为改善用户体验的关键技术。
3. 方案 #
架构 #
owner ── 正常操作 ──→ call(任意合约, ETH, calldata)
guardians ── 全票通过 ──→ signalNewOwner(newOwner) → 自动执行恢复
owner ── 管理守护人 ──→ addGuardian / removeGuardian
核心机制 #
signalNewOwner(_proposedOwner):每个守护人只能对同一个 proposedOwner 投票一次- 当
signalCount == guardianCount:自动更换 owner - 对不同 proposedOwner 的信号分开追踪
4. 遇到的陷阱 #
4.1 全票 vs 多数票的权衡 #
本关采用全票(所有守护人),这意味着:
- 任一守护人可以单方面阻止恢复
- 如果守护人也丢失了密钥 → 无法恢复
4.2 守护人集合变更影响 #
如果 owner 在恢复过程中增删守护人,guardianCount 的变化可能:
- 增加守护人:原先的全票不再是全票
- 减少守护人:部分投票即可提前触发恢复
4.3 多候选人的信号追踪 #
守护人 A 投票给 proposedOwner1,守护人 B 投票给 proposedOwner2 —— 两者的 signalCount 分开计算,互不影响。
5. 陷阱的原因 #
5.1 #
全票是安全性和活性之间的权衡。全票偏向安全(需要全部同意),多数票偏向活性(不会因一两个失联守护人而恢复不了)。
5.2 #
这是设计选择:本关要求全票,且不包含时间锁。工业级实现(如 Argent、Safe)通常使用多数票(如 3/5)+ 时间锁。
5.3 #
signalNewOwner 中 signalCount 按 _proposedOwner 维度独立追踪:
solidity
mapping(address => mapping(address => bool)) public hasSignaled; // proposedOwner → guardian → signaled
mapping(address => uint256) public signalCount; // proposedOwner → count
6. 如何解决陷阱 #
- 在生产中使用多数票(如 N-of-M)+ 时间锁 + 取消机制
- 守护人选择:可信 + 技术支持能力 + 地理分布
- owner 变更后,考虑清理旧信号(本关简化未实现)
7. 技术要点 #
| 要点 | 说明 |
|---|---|
| 社交恢复模式 | 守护人全票更换 owner |
| 智能钱包抽象 | call 函数执行任意链上操作 |
| 全票机制 | signalCount == guardianCount 自动触发 |
| 守护人管理 | owner 可增删守护人 |
| 与 Safe/Argent 对比 | 工业级用 M-of-N + 时间锁 |