JavaScript 不可用。

我们检测到浏览器禁用了 JavaScript。请启用 JavaScript 或改用支持的浏览器来继续访问

Solidity 合约验证签名消息

作者:Anban Chu

发表日期:2023年06月15日

所属目录:合约开发

标签:

核心

  • signMessage ( personal_sign 方式)
  • verifyMessage ( recover )

合约核心代码

// 引入的库
import '@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol';
import '@openzeppelin/contracts/utils/cryptography/ECDSA.sol';

// ======================== Functions ========================
function claim(uint256 nonce, uint256 amount, uint256 deadline, bytes calldata signature) public {
    // ...
    require(recover(msg.sender, nonce, amount, deadline, signature) == serviceAddress, 'signer error');
    // ...

}

// ======================== Internal ========================
function recover(address user_address, uint256 nonce, uint256 amount, uint256 deadline, bytes calldata signature) internal pure returns (address signer) {
    bytes32 messageHash = MessageHashUtils.toEthSignedMessageHash(keccak256(abi.encode(user_address, nonce, amount, deadline, block.chainid, address(this))));
    signer = ECDSA.recover(messageHash, signature);
}

前后端代码演示

可以先去掉 chainid 和 合约地址,进行签名,对比最终结果是否相同。

const ethers = require("ethers");
const AbiCoder = new ethers.AbiCoder()
const privatekey = ''
const wallet = new ethers.Wallet(privatekey);

const params = {
    "user_address": "0xXXXXX",
    "nonce": "1",
    "amount": "10000000000000000000",
    "deadline": "1724342400",
    data_message: "", // encode
    data_message_hash: "", // encode to keccak256(sha3)
    data_signature_by: "",
    data_signature: "", // use service address to sign encode_hash
};
(async () => {
    const result = AbiCoder.encode(["address", "uint256", "uint256", "uint256"], [params.user_address, params.nonce, params.amount, params.deadline]);
    params.data_message = result;
    params.data_message_hash = ethers.keccak256(result);
    // 签名:地址+结果
    params.data_signature_by = wallet.address;
    params.data_signature = await wallet.signMessage(ethers.getBytes(params.data_message_hash));
    console.log('params', params);

    const recoveredAddress = ethers.verifyMessage(ethers.getBytes(params.data_message_hash), params.data_signature)
    console.log('恢复签名地址', recoveredAddress);
})()




以上就是本篇文章的全部内容了,希望对你有帮助。

>> 本站不提供评论服务,技术交流请在 Twitter 上找我