iT邦幫忙

2024 iThome 鐵人賽

DAY 16
0
Modern Web

web3 短篇集系列 第 16

結構化的簽章 (ERC-712)

  • 分享至 

  • xImage
  •  

建立一個結構化的簽章,可用於特定鏈上合約的函式呼叫,用戶使用錢包管理器簽名時,能夠清楚呈現所要簽的內容。

使用 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

上一篇
允許代付手續費的代幣 (ERC-2612)
下一篇
合約錢包的簽章 (ERC-1271)
系列文
web3 短篇集30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言