Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add a description #825

Merged
merged 3 commits into from
Nov 8, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions 52_EIP712/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,19 @@ tags:

之前我们介绍了 [EIP191 签名标准(personal sign)](https://github.com/AmazingAng/WTF-Solidity/blob/main/37_Signature/readme.md) ,它可以给一段消息签名。但是它过于简单,当签名数据比较复杂时,用户只能看到一串十六进制字符串(数据的哈希),无法核实签名内容是否与预期相符。

![](./img/52-1.png)
![image1](./img/52-1.png)

[EIP712类型化数据签名](https://eips.ethereum.org/EIPS/eip-712)是一种更高级、更安全的签名方法。当支持 EIP712 的 Dapp 请求签名时,钱包会展示签名消息的原始数据,用户可以在验证数据符合预期之后签名。

![](./img/52-2.png)
![image2](./img/52-2.png)

## EIP712 使用方法

EIP712 的应用一般包含链下签名(前端或脚本)和链上验证(合约)两部分,下面我们用一个简单的例子 `EIP712Storage` 来介绍 EIP712 的使用方法。`EIP712Storage` 合约有一个状态变量 `number`,需要验证 EIP712 签名才可以更改。

### 链下签名

1. EIP712 签名必须包含一个 `EIP712Domain` 部分,它包含了合约的 name,version(一般约定为 “1”),chainId和 verifyingContract(验证签名的合约地址)。
1. EIP712 签名必须包含一个 `EIP712Domain` 部分,它包含了合约的 name,version(一般约定为 “1”),chainId 和 verifyingContract(验证签名的合约地址)。

```js
EIP712Domain: [
Expand Down Expand Up @@ -69,6 +69,7 @@ EIP712 的应用一般包含链下签名(前端或脚本)和链上验证(
],
};
```

3. 创建一个 `message` 变量,传入要被签名的类型化数据。

```js
Expand All @@ -77,7 +78,8 @@ EIP712 的应用一般包含链下签名(前端或脚本)和链上验证(
number: "100",
};
```
![](./img/52-3.png)

![image3](./img/52-3.png)

4. 调用钱包对象的 `signTypedData()` 方法,传入前面步骤中的 `domain`,`types`,和 `message` 变量进行签名(这里使用 `ethersjs v6`)。

Expand All @@ -88,7 +90,8 @@ EIP712 的应用一般包含链下签名(前端或脚本)和链上验证(
const signature = await signer.signTypedData(domain, types, message);
console.log("Signature:", signature);
```
![](./img/52-4.png)

![image4](./img/52-4.png)

### 链上验证

Expand Down Expand Up @@ -182,11 +185,18 @@ contract EIP712Storage {
}
```

## Remix 复现
## 部署复现

1. 部署 `EIP712Storage` 合约。
1. 在 `Remix` 部署 `EIP712Storage` 合约。

2. 运行 `eip712storage.html`,根据浏览器的内容安全策略([Content Security Policy](https://github.com/MetaMask/faq/blob/9257d7d52784afa957c12166aff20682cf692ae5/DEVELOPERS.md#requirements-nut_and_bolt))的要求,MetaMask 不能通过打开的本地文件(file:// 协议)与 DApp 通信。 可以使用 Node 静态文件服务器 `http-server` 启动本地服务,在包含 `eip712storage.html` 文件的目录下执行以下命令:

```sh
npm install -g http-server
http-server
```

2. 运行 `eip712storage.html`,将 `Contract Address` 改为部署的 `EIP712Storage` 合约地址,然后依次点击 `Connect Metamask` 和 `Sign Permit` 按钮签名。签名要使用部署合约的钱包,比如 Remix 测试钱包:
在浏览器中打开 `http://127.0.0.1:8080` 就可以访问了。 然后将 `Contract Address` 改为部署的 `EIP712Storage` 合约地址,然后依次点击 `Connect Metamask` 和 `Sign Permit` 按钮签名。签名要使用部署合约的钱包,比如 Remix 测试钱包:

```js
public_key: 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4
Expand Down
Loading