Ребята из ethers. js нашли мою проблему. Как они там объясняют: https://github.com/ethers-io/ethers.js/issues/823#issuecomment -625953096 , функция signMessage
эфиров. js использует EIP-191 с форматом personal_sign, поэтому он ставит перед сообщением префикс "\x19Ethereum Signed Message:\n"
.
Чтобы получить тот же результат в эфирах. js как в golang, мы должны использовать необработанный SigningKey, а не оболочку Wallet:
const hexPrivateKey = "0xae78c8b502571dba876742437f8bc78b689cf8518356c0921393d89caaf284ce";
const signingKey = new ethers.utils.SigningKey(hexPrivateKey);
const signature = signingKey.signDigest(ethers.utils.id("bou"));
//{ r: '0xc83d417a3b99535e784a72af0d9772c019c776aa0dfe4313c001a5548f6cf254',
// s: '0x477f5334c30da59531bb521278edc98f1959009253dda4ee9f63fe5562ead5aa',
// _vs: '0x477f5334c30da59531bb521278edc98f1959009253dda4ee9f63fe5562ead5aa',
// recoveryParam: 0,
// v: 27 }
ethers.utils.joinSignature(signature);
// "0xc83d417a3b99535e784a72af0d9772c019c776aa0dfe4313c001a5548f6cf254477f5334c30da59531bb521278edc98f1959009253dda4ee9f63fe5562ead5aa1b"
Единственное, что нужно учитывать, это то, что последние 2 цифры этой подписи в эфирах. js не будут такими же, как golang, как в простых эфирах. js функция joinSignature использует v в конце, но golang, показанная выше, использует параметр восстановления в конце.