eth.sign vs eth.accounts.sign create different sign

Viewed 3565

When I sign a string with the web3.eth.sign() method and web3.eth.accounts.sign() method. The result value of the two signatures is different. I don't know why these two results are different.

I'm using the latest web3.js. And the private key is from metamask.

This is my code

await ethereum.enable();
web3 = new Web3(web3.currentProvider);

let accounts = await web3.eth.getAccounts();
let msg = "sign this message"
let prefix = "\x19Ethereum Signed Message:\n" + msg.length
let msgHash1 = web3.utils.sha3(prefix+msg)

let sig1 = await web3.eth.sign(msgHash1, accounts[0]);
let privateKey = "0xcfb51f3737044cb4bfb49cbb10ae67d79ee81523d7065e95972cc23ed914e95e"
let sigObj = await web3.eth.accounts.sign(msgHash1, privateKey)
let sig2 = sigObj.signature;

console.log(sig1)
console.log(sig2)

And this is result. enter image description here

3 Answers

The source code shows that the difference is that web3.eth.accounts.sign prefixes and hashes the message before signing it.

In your example pass in msg instead of msgHash to eth.accounts.sign:

So this signature:

const msg = 'hello world'
const { signature } = await web3.eth.accounts.sign(msg, privateKey)

will produce the same signature as eth.sign with hashed message:

const msg = 'hello world'
const msgHash = web3.eth.accounts.hashMessage(msg)
const signature = await web3.eth.sign(accounts[0], msgHash)

web3.eth.sign and web3.eth.accounts.sign generate the same signature in web3.js v1.3.4 .

Correct me if I am wrong, It seems web3.eth.sign calls web3.eth.accounts.sign under the hood, here

Related