I am creating a signature with web3.js form a hashed message that contains two numbers and an address:
const tokenIds = [1,2,3];
const state = 1;
const messageHash = web3.utils.keccak256(tokenIds.length + state + web3.utils.keccak256(fromAddress));
const sign = await web3.eth.accounts.sign(messageHash, signer.privateKey);
await contract.myFn(
tokenIds,
sign.v,
sign.r,
sign.s,
{
from: fromAddress,
}
);
In my smart contract I then try to reconstruct the hash for message
and verify the signature as follow:
function myFn(uint[] calldata tokenIds, uint8 v, bytes32 r, bytes32 s) external {
require(
_signerAddress == ecrecover(
keccak256(abi.encodePacked(
"\x19Ethereum Signed Message:\n32",
// messageHash:
// When I concat those two strings with the address
// this hash is invalid (not the same as the on from the client).
keccak256(abi.encodePacked(
// uint256 amount
Strings.toString(tokenIds.length),
// uint256 state
Strings.toString(state),
// address msg.sender is fromAddress
keccak256(abi.encodePacked(msg.sender))
))
))
, v, r, s
),
'mint not allowed'
);
}
Basically it seems that the string concatenation when recreating messageHash
on hash doesn't match. Maybe there is a reliable way to convert the msg.sender
(fromAddress
) to string?