ecrecover
returns public key, you need to convert it to address with pubToAddress
.
pub = ethJsUtil.ecrecover(msg, v, r, s);
addrBuf = ethJsUtil.pubToAddress(pub);
addr = ethJsUtil.bufferToHex(addrBuf);
Also, you can use fromRpcSig
to get v, r, s
sig = web3.eth.sign(myAccount,msg)
res = ethJsUtil.fromRpcSig(sig)
pub = ethJsUtil.ecrecover(msg, res.v, res.r, res.s);
Please note that web3.eth.sign
adds prefix to the message before signing it (see JSON-RPC spec).
Here is how to add it manually:
const util = require('ethereumjs-util')
const msg = new Buffer('hello');
const sig = web3.eth.sign(web3.eth.accounts[0], '0x' + msg.toString('hex'));
const res = util.fromRpcSig(sig);
const prefix = new Buffer("\x19Ethereum Signed Message:\n");
const prefixedMsg = util.sha3(
Buffer.concat([prefix, new Buffer(String(msg.length)), msg])
);
const pubKey = util.ecrecover(prefixedMsg, res.v, res.r, res.s);
const addrBuf = util.pubToAddress(pubKey);
const addr = util.bufferToHex(addrBuf);
console.log(web3.eth.accounts[0], addr);
On the other hand, testrpc (at least version 3.0.5) does not add such prefix.
Example node.js + testrpc session:
const util = require('ethereumjs-util')
const msg = web3.sha3('hello!');
const sig = web3.eth.sign(web3.eth.accounts[0], msg);
const {v, r, s} = util.fromRpcSig(sig);
const pubKey = util.ecrecover(util.toBuffer(msg), v, r, s);
const addrBuf = util.pubToAddress(pubKey);
const addr = util.bufferToHex(addrBuf);
console.log(web3.eth.accounts[0], addr);
Best Answer
You could try this library it works perfectly. https://github.com/LimelabsTech/eth-ecies