Im trying to test some signature verification in Solidity. I have generated the signature with nodejs using the ethers.js library. The signature successfully verifies in nodejs.
I have tried to verify the same signature in solidity but it recovers a different signer address.
NodeJS Code
"use strict";
const ethers = require("ethers");
// remix account #0. Address: 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4
var wallet = new ethers.Wallet("PK HERE");
console.log("Wallet Address: " + wallet.address);
async function SignData() {
var packedAddress = ethers.utils.solidityPack(["address"], [wallet.address]);
var sig = await wallet.signMessage(packedAddress);
console.log("Sig1 " + sig);
console.log("Sig1 Valid? " + (ethers.utils.verifyMessage(packedAddress, sig) == wallet.address));
}
SignData();
Console output:
Sig1 0xbc223797d57c0cac4405c7751a54cae569c8a96c7a2296af28c18b45291a54f5774b1606277dfa1b19e83b24ab415e63b4dcd60be194f73c0ebe5cb3cd3e40e61c
Sig 1 Valid? true
Remix Code to verify the same signature
function testVerify(address signer, bytes memory signature_rsv) external pure returns(bool, address) {
bytes32 hashedMessage = keccak256(abi.encodePacked(signer));
(uint8 v, bytes32 r, bytes32 s) = splitSignature(signature_rsv);
address recov_signer = ecrecover(hashedMessage, v, r, s);
return (recov_signer == signer, recov_signer);
}
function splitSignature(bytes memory sig)
internal
pure
returns (uint8 v, bytes32 r, bytes32 s)
{
require(sig.length == 65, "Signature length is wrong !");
assembly {
// first 32 bytes, after the length prefix.
r := mload(add(sig, 32))
// second 32 bytes.
s := mload(add(sig, 64))
// final byte (first byte of the next 32 bytes).
v := byte(0, mload(add(sig, 96)))
}
return (v, r, s);
}
Remix returns:
0: bool: false
1: address: 0x0E929401ba22b6b2035DdDc1A3D3F078E7779560