在 Solidity 中验证签名消息

参考https://learnblockchain.cn/article/4250

前端签名

<script>
  async function signMessage() {
    if (!window.ethereum) return alert("Please Install Metamask");

    // connect and get metamask account
    const accounts = await ethereum.request({ method: "eth_requestAccounts" });

    // message to sign
    const message = "hello";
    console.log({ message });

    // hash message
    const hashedMessage = Web3.utils.sha3(message);
    console.log({ hashedMessage });

    // sign hashed message
    const signature = await ethereum.request({
      method: "personal_sign",
      params: [hashedMessage, accounts[0]],
    });
    console.log({ signature });

    // split signature
    const r = signature.slice(0, 66);
    const s = "0x" + signature.slice(66, 130);
    const v = parseInt(signature.slice(130, 132), 16);
    console.log({ r, s, v });

    alert(signature);
  }
</script>

例子中对"hello"进行签名

{message: 'hello'}
{hashedMessage: '0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8'}
{signature: '0xd78666fa24e699025c8bd4ec8046a721e6f7fda112710fd9…d7e45ed0347c719601b37a61346e01c2961051599db88db1b'}
{r: '0xd78666fa24e699025c8bd4ec8046a721e6f7fda112710fd95549becc40ddbd21', s: '0x14fb13cc76f7db607d7e45ed0347c719601b37a61346e01c2961051599db88db', v: 27}

solidity验证

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.0;

contract Verify {

    function VerifyMessage(bytes32 _hashedMessage, uint8 _v, bytes32 _r, bytes32 _s) public pure returns (address) {
        bytes memory prefix = "\x19Ethereum Signed Message:\n32";
        bytes32 prefixedHashMessage = keccak256(abi.encodePacked(prefix, _hashedMessage));
        address signer = ecrecover(prefixedHashMessage, _v, _r, _s);
        return signer;
    }

}

运行之后,得到签名的钱包

Last updated