Ethers.js 签名方法总结
在 ethers.js 里,常见的签名方式主要有三类,取决于你要签的数据类型:
1. 签消息(Message Signing)
- 方法:
wallet.signMessage(message) - 标准:EIP-191
- 特点:
- 会在消息前加上
"Ethereum Signed Message: "前缀再签名。 - 通常用于证明“某人控制了某个地址”,而不是上链执行交易。
- 会在消息前加上
- 用途:
- 登录验证(Web3 登录)
- 签署非结构化数据
- 示例:
const wallet = new ethers.Wallet(privateKey); const signature = await wallet.signMessage("hello world");
2. 签交易(Transaction Signing)
- 方法:
wallet.signTransaction(tx) - 特点:
- 需要构造交易对象(to, value, gasLimit, nonce, data 等)。
- 返回序列化的原始交易(rawTx),可通过
provider.sendTransaction()广播到链上。
- 用途:
- 转账
- 合约调用
- 示例:
const tx = { to: "0xabc...", value: ethers.utils.parseEther("0.01"), gasLimit: 21000, nonce: 0, chainId: 1, }; const signedTx = await wallet.signTransaction(tx);
3. 签结构化数据(Typed Data / EIP-712 签名)
- 方法:
signer._signTypedData(domain, types, value)(推荐)- 或底层调用
eth_signTypedData_v4
- 标准:EIP-712
- 特点:
- 对结构化数据(JSON schema)进行签名。
- 可验证具体字段,不像
signMessage那样是纯字符串。
- 用途:
- DeFi、NFT 协议里常见(Permit、MetaTx、Off-chain 授权)。
- 示例:
const domain = { name: "MyApp", version: "1", chainId: 1, verifyingContract: "0xabc...", }; const types = { Person: [ { name: "name", type: "string" }, { name: "wallet", type: "address" }, ], }; const value = { name: "Alice", wallet: "0xabc...", }; const signature = await wallet._signTypedData(domain, types, value);
总结
- 签消息 →
signMessage(EIP-191) - 签交易 →
signTransaction - 签结构化数据 →
_signTypedData(EIP-712)