本页目录
签署数据
可读消息使用 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。它签署的是不透明数据,用户难以核实真实意图。方法支持情况可能因账户类型、硬件型号、固件和钱包版本而异;请处理不支持方法的错误,不要假定所有已连接账户都能签署所有格式。
示例
最后更新于