建立一個結構化的簽章,可用於特定鏈上合約的函式呼叫,用戶使用錢包管理器簽名時,能夠清楚呈現所要簽的內容。
使用 openzeppelin 的套件實作合約的驗證函式:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.27;
import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
contract ERC712Verify is EIP712 {
bytes32 private constant VERIFY_TYPEHASH = keccak256("Verify(uint256 num,bool boo)");
constructor(string memory name) EIP712(name, "1") {}
function verify(uint256 num, bool boo, bytes calldata signature) public view returns (bool) {
bytes32 structHash = keccak256(abi.encode(VERIFY_TYPEHASH, num, boo));
bytes32 hash = _hashTypedDataV4(structHash);
address signer = ECDSA.recover(hash, signature);
if (signer != msg.sender) {
revert("Invalid signature");
}
return true;
}
}
合約部署在 sepolia: 0x8F107A9862D2BD394c0a738F7FBC2b7c1772a52D
使用 ethers v6 實作簽 ERC-712 簽章:
import { Wallet } from 'ethers'
const signer = new Wallet(process.env.PRIVATE_KEY!)
const verifyingContract = '0x8F107A9862D2BD394c0a738F7FBC2b7c1772a52D'
const domain = {
name: 'ERC712 Verify',
version: '1',
chainId: '11155111',
verifyingContract,
}
console.log('signer:', signer.address)
console.log('domain:', domain)
const types = {
Verify: [
{ name: 'num', type: 'uint256' },
{ name: 'boo', type: 'bool' },
],
}
const value = {
num: 42n,
boo: true,
}
const signature = await signer.signTypedData(domain, types, value)
console.log('==================================')
console.log('signature', signature)
驗證失敗!怎麼會這樣...
QQ,之後再來看哪裡有問題。
IERC5267
function eip712Domain() external view
returns (
bytes1 fields,
string memory name,
string memory version,
uint256 chainId,
address verifyingContract,
bytes32 salt,
uint256[] memory extensions
);
call eip712Domain
cast call \
--rpc-url $sepolia \
0x4139982367D9b72Aba0aAeb347eD2393eB59799E \
"eip712Domain()(bytes1,string,string,uint256,address,bytes32,uint256[])"
call verify
cast call \
--rpc-url $sepolia \
0x4139982367D9b72Aba0aAeb347eD2393eB59799E \
"verify(uint256,bool,bytes)" \
42 true 0x592139814a658542a43130a0a1ddd2e348e5643f54cafa675beea9d94920239c6165ea15877b4f843e4b05bed97af1119d203e6fd50c1ea682966f593d2c43b91c