1

I'm aware of these posts

How do you sign an verify a message in javascript proving you own an Ethereum address?

How does one properly use ecrecover to verify Ethereum signatures?


I'd like to sign a message and then verify it. I use the following command line in the geth terminal.

var msg = web3.sha3('Schoolbus')
var signature = web3.eth.sign(web3.eth.accounts[0], msg)
var r = signature.slice(0, 66)
var s = '0x' + signature.slice(66, 130)
var v = '0x' + signature.slice(130, 132)
v = web3.toDecimal(v)

Then I use the smart contract below, and call:

   call_ecover(r, s,  v, msg)

But what i get is: 0x0000000000000000000000000000000000000000

 pragma solidity ^0.5.0;
 contract Call_verify{

function call_ecover(bytes32 r, bytes32 s, uint8 v, bytes32 hash)external pure returns (address){ bytes memory prefix = "\x19Ethereum Signed Message:\n32";
bytes32 prefixedHash = keccak256(abi.encodePacked(prefix,hash));
return ecrecover(prefixedHash, v, r, s);
}

}

Note that I'm using compiler version 0.5.3 on remix.

Question: Why cannot I get the return value of ecrecover() function in my contract? Am I missing anything?

Aydin
  • 2,117
  • 6
  • 25
  • 41

2 Answers2

2

According to the documentation, it’s web3.eth.sign(data, address). I think you inversed the parameters. See https://web3js.readthedocs.io/en/1.0/web3-eth.html#sign.

Also, do you send the good hash in the call_ecover function? I think you need to send the hash of msg (in your case, a hash of a hash: web3.sha3(msg)).

n1c01a5
  • 294
  • 1
  • 9
  • You don't have to send hash of hash, you have to send what was signed. – Sanjay S B Jul 17 '19 at 05:31
  • In the code, msg is the hash of 'Schoolbus’ and call_ecover needs the hash of the msg so in this case it’s a hash of a hash. – n1c01a5 Jul 17 '19 at 11:09
  • In a digital signature, when you are signing a message, it means you are signing a hash of the message. This is used to verify the origin as well as integrity of the message. You can check the working logic in my answer. I have hashed SchoolBus only once before signing. This same hash is given as an input to the ecrecover function in solidity – Sanjay S B Jul 17 '19 at 11:42
  • Yes I agree with you and your code seems more clean but in the example of Ay. the message is a hash. – n1c01a5 Jul 17 '19 at 21:56
2

The following code snippet works:

    //pragma solidity ^0.5.0
    function checkSignature(bytes32 h, uint8 v, bytes32 r, bytes32 s) public pure returns (address signer) {
        bytes memory prefix = "\x19Ethereum Signed Message:\n32";    
        bytes32 prefixedHash = keccak256(abi.encodePacked(prefix,h));  
        signer = ecrecover(prefixedHash, v, r, s); 
    }
    //web3 1.0
    //multisig is my constract instance and second is an account address.

    const message = "SchoolBus";
    const h = web3.utils.soliditySha3(message);
    let signature = await web3.eth.sign(h, second);

    var r = signature.slice(0, 66);
    var s = "0x" + signature.slice(66, 130);
    var v = "0x" + signature.slice(130, 132);
    v = web3.utils.toDecimal(v);
    v = v + 27;

    const result = await multisig.checkSignature(h, v, r, s);
    //result === second

Note: web3.sha3 is a method from v0.2x. in v1.0 the function used is as described above. ecrecover gets the signer details from a piece of data, usually a hash and the signature obtained when the signer signed the data.

Sanjay S B
  • 1,329
  • 7
  • 23