Verify Signature

심우진·2022년 5월 22일

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

/*
0. message to sign
1. hash(message)
2. sign(hash(message), private key) | offchain
3. ecrecover(hash(message), signature) == signer
*/

contract VerifySignature {
    function verify(address _signer, string memory _message, bytes memory _sig) external pure returns (bool) {
        bytes32 messageHash = getMessageHash(_message);
        bytes32 ethSignedMessageHash = getEthSignedMessageHash(messageHash);

        return recover(ethSignedMessageHash, _sig) == _signer;
    }

    function getMessageHash(string memory _message) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(_message));
    }

    function getEthSignedMessageHash(bytes32 _messageHash) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(_messageHash));
    }

    function recover(bytes32 _ethSignedMessageHash, bytes memory _sig) public pure returns (address) {
        (bytes32 r, bytes32 s, uint8 v) = _split(_sig);
        return ecrecover(_ethSignedMessageHash, v, r, s);
    }

    function _split(bytes memory _sig) internal pure returns (bytes32 r, bytes32 s, uint8 v) {
        require(_sig.length == 65, "invalid signature length");

        assembly {
            r := mload(add(_sig, 32))
            s := mload(add(_sig, 64))
            v := byte(0, mload(add(_sig, 96)))
        }
    }
}

  1. getMessageHash()에 string으로 넣을 메시지를 입력한다.
  2. 결과값 해시를 getEthSignedMessageHash()에 넣는다.
  3. 콘솔에서 ethereum.enable(),
    account 설정과 getMessageHash의 결과값 해시를 hash를 입력한다.
  4. 콘솔에서 ethereum.request({method: "personal_sign", params: [account, hash]}) 입력 후,
    recover에 getEthSignedMessageHash 해시와
    PromiseResult 해시 입력
  5. verify에서 _signer에 recover 해시값,
    _message에 메시지,
    _sig에 콘솔창 해시를 입력

result는 true(메시지가 하나라도 맞지 않으면 false가 나옴)

0개의 댓글