为什么我在 dApp 里每一次签名都要小心?

钱包 · 2026-05-30 · 比特三棱镜编辑部
AI 搜索

老玩家圈里有句被反复说过的话——“签名比转账更危险”。新手听到这句话往往不理解:转账实打实扣资产,签名只是按下一个按钮、没花一分钱 Gas,怎么会更危险?答案在于"签名"在 Web3 里不是"我同意一下"这么简单的动作,它可能授予一份永久且无限的资产支配权。这一篇试着把每一次签名背后到底发生了什么讲清楚,让你看到一个签名窗口的时候,心里有一份明确的风险地图

dApp 签名风险示意

先讲清楚"签名"到底是什么

钱包里的签名分两大类,混在一起谈是初学者最容易出问题的地方。

第一类是交易签名(transaction signature)——你发起一笔会改变链上状态的交易(转账、swap、mint、stake),需要私钥对交易数据签名,然后广播到链上,矿工/验证者打包确认。这种签名必须花 Gas,因为它要真正写入区块。

第二类是消息签名(message signature)——你对一段任意数据用私钥签名,不广播、不写入链上、不花 Gas。这种签名经常被 dApp 用来证明"你确实控制这个地址"——例如登录时让你签一条 “Sign in to …” 的消息。但这种签名也可以承载授权语义,让你在不知情的情况下批准了一份永久的资产支配权。

最关键的认知是——消息签名没有 Gas 不代表它没有后果。它可以被对方拿去链上调用某些合约函数,把你的资产直接转走。详细原理可以补 钱包入门

签名的几种类型与各自的风险等级

按风险等级排开,常见的签名类型大致是这几类:

  • personal_sign / eth_sign 简单消息签名——风险中等。如果你看到一段明显是 “Sign in to MyDApp” 的人类可读消息,风险较低;但如果消息内容是一串乱码或十六进制,那很可能是一笔伪装成消息的交易,风险极高。
  • EIP-712 结构化签名——风险取决于结构内容。EIP-712 的好处是钱包可以把字段名称展示出来,让你看到这是一份"授权 100 USDC 给地址 0x…“而不是乱码;但很多新型钓鱼就是利用 EIP-712 字段名设计得很像"登录”,实际却是 permit 授权。
  • permit 签名(ERC-2612 / Permit2)——风险极高。这种签名直接授权对方在指定时间内动用你的指定代币,不需要你额外花 Gas 就完成了授权,是 2024–2025 年钓鱼大幅增加的主要载体。
  • approve / setApprovalForAll 交易签名——风险高。这是经典的"无限授权"载体,签了就意味着对方合约可以在以后任意时间转走你这种代币(或这个 NFT collection 里所有 NFT)。

dApp 签名风险示意

为什么"无 Gas 签名"反而最危险

普通用户的直觉是"花 Gas 的才是真交易",但在 permit 签名出现之后这条直觉刚好倒过来。permit 签名的设计初衷是为了让用户体验更顺——你不用先付一笔 Gas 做 approve,再付一笔 Gas 做 swap,而是直接签一个消息,前端把这个签名连同 swap 交易一起发出去,省一笔 Gas。

但攻击者利用了这个特性——他们设计一个看起来像普通登录或者授权的 EIP-712 弹窗,实际背后是一份给攻击者地址的 permit 授权。一旦你签了,攻击者拿着这份签名直接去链上调用 permit 函数,再调用 transferFrom 把你的代币转走。整个过程你没有花任何 Gas,没有触发任何"转账确认",但资产已经离开你的钱包。

这就是"无 Gas 签名最危险"的底层逻辑。具体钓鱼手法和防御实战可以读 MetaMask 钓鱼防御

签名前的自检清单

不论是哪种签名类型,签之前都应该走完一份自检清单。这套清单的核心是:不让你"凭感觉"签

  • 看域名——签名弹窗里的来源是不是你认识的 dApp 域名?是不是有相近字符的钓鱼仿冒(“unisawp.org” “metarnask.io”)?
  • 看请求类型——是 transaction、personal_sign、eth_signTypedData_v4 中的哪一种?后两种要特别警惕。
  • 看签名内容——如果是 EIP-712,钱包会展示结构字段。字段里是不是出现了 spender / approve / permit / value 这些关键词? 出现就要怀疑是授权类签名。
  • 看代币地址和数量——如果出现 token 地址或者 value 字段,确认这个 token 是你愿意授权的、数量是合理的(无穷大 / uint256.max 极其危险)。
  • 看对手方地址——授权对象是合约还是 EOA 地址?合约要查清楚是不是合法协议地址;EOA 地址(特别是没有 ENS 没有标签的随机地址)几乎一定是钓鱼。
  • 拒不熟悉就拒签——这是最后一道防线。不熟悉就关掉签名窗口、不熟悉就关掉签名窗口、不熟悉就关掉签名窗口

配合"权限管理"工具一起用

光靠"签名前自检"不够,还要定期给钱包做"授权清理"。手里挂着几十个长期 approve 的钱包,等于把钥匙撒在地上

可以做这几件事:

  • 定期用 revoke.cash / etherscan 的 Token Approvals 页面清理掉不再使用的 approve 授权。
  • 大额持仓和日常交互分开钱包——主钱包不连任何 dApp,只用日常钱包参与 DeFi,一旦签名出问题损失被隔离。
  • 使用支持 simulation 的钱包前端——Rabby、Frame 等新一代钱包会在签名前模拟执行并显示实际效果,相关对比可以读 Rabby vs MetaMask 对比
  • 大额操作用硬件钱包签——硬件钱包屏幕会独立显示签名内容,避免被中间人改写。硬件钱包风险讨论可以补 硬件钱包供应链风险

dApp 签名风险示意

几个真实场景演练

把以上原则套到几个常见场景里。

场景一:你点了一个空投网站,它弹出一个 “Sign to claim airdrop” 消息。打开签名内容看:如果是 personal_sign 一行 “Claim airdrop for 0x…” 的可读消息,且这个网站是你确认过的官方域名,风险较低;如果是 EIP-712 结构化签名里出现 spender / permit 字段,立刻关掉——这是典型的空投钓鱼。空投参与策略可以补 空投资格策略

场景二:你在 Uniswap 上做 swap,弹出一个 Permit2 签名。这是正常流程,因为 Uniswap 的 Permit2 是真实的代币授权机制。但要看清楚:spender 是 Uniswap 的 Permit2 合约地址(可以在 Uniswap 文档里查到),value 不要是 uint256 最大值,到期时间最好不要太长。读 Uniswap 入门 了解协议背景。

场景三:朋友发来一个"高收益 farming"的链接,连上钱包让你签一份 setApprovalForAll直接关掉。setApprovalForAll 让对方合约可以转走你这种 NFT collection 里所有 NFT,是 NFT 钓鱼的经典载体。

把签名当成签合同看

把所有内容压缩成一条心法——在 dApp 里点签名按钮,等价于在现实里签一份你没读过的合同。现实中你不会乱签合同,链上也不能乱签签名。"无 Gas"和"消息"两个标签让很多用户放松警惕,但这恰恰是攻击者最希望看到的状态。每次看到签名弹窗,把上面那份自检清单在脑子里过一遍,慢三秒再决定签或不签——多出来这三秒在大多数时候不会让你错失什么,但有一天它会替你挡掉一次足以清空钱包的损失。本文不构成投资建议或资产保管建议。