I am trying to verify a signature generated in metamask with go-web3.
Solidity verification code
contract Verify {
function VerifyMessage(bytes32 _hashedMessage, uint8 _v, bytes32 _r, bytes32 _s) public pure returns (address) {
bytes memory prefix = "\x19Ethereum Signed Message:\n32";
bytes32 prefixedHashMessage = keccak256(abi.encodePacked(_hashedMessage));
address signer = ecrecover(prefixedHashMessage, _v, _r, _s);
return signer;
}
}
I am able to successfully recover the signer in metamask and web3js, but in golang I am getting an incorrect return address.
Golang function
func VerifySignature(_data global.SignatureData, walletAddress string) bool {
web3, err := web3.NewWeb3(global.AvaxRpcURL)
if err != nil {
log.Println(err)
return false
}
avaxMainnetChainId := int64(43113)
if err := web3.Eth.SetAccount(config.PrivateKey); err != nil {
log.Println(err)
return false
}
web3.Eth.SetChainId(avaxMainnetChainId)
tokenAddr := "0xF686F5D7165e8Ce1C606978F424a2DBd4a37e122"
contract, err := web3.Eth.NewContract(constants.VerificationABI, tokenAddr)
fmt.Println(_data.HashedMessage, _data.V, _data.R, _data.S)
if err != nil {
log.Println(err)
return false
}
msg := [32]byte{}
copy(msg[:], []byte(_data.HashedMessage))
num := _data.V
v, err := strconv.Atoi(num)
if err != nil {
log.Println(err)
return false
}
r := [32]byte{}
copy(r[:], []byte(_data.R))
s := [32]byte{}
copy(s[:], []byte(_data.S))
signer, err := contract.Call("VerifyMessage", msg, uint8(v), r, s)
if err != nil {
log.Println(err)
return false
}
log.Println(signer, walletAddress)
if signer.(common.Address).String() == walletAddress {
return true
}
return false
}
I am thinking I am doing something wrong with the function paramaters, all variables come in as a string and I am converting them to the correct types.
I have verified that my data is correct, and my inputs are correct as strings. Web3 go requires the paramaters to match the abi perfectly so I suspect my conversions may be the issue.