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?

2 Answers 2

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)).

4
  • You don't have to send hash of hash, you have to send what was signed.
    – Sanjay S B
    Commented Jul 17, 2019 at 5: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
    Commented Jul 17, 2019 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
    Commented Jul 17, 2019 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
    Commented Jul 17, 2019 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.