I'm trying to create a signed message off-chain using ethers.js and verify that message on-chain using ecrecover
. I'm signing the correct message from my metamask wallet, and passing the r, s, and v from that signature into ecrecover, but not getting a match to my metamask wallet.
My solidity code should work for prefixed or non-prefixed signatures.
Here's the contract I'm using to verify signatures:
pragma solidity ^0.5.0;
contract SignatureVerifier {
/// @dev Signature verifier
function isSigned(address _address, bytes32 messageHash, uint8 v, bytes32 r, bytes32 s) public pure returns (bool) {
return _isSigned(_address, messageHash, v, r, s) || _isSignedPrefixed(_address, messageHash, v, r, s);
}
/// @dev Checks unprefixed signatures.
function _isSigned(address _address, bytes32 messageHash, uint8 v, bytes32 r, bytes32 s)
internal pure returns (bool)
{
return ecrecover(messageHash, v, r, s) == _address;
}
/// @dev Checks prefixed signatures.
function _isSignedPrefixed(address _address, bytes32 messageHash, uint8 v, bytes32 r, bytes32 s)
internal pure returns (bool)
{
bytes memory prefix = "\x19Ethereum Signed Message:\n32";
return _isSigned(_address, keccak256(abi.encodePacked(prefix, messageHash)), v, r, s);
}
}
From ethers, here's (a simplified version of) the code I'm using to generate the signature, which I use as parameters for the _isSigned
function call.
let provider = new ethers.providers.Web3Provider(window.ethereum)
let signer = provider.getSigner()
let dataHash = '0x952d17582514a6a434234b10b8e6b681b6006c8ed225d479fa3db70828b9cd60'
let signature = await signer.signMessage(dataHash)
let sigBreakdown = ethers.utils.splitSignature(signature)
console.log(sigBreakdown)
this prompts me for a signature in matamask where I sign the correct dataHash. It then logs an r, s, and v value.
In remix, I call isSigned
, passing my metamask address, the dataHash (0x952...d60), and the r, s, and v values, expecting a result of true
but it's returning false
. I'm fairly confident in the solidity code and the javascript code here, but clearly I'm missing something. Help is greatly appreciated!