如何通过Web3与Metamask实现简单的数据签名
Metamask + Web3 简易数据签名实现方案
前置前提:你已经完成Metamask连接,已获取的用户地址存放在
userAddress变量中,以下示例无需额外依赖即可运行。
方案1:普通字符串签名(最快上手,适合测试)
直接用personal_sign方法,几行代码即可完成,调用后会自动触发Metamask签名弹窗:
- 直接调用Metamask注入对象的实现(无需引入Web3依赖):
const rawMessage = "测试签名内容"; // 字符串转十六进制避免特殊字符解析问题 const hexMessage = `0x${Buffer.from(rawMessage, "utf8").toString("hex")}`; const signature = await window.ethereum.request({ method: "personal_sign", params: [hexMessage, userAddress] }); console.log("签名结果:", signature);
- 基于Web3实例的实现:
const rawMessage = "测试签名内容"; const signature = await web3.eth.personal.sign(rawMessage, userAddress); console.log("签名结果:", signature);
拿到签名后你可以直接用熟悉的ecrecover方法恢复地址,和userAddress比对即可完成验签。
方案2:EIP-712结构化数据签名(适合正式场景)
如果需要用户在签名弹窗中清晰看到待签名的结构化内容,可以用eth_signTypedData_v4方法,也是Metamask当前原生支持的标准签名方法:
// 链信息配置 const domain = { name: "你的测试DApp名称", version: "1.0", chainId: await web3.eth.getChainId(), verifyingContract: "0x0000000000000000000000000000000000000000" // 无验证合约可直接填零地址 }; // 结构化数据类型定义 const types = { SignContent: [ { name: "内容", type: "string" }, { name: "时间戳", type: "uint256" } ] }; // 实际待签名数据 const value = { 内容: "测试结构化签名", 时间戳: Date.now() }; const signature = await window.ethereum.request({ method: "eth_signTypedData_v4", params: [userAddress, JSON.stringify({domain, types, value})] }); console.log("结构化签名结果:", signature);
以上两种方法均为Metamask当前最新支持的签名方案,不存在过时问题,测试场景直接复制方案1的代码即可快速跑通。
内容的提问来源于stack exchange,提问作者Zachary Baker
相关产品推荐
相关产品推荐

