Skip to content
On this page

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 + 时间锁

Built with AiAda