
在 SSP 中撤销代币授权
每当你在 EVM 链上确认一笔 swap、存款或 NFT 挂单时,你都在授予 dApp 替你转移特定 ERC-20 代币的权限。这些权限——称为授权或 allowance——在交易结算之后仍会留在 on-chain。几个月后,你在三月信任过的合约,到了六月可能仍然有权把那枚代币掏空。解决办法很直接:撤销你不再需要的授权。本指南演示如何从 SSP 完成这件事——SSP 是一个 self-custodial 的 2-of-2 wallet,任何一笔交易(包括撤销)都需要 SSP Key 联合签名。
如果你对这个概念还陌生,先阅读 代币授权:你一直在发放的许可。那里讲清楚了为什么需要授权,以及为什么无限 allowance 是 DeFi 中默认的攻击面。本文是它的清理篇。
简短回顾
当你签名一笔 approve(spender, amount) 调用时,代币合约会记录:spender(通常是路由、vault 或 marketplace 合约)被允许从你的地址转出至多 amount 的该代币。许多 dApp 会请求 2^256 - 1——实际上等同于无限——以便在以后的交互中替你省 gas。这种便利同时也是风险:如果 spender 合约日后被攻陷,或者你不再使用该 dApp 但 allowance 还挂着,攻击者可以在任何时候掏空你的全部余额。
撤销会把这一授权撤回。它并不撤回过去发生的转账,也不会"删除"任何内容,只是把 allowance 重新置零。
撤销的底层机制
一次撤销不过是一笔普通交易。你在原本授予授权的同一条链上、同一份代币合约上调用 approve(spender, 0)。这一次函数调用,会把合约内 allowance[owner][spender] 映射写入一个新的 0,覆盖原来的数字。
几个需要内化的机制要点:
- 每条链、每个 token-spender 对要撤销一次。 如果你在 Ethereum 上授权过一个 USDC 的 spender,又在 Polygon 上授权过同一个 spender,那就需要两笔撤销交易——每条链各一笔。Allowance 并不会跨链共享。
- 撤销是一笔独立交易。 它和任何转账一样要消耗 gas。请预先准备:在对应链上准备好原生资产(Ethereum 上是 ETH,Polygon 上是 MATIC,等等)用于支付手续费。
- 可能比你担心的便宜。 撤销只是一次简单的写入,通常比一次 swap 还便宜。在 Base 这类 Layer 2 上往往只有几分钱。
- SSP 仍然需要联合签名。 因为 SSP 是 2-of-2 wallet,撤销交易走的还是和任何其他交易一样的流程:由 extension 发起,SSP Key 审核并联签。你的保护机制延伸到清理动作本身——单一设备无法单独撤销,也无法被诱骗去"批准一个伪装成撤销的请求"。
撤销的两条路径
从 SSP 撤销授权有两种同样合法的方式。挑符合当下情况的那一种即可。
路径 1:使用可信的区块浏览器
这是手动且透明的路线。当你确切知道要撤销哪个代币、哪个 spender,或者不想连接第三方工具时,它很合适。
- 在合适的浏览器上打开该代币的合约页:
- Ethereum: etherscan.io
- Polygon:polygonscan.com
- Base:basescan.org
- BNB Smart Chain:bscscan.com
- Avalanche:snowtrace.io
- 进入 Contract 标签,再点 Write Contract(若该代币是 proxy 合约——大多数主流稳定币都是——则点 Write as Proxy)。
- 找到
approve函数。它的两个输入是spender(你要撤销的地址)与amount(新的 allowance)。 - 把
amount设为0。粘贴 spender 地址——从你以前的交易历史里复制,绝不要凭记忆敲。 - 连接你的 wallet。大多数浏览器都支持 WalletConnect,这是连接 SSP 的推荐方式。在 extension 里确认连接请求。
- 点击 Write。浏览器构造
approve(spender, 0)交易并把它递交给 SSP。SSP 的 extension 显示调用细节;SSP Key 联签;撤销被广播。
这条路啰嗦,但你签下了什么完全没有任何模糊空间。
路径 2:使用专门的撤销工具
对大多数用户而言这是更实用的选择。revoke.cash 是这件事广泛使用的开源工具。它会跨所支持的各条链扫描你的地址,列出每一笔仍在生效的 allowance,标记其中风险较高的(无限金额、陌生合约),并允许你通过已连接的 wallet——单笔或批量——撤销它们。
流程:
- 在浏览器中直接打开
revoke.cash。把真实域名加入收藏夹,并且只通过这个收藏入口访问。撤销工具的钓鱼仿冒站之所以存在,正是因为用户来到那里时已经做好了签交易的准备。 - 通过 WalletConnect 连接,然后用 SSP 扫码或粘贴 URI。
- 把链选择器切换到你想审计的那条链。revoke.cash 会拉取你在那条链上的授权。
- 浏览列表。每一行显示代币、spender、allowance 数额,以及(通常)一个 dApp 标签。
- 对任何你不再使用的项点击 Revoke。每一次撤销都是一笔独立的
approve(spender, 0)交易,由 SSP 联签。
一份实用的审计流程
每年抽出 20 分钟一两次,按这个清单走一遍:
- 通过 WalletConnect 把 SSP 连接到 revoke.cash。
- 审查你在每条用过的链上的活跃授权。先从 Ethereum 开始——历史上授权关系图最密集的就是它——然后依次走 Polygon、Base、BNB Smart Chain 和 Avalanche。
- 优先处理风险最高的项。按无限 allowance 和不认识的 dApp 名字排序或扫一眼。一个你在 2024 年用过一次 swap、之后再没碰过的协议就是首选目标。任何你完全认不出来的合约也是。
- 撤销。在 SSP extension 里确认该交易;SSP Key 提示你联签;撤销被广播。
- 在 SSP Key 上联签。这是再次核对目标的时机。SSP Key 会显示你正在调用的合约和函数——确认两者都与你的本意一致。
- 每条链都重复一次。Allowance 是按链分别存储的。不要假定 Ethereum 上的一次撤销会顺带清理 Polygon。
你不需要把一切都清空。目标是让那些你仍在主动使用的合约保留 allowance,把其余的归零。
注意事项
- 域名卫生。只使用官方域名
revoke.cash。仿冒钓鱼站恰恰瞄准了这一场景,因为用户此时本来就处在签署交易的状态。先收藏;连接前先核对地址栏。 - 逐链的事实。在 Ethereum 上撤销 USDC 的授权,并不会影响 Polygon 上的 USDC 授权——尽管在你的投资组合里它们看起来"像同一个代币"。一定要按链逐条走过来。
- gas 预算。撤销要付 gas。在 Ethereum 上,一批积攒下来的撤销可能加起来不便宜;趁 gas 安静时做。在 Layer 2 上成本几乎可以忽略。
- 永远要核对 spender。在签下任何"撤销"交易之前,确认调用里的 spender 地址,与你打算撤销的那个合约一致。恶意站点完全可能展示一个假的撤销 UI,实际上却在向攻击者发出一笔新的授权。在 SSP Key 的提示上读出函数名(
approve)和金额(0),就是你最后的防线。 - permit 是另一回事。一些代币(USDC、DAI 的若干变体)支持
permit——一种作为授权使用的 off-chain 签名。revoke.cash 会尽量列出它能识别的 permit 类授权;对于你认不出来的任何项,按你对待 on-chain allowance 的方式来对待它。
清理阶段的 2-of-2 优势
这是经常被忽略的一点:在 SSP 中撤销并不是单一设备上的一次点击。你的 extension 起草了撤销,但它不能独自广播。SSP Key 必须联签,而那一步联签正是你检视"实际要被提交的是什么"的时机。如果你的 extension 哪一天被攻陷,试图提交一笔伪装成"撤销"的恶意交易——其实是一笔新的授权——SSP Key 会在自己的屏幕上显示真正的函数和真正的金额。两台设备,两次发现问题的机会。
定期做一次授权卫生,是大多数用户绕开的、在 DeFi 中杠杆最高的一项习惯。在日历里设一个提醒,做完审计,睡得更安稳。也欢迎继续阅读这个系列——如果你想把链特定的细节稳住,从 SSP 中的 Ethereum 开始;或回头看 代币授权:你一直在发放的许可,提醒自己这件事为什么重要。


