
图片资料:官方来源
在支持“使用以太坊登录”(Sign-In with Ethereum,SIWE,对应 ERC-4361)的站点上,钱包会弹出以纯文本形式呈现的登录消息,末尾是签名按钮。这段消息签名与 ERC-20 的 approve 交易不同:登录签名证明地址控制方同意建立会话,不会移动代币,也不会授予代币花费额度。不过,钱包中外观相似的其他签名请求可能带来资金风险,因此核对字段仍是必要动作。
登录签名与approve的区别
SIWE 消息由请求方生成,按 ERC-191 前缀构造,再由钱包签名,服务端负责校验签名和消息内容。它要回答的是“这个地址是否同意以某身份登录某站点”。approve 是链上交易,调用代币合约修改授权额度。前者是链下消息签名,后者是链上状态变更。钱包界面可能都只显示一段文本或一个确认按钮,仅凭外观无法判断性质。
另外,执行登录签名的账户不限于由私钥直接控制的普通账户(EOA)。合约账户也能按 ERC-1271 验证签名,此时验证结果取决于所绑定链上的合约状态,而不是某个私钥持有者。
必填与可选字段
按 ERC-4361 的消息格式,必填字段有 domain、address、uri、version、chain-id、nonce、issued-at;scheme、statement、expiration-time、not-before、request-id、resources 为可选。核对字段时,先看与请求来源相关的几项:
- domain:发起签名请求的站点,取值是 RFC 3986 的 authority,可以带端口。消息中写的域名与钱包实际读到的请求来源不一致时,应停止签名。
- uri:签名所针对的资源标识,通常是站点的登录页地址,但不必然如此。它说明这次登录要访问哪个资源,而不是域名一致性的自动证明;domain 与 URI 属于不同字段,各有各的预期值。
- chain-id:会话绑定的 EIP-155 链号。合约账户的签名验证要在该链上解析,链号写错会导致验证失败或落到错误的网络。
- address:执行签名的地址,应与钱包当前选中的账户一致。
- nonce:至少 8 位字母数字,由请求方生成,用于防重放。
- issued-at:消息生成时间,RFC 3339 格式。expiration-time 若存在,应确认签名时尚未过期。
nonce的防重放依赖服务端
常见误解是“消息里有 nonce 就不会被重放”。nonce 能否防重放,取决于服务端是否把它与自己签发的那次请求绑定,并在使用后作废或限制有效期。若服务端只检查 nonce 格式、不检查来源,或允许同一 nonce 反复使用,防重放就失效。这属于服务端实现,钱包端无法替你保证。看到 nonce 只说明消息格式合规,不说明站点校验到位。
钱包端与站点端各自核对什么
钱包端应核对请求来源与消息中的 scheme、domain 是否匹配,防止页面冒充其他站点发起登录。站点端则应校验消息格式、nonce、过期时间、URI 是否符合预期,并把会话绑定到签名地址,而不是绑定到 ENS 这类可变更的解析结果。两端各管一段:钱包管“请求从哪来”,站点管“凭证是否一次性、是否过期”。
一个假设算例
假设你在 https://app.example.org 看到登录请求,消息首行为 app.example.org wants you to sign in with your Ethereum account:,地址为 0x…,Chain ID: 1,Nonce: 32891756,Issued At: 2026-11-02T08:00:00Z,Expiration Time: 2026-11-02T08:05:00Z。以上时间均为 UTC。核对时:域名与站点一致;链号为 1,会话按以太坊主网解析;nonce 长度合规;你在 08:06(UTC)才确认签名,已超过过期时间,服务端应拒绝。若域名变成 app.example.org.evil.test,即使其余字段完全一致,也应停止签名。
什么时候该停下
签名被拒时,先看 domain 与当前页面是否一致,再看 chain-id 是否为你实际使用的网络,然后确认 nonce 是否已被使用或消息是否已过期。若站点提示“签名无效”,可能是消息不符合 ABNF 格式,也可能是合约账户的 ERC-1271 验证所依赖的链上状态已变化。签登录不等于转账,但外观相似的其他签名可能危险;不签自己看不懂内容的消息,比记住字段清单更基本。