5

EDIT: Problem Solved; working example of login below

I use the sha3 of a message I want to sign with eth.sign m = web3.sha3("Please work.")

I then runeth.sign(eth.coinbase, m)

And it returns me: 0x1c28d6720234343026c24718728cf0c251b0d09c87c32a6e380396a3360065290d0e7ec99a48e547e36645cecc11fd8d09742955c3d16c32eb75d9b24dd158d754

Theoretically, I would be able to derive the validity of the signature from this.

r = 0x1c28d6720234343026c24718728cf0c251b0d09c87c32a6e380396a336006529

s = 0x0d0e7ec99a48e547e36645cecc11fd8d09742955c3d16c32eb75d9b24dd158d7

v = 54?! ( I was under the impression this would be a 0 or 1. For ecrecover I tried 27 and 28 )

Now I plug these into ecrecover(m, v, r, s) and I get...

With 27: 0x8c6c953abf2957f7fec4c689f8fe2ff09b81b245

With 28: 0xb8feaa9b9bfd7f10caefdc6d7baa1f74c37cedef

What in the world is going on? I'm trying to implement a login for my application using web3 and this is a major roadblock. I'm hoping you geniuses can correct me where I'm wrong.

Thanks.

2

I came across the answer myself, See working code below. I was following this guide which I would not recommend!.

I was also using parity in geth mode to sign the data, which I also would not recommend. Switching to plain old geth RPC gave me more sane results.

That being said, beware of v!. There is a bug between implementations of geth which will return either 00/01 or 1b/1c for v. I solved my problem by using ethereumjs-util's fromRpcSig method, which accounts for the bug. If the following doesn't work try importing web3 and using its sha3 method with ethUtils toBuffer.

Here's a complete snippet of code client side and server side which implement login:

CLIENT

function login() {
  let data = web3.sha3('hello world');
  web3.eth.sign(web3.eth.defaultAccount, data, (err, result) => {
    if (!err) {
      axios.post(url + '/login', {
        addr: web3.eth.defaultAccount,
        sig: result
      }).then((res) => {
        console.log(res);
      });

    }
  });
}

SERVER

var ethUtils = require('ethereumjs-util');

let addr = req.body.addr;
let sig = req.body.sig;

let signature = ethUtils.fromRpcSig(sig);

let data = 'hello world';

let pubKey = ethUtils.ecrecover(
  ethUtils.sha3(data),
  signature.v,
  signature.r,
  signature.s);

let foundAddr = '0x' + ethUtils.pubToAddress(pubKey).toString('hex');

if (foundAddr === addr) {
  // Hooray! The user's signature proves they are who they say they are!
} else {
  // Not authenticated successfully
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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