In my contract I'm verifying if some data was correctly signed by the owner. It looks like this:
require(
owner() ==
ecrecover(keccak256(abi.encodePacked(this, aCustomId)), v, r, s),
"owner should sign aCustomId"
);
Which means i should be retrieving v, r, s from a backend, which I currently do like this:
import * as ethUtil from 'ethereumjs-util';
const hash = soliditySha3(
'myContractAddress',
'11111',
);
const signature = ethUtil.ecsign(
ethUtil.toBuffer(hash),
wallet.getPrivateKey(),
);
return {
r: ethUtil.bufferToHex(signature.r),
s: ethUtil.bufferToHex(signature.s),
v: signature.v,
aCustomId: 11111,
};
// return the v, r, s
however, it seems like it's not correct as I keep getting "owner should sign aCustomId".
How can i create the correct hash so my v,r,s parameters are correct for recovering later ?
I'm using solidity version 0.6.12
The contract is called something like this:
myContract.methods
.someMethod(
11111,
vValueAsInt,
"sValue",
"rValue",
)
.send({ from: account }, function(
error: any,
transactionHash: any
) {
console.log(transactionHash);
console.log(error);
});
Best Answer
Here is a working code with web3js 1.3.0, ethereumjs-utils 5.2.5 and solidity 0.6.12 :
Javascript part
Note that we use
hashPersonalMessage
in addition tosoliditySha3
in order to add a prefix to the data before signing it. This prefix is :"\x19Ethereum Signed Message:\n32"
. It's a security standard which prevents attacks such as a malicious attempt to make a user sign a transaction while making him believe that he is signing a message.Smart contract
The two important things here are :
address(this)
(and notthis
).