Skip to Content
dApp 接入
本页目录

签署数据

可读消息使用 personal_sign;EIP-712  结构化数据使用 eth_signTypedData_v4。连接账户后再请求签名,并在打开钱包提示前说明用户将授权的内容。

普通消息

personal_sign 的第一个参数是十六进制编码的消息,第二个参数是签名地址,返回值为签名字符串。请求签名不会提交交易,也不产生网络费用。

const provider = window.$onekey?.ethereum; if (!provider) throw new Error('OneKey Ethereum provider is unavailable.'); const [address] = await provider.request({ method: 'eth_requestAccounts' }); const message = 'Sign in to example.com. Nonce: <SERVER_GENERATED_NONCE>'; const bytes = new TextEncoder().encode(message); const data = '0x' + Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join(''); try { const signature = await provider.request({ method: 'personal_sign', params: [data, address], }); // Verify the signature and one-time challenge on your server. console.log(signature); } catch (error) { console.error(error.code, error.message); }

用于登录时,请将占位值替换为服务器生成的一次性挑战,并验证目标域名、过期时间和签名者。不能仅凭“存在签名”就认定身份验证成功。

结构化数据 v4

以 [address, JSON.stringify(typedData)] 调用 eth_signTypedData_v4。typedData 对象包含 types、primaryType、domain 和 message,每个消息字段必须符合其声明的类型。

Domain 字段用途
name便于阅读的应用或协议名称
version签名域版本
chainId签名所针对的链
verifyingContract验证签名的合约地址;它是地址,不是 URL
salt协议需要时使用的可选域分隔值

域分隔有助于区分签名上下文。验证签名的应用或合约仍需校验 domain,并实现自己的重放保护;EIP-712 本身不提供重放保护。

// `typedData` must be built from your protocol's complete EIP-712 schema. const signature = await provider.request({ method: 'eth_signTypedData_v4', params: [address, JSON.stringify(typedData)], });

旧版签名方法

已有集成可能使用 eth_signTypedData 或 eth_signTypedData_v3,其编码与 v4 不同。更换 RPC 方法时,也必须调整并测试验证端。RPC 方法名称包含 eth_ 前缀。

应用登录应避免使用 eth_sign。它签署的是不透明数据,用户难以核实真实意图。方法支持情况可能因账户类型、硬件型号、固件和钱包版本而异;请处理不支持方法的错误,不要假定所有已连接账户都能签署所有格式。

示例

打开示例 

最后更新于