如何使用 EIP-712 签名
介绍EIP-712
EIP-712,即“带有类型结构化数据的哈希与签名”,是以太坊改进提案中的一个标准。 它提供了一种标准化的方法来签署结构化数据,使得签名过程更安全且用户友好。
EIP-712 签名的关键组成部分
- EIP712域: 每个 EIP-712 签名都必须包含一个 EIP712域部分。 该部分包含有关合约和环境的重要信息。
EIP712Domain: [
{ name: "name", type: "string" },
{ name: "version", type: "string" },
{ name: "chainId", type: "uint256" },
{ name: "verifyingContract", type: "address" },
];
这些信息会在签名过程中显示,并确保签名只能通过特定链上的特定合约进行验证。
- 域对象: 在你的签名脚本中,需要提供域信息:
const domain = {
name: "EIP712Voting",
version: "1",
chainId: 71, // Conflux eSpace testnet
verifyingContract: "0xDD1184EeC78eD419d948887B8793E64a62f13895",
};
- 自定义类型: 你需要定义与合约结构相匹配的自定义类型:
const types = {
Vote: [
{ name: "voter", type: "address" },
{ name: "proposal", type: "uint256" },
{ name: "nonce", type: "uint256" },
],
};
- 消息: 创建一个包含要签名数据的消息对象:
const value = {
voter: await signer.getAddress(),
proposal: 1, // Voting for proposal 1
nonce: await contract.nonces(signer.address),
};
- 签名过程: 使用钱包的
signTypedData()
方法来创建签名:
const signature = await signer.signTypedData(domain, types, value);
EIP-712的优点
- 提高可读性: 用户可以清楚地看到他们在签署什么,减少了恶意交易的风险
- 增强安全性:结构化格式有助于防止某些类型的钓鱼攻击。
- 更好的用户体验: 钱包和 dApp 可以显示更有意义的签名请求。
- 跨平台一致性:确保在不同的以太坊兼容平台上行为一致。
在本教程中,我们将使用 Hardhat 在 Conflux eSpace 网络上实现 EIP-712 签名,并创建一个简单的投票系统来演示其用法。 我们的投票系统将允许用户在链下签署他们的投票并将其提交到区块链,从而确保隐私和效率。