I generated a signed message using ethers.js. Here's how I did that:
const provider = new ethers.providers.Web3Provider(web3Provider.provider);
const signer = provider.getSigner();
await signer.signMessage("hexcowboy")
Now I have a message signed by 0x37121F74d25262011AdD8cc8D13E6923AEb699d8
with the message hexcowboy
and the signed message being 0x27876c5cc1be67e8313633ab0f72ace790886c88a664df1ca0b858c1834782002a0ae1e44fdb3fe7586eec431c115205a36a05bbd31c6c2bce04605825e91cfe1b
.
I know my message signature is valid because ether.js can recover my public key from it:
import { utils } from 'ethers';
const output = utils.verifyMessage("hexcowboy", "0x27876c5cc1be67e8313633ab0f72ace790886c88a664df1ca0b858c1834782002a0ae1e44fdb3fe7586eec431c115205a36a05bbd31c6c2bce04605825e91cfe1b");
console.log(output);
When I try to recover the public key from this message using Go Ethereum, I'm not getting the correct public key using SigToPub
.
func VerifyMessage(ctx context.Context, message string, signedMessage string) (string, error) {
// Hash the unsigned message
hash := crypto.Keccak256Hash([]byte(message))
// Get the bytes of the signed message
decodedMessage := hexutil.MustDecode(signedMessage)
decodedMessage[64] = 0
test, err := crypto.SigToPub(hash.Bytes(), decodedMessage)
if err != nil {
return "", err
}
fmt.Println(crypto.PubkeyToAddress(*test)) // 0xDd874aAD8bAf218e4DfAd2b59E2798E775e48eB5
return "", nil
}
What do I need to do to recover an address from an ethers.js signed message in Go Ethereum?
Best Answer
Solved my answer. I wasn't aware I needed to add the prefix for EIP-191 signed messages. Here is my working code: