I've seen many instances of verifying signed messages in which the hash to be verified gets passed as an argument. I need to first recreate the hash on-chain, before running ecrecover on it. However, when I keccak256 hash the same thing I hashed off-chain, I'm getting a non-match.
Here's my web3 code, where I create the hash off-chain:
let prepend = keccak256(ethers.utils.defaultAbiCoder.encode(
[ 'string' ],
[ "\x19Ethereum Signed Message:\n32" ]
));
let message = ethers.utils.defaultAbiCoder.encode(
[
'address', 'string', 'uint256'
],
[
contracts.accessControls.address, 'Generate authorization code', this.state.spaceId
]
);
let msg = keccak256(prepend, message);
await accessControlContract.commitSignatureHash(indexOfUser, this.state.spaceId, msg);
web3.eth.sign(msg, context.account, (err, res) => {
if(err){
console.log(err);
} else{
this.setState({userSecretCode: "register " + this.state.spaceId + context.account + res});
console.log(this.state.userSecretCode)
}
});
And here's my solidity code where I try to recreate the same hash on chain and then run ecrecover on the sending address:
function commitSignatureHash(uint256 index, uint256 space, bytes32 hashToVerify) public {
require(whitelistForSpace[space][index] == msg.sender);
latestCommittedHashByAddressBySpace[space][msg.sender] = hashToVerify;
timeStampByAddressBySpace[space][msg.sender] = now;
}
function verifySignature(address userRegisteringSpace, uint256 space, uint8 v, bytes32 r, bytes32 s) public view returns (bool){
bytes32 hashToVerify = keccak256(
abi.encodePacked(
address(this),
'Generate authorization code',
space));
bytes memory prefix = "\x19Ethereum Signed Message:\n32";
bytes32 prefixedHash = keccak256(abi.encodePacked(prefix, hashToVerify));
//making sure it recreates a previously committed hash
require (prefixedHash == latestCommittedHashByAddressBySpace[space][userRegisteringSpace]);
return userRegisteringSpace == ecrecover(prefixedHash, v, r, s);
msg (created off-chain) doesn't seem to be matching prefixedHash (created on-chain)