生成并验证类型结构化数据签名(EIP-712签名)

2022-04-11 13:41:24 浏览数 (1)

本文作者:影无双[1]

我花了太多时间来弄清楚如何生成并验证类型结构化数据签名,所以整理这篇文章希望可以帮你节省点时间。

我正在进行的项目[2],需要用户用钱包签署一些数据。通常,我只会用个人签名[3],但是在一些情况下,数据有特定的格式,我想让钱包签名提示看起来更好一些。

以太坊的签名

用以太坊钱包对数据签名时,有多种方式可以选择。你可以用“普通的”,可以签名任何字符串(在签名交易时用的);你可以用个人签名,这会为签名信息添加一个前缀;或者你可以用类型结构化数据签名,它允许为用户需要签名的信息定义格式(并且签名提示显示更好)。

输入数据

在这个项目中,我决定使用类型结构化数据签名(EIP-712 签名)。首先,定义types(消息要用的结构)和domain(关于 app 的信息)。

代码语言:javascript复制
// Let's assume we're signing an email message
const message = {
    from: {
        name: 'Miguel Piedrafita',
        wallet: '0xE340b00B6B622C136fFA5CFf130eC8edCdDCb39D'
    },
    to: {
        name: 'Alex Masmej',
        wallet: '0xD3e9D60e4E4De615124D5239219F32946d10151D'
    },
    contents: 'We need more NFTs.'
};

// Our domain will include details about our app
const domain = {
    name: 'Ether Mail',
    version: '1',
};

// Here we define the different types our message uses
const types = {
    Person: [
        { name: 'name', type: 'string' },
        { name: 'wallet', type: 'address' }
    ],
    Mail: [
        { name: 'from', type: 'Person' },
        { name: 'to', type: 'Person' },
        { name: 'contents', type: 'string' }
    ]
};

有了domaintypes,我们就可以用ethers.js库来获取签名。

代码语言:javascript复制
import { ethers } from 'ethers'

const web3 = new ethers.providers.Web3Provider(provider)

const signature = await web3.getSigner._signTypedData(
    domain, types, message,
)

验证

现在我们只需要一种验证签名的方法。为此,我们需要前面生成的签名和签名的钱包地址,还有上一步中的domaintypes

代码语言:javascript复制
import { verifyTypedData } from 'ethers/lib/utils'

export const verifySignature = (signature, message, address): boolean => {
    return verifyTypedData(
        domain, types, message, signature,
    ).toLowerCase() === address.toLowerCase()
}

原文链接:https://m1guelpf.blog/lgIDdfbeDSElr0g7kaP0TZLkkjAqkQGPriauuYSrLlI

参考资料

[1]

影无双: https://learnblockchain.cn/people/58

[2]

项目: https://sonarwave.xyz

[3]

个人签名: https://learnblockchain.cn/article/3744

0 人点赞