01钱包弹窗里其实有两类请求
一类是转账,你签完之后资产立刻离开你的地址;另一类是授权,你签完之后资产没有动,但你把「可以动它」的权限交给了某个合约。后者更危险,因为当下什么都没发生。
差别在于,转账的后果是即时可见的:余额少了,你知道自己做了什么。授权的后果是延迟的:今天签了,可能几周之后才被用掉,而那时候你早忘了自己签过什么。
还有第三种情况介于两者之间:一段纯粹的消息签名。它常用于「证明这个地址是你的」,通常无害——但也有被滥用的形式,第 04 节会讲。
三类请求在钱包里长什么样
各家钱包的措辞不同,但这三类请求在界面上有比较稳定的特征,认这些特征比认按钮文案可靠:
| 类型 | 界面上通常会出现 | 要不要付费用 | 后果什么时候发生 |
|---|---|---|---|
| 转账 | 收款地址 + 数量 + 预估网络费用 | 要 | 立刻,余额马上变化 |
| 授权 | 代币名称 + 额度 + 被授权的合约地址 | 要 | 以后,可能几个月后 |
| 消息签名 | 一段文本或结构化数据,没有费用估算 | 不要 | 看内容,可能等同授权 |
最需要留神的是最后一行:因为它不显示费用,看起来最人畜无害,而它恰恰是目前欺骗性最强的一种。
02授权到底是什么意思
代币合约里有一个记录,写着「地址 A 允许合约 B 动用最多多少数量的代币」。你签一次授权,就是往这个记录里写一条。之后合约 B 可以在不再打扰你的情况下,按额度把币划走。这个 approve / allowance 机制是代币标准 EIP-20 规定的。
为什么要有这个机制?因为链上兑换、质押这类操作需要合约代你转移代币。如果每一次都要你重新确认,体验会很糟。所以设计成一次授权、多次使用。
问题是这个便利有代价:
- 授权不会自动过期。你去年为了一次兑换签的授权,今年仍然有效。
- 合约本身可能后来被攻破。今天安全的合约,不代表永远安全,而你的授权还挂在那里。
- 你几乎不会主动去检查。没有任何界面会提醒你「你目前给出了 37 个授权」。
所以定期清理是必要的,怎么查、怎么撤写在 怎么查和撤销已有的授权。
03无限额度授权是什么
授权时可以指定额度。很多应用默认申请一个极大的数值,实际效果就是「这个合约可以动用你这个代币的全部余额,包括你以后才转进来的」。
为什么它们要这么做?因为这样用户只需要授权一次,之后再多的操作都不用重新签。从产品体验角度是合理的,从风险角度是把上限打开了。
实际差别是这样:
| 限额授权 | 无限额度授权 | |
|---|---|---|
| 能动多少 | 只能动你指定的那个数 | 全部余额,含以后转入的 |
| 用完之后 | 额度耗尽,需要重新授权 | 一直有效 |
| 体验 | 要多签几次 | 一次搞定 |
| 合约出事时 | 损失被限制在额度内 | 该代币可能被全部转走 |
把额度改小会不会导致操作失败
这是很多人不敢动那一栏的原因。实际情况是:只要额度不小于这次操作真正需要的数量,就不会失败。多数钱包在弹窗里会显示这次操作涉及的数量,把额度设成那个数或略高一点即可。
会遇到的两个小麻烦是:
- 额度用完之后,下次操作要重新授权一次,也就是多花一笔网络费用。
- 有些应用的界面没有提供改额度的入口,只能在钱包这一侧改。
值不值得为此多花几次费用,取决于那个代币在你手上有多少。余额越大,限额的性价比越高——因为无限额度授权的潜在损失是按余额算的,而多付的费用是固定的。
多数钱包允许你在授权弹窗里手动改额度。对不熟悉的应用,改成这次操作真正需要的数量;对你长期使用、且规模较大的成熟应用,用无限额度换体验是一个可以接受的选择,但要把它记进你的定期检查清单。
04「不花 Gas 的签名没有风险」——这句话是错的
不花 Gas 只说明这个签名当时没有上链,不说明它没有效力。有一类离线签名可以被对方拿去链上使用,效果等同于你亲自授权转移资产。
这是目前最有欺骗性的一种手法,原因就在于用户已经被教育成「弹窗里显示要花钱的才要小心」。而这类请求恰恰不显示费用,看起来无害得多。
它的原理是:某些标准允许你用私钥签一段结构化的数据,这段数据本身描述了一个授权或者一笔资产转移。签名做完之后,拿到它的人可以在任意时刻把它提交上链并支付费用。费用他们出,被划走的资产是你的。
不要按「花不花钱」来判断风险。要按「这段内容授予了什么」来判断。看不懂那段内容写的是什么,就不要签——这个判断可以直接迁移到你遇到的每一个弹窗。
05常见的几种恶意签名场景
它们的共同点是给你一个「必须现在点确认」的理由:领空投、验证钱包、解锁资格、参加活动。真正的目的都是拿到一个授权。
- 假空投领取页。页面显示你有一笔奖励待领,点「领取」实际弹出的是授权请求。
- 「验证钱包所有权」。正常的所有权验证只需要一段普通消息签名,不涉及任何资产权限。如果弹窗里出现了代币名称和额度,那就不是验证。
- 仿冒的知名应用页面。界面和真站一模一样,域名差一两个字符,合约地址是攻击者的。
- 「你的资产有风险,请立即迁移」。用恐慌驱动你快速点确认。
- 批量授权。一次弹窗里包含多个代币的权限,你只看了第一个。
这些场景怎么找上门、以及其他不涉及签名的被盗路径,写在 钱包被盗通常是怎么发生的。
一个真实存在的判断难点
上面那些例子读起来都很好识别,但现实里有一个灰色地带:正规的、你确实想用的应用,也会请求无限额度授权。这时候「请求无限额度 = 骗局」这条简单规则就失效了,你不能靠它做判断。
能用的替代判断有三条:
- 我是怎么到这个页面的?自己从收藏夹或手动输入域名进来的,比从一条链接点进来的可信得多。绝大多数仿冒站要靠一条链接才能把你带过去。
- 这个请求和我正在做的事对得上吗?我在做兑换,它请求兑换用的那个代币的权限,对得上;我只是在浏览,它却弹出授权,对不上。
- 那个合约地址是不是官方公布的那个?这是最硬的一条,下一节讲怎么核对。
三条都成立时,给一个正规应用无限额度是一个可以接受的取舍——前提是你把它记进定期检查的清单,而不是给完就忘。
06点确认之前,具体看什么
看四样:这是转账还是授权、涉及哪个代币、额度是多少、对方合约地址是不是你预期的那个。四样里有任何一样看不明白,就关掉弹窗。
- 请求类型。钱包一般会在弹窗顶部标明。写着「授权」「approve」「permit」一类的,就是在给权限。
- 代币和额度。额度那一栏如果是一个大得离谱的数字或者写着「无限」,先改小。
- 交互对象。那个合约地址是不是你正在使用的应用的官方地址。这一条要花点力气核对,但它能挡住仿冒站。
- 你自己在干什么。如果你只是在浏览,或者只是想连接钱包看看,却弹出了授权请求,那本身就是异常信号。
合约地址怎么核对
这一步听起来很技术,实际操作只有三下:
- 从钱包弹窗里复制那个交互对象的地址。
- 去应用的官方文档或官方社交账号找它公布的合约地址。
- 逐字比对,特别是中间那一段——伪造的地址常常刻意做成首尾相似。
如果找不到官方公布的地址,那本身就是一个信号:一个正经的应用会把自己的合约地址写在明处,因为这是它的用户核对身份的唯一方式。
顺带一提,你也可以把那个地址贴到区块浏览器上看看:它是什么时候部署的、有多少人跟它交互过。一个昨天才部署、只有几笔交互的合约,出现在一个自称知名应用的页面上,结论很清楚。
逐个判断很累,而且总有判断失误的一天。所以更有效的做法是把资产分开:用一个只放小额的钱包去连接各种网站,主要资产放在另一个从不连接任何站点的钱包里。这样一次判断失误的损失是有上限的。用途分离的做法写在 创建钱包那一篇。