1

Is there any way to do that? To recover address in nodejs server-side from signature and message after it was signed with web3.personal.sign client-side? I tried this: https://ethereum.stackexchange.com/a/12580/42452 with ethereumjs-util; I tried recoverTypedSignature() from eth-sig-util but in both cases recovered addresses didn't match signing addresses.

Here is the client-side code:

function authorize() {
  web3.eth.getAccounts(function (err, account) {
    let nonce = "123ABC";
    web3.personal.sign(nonce, account[0], function (err, signature) {
      //send to nodejs server
      $.post("http://localhost:8087", {signature: signature, nonce: nonce, address: account[0]}, function (data) {
        console.log(data);
      });
    })
  })
}

and server-side:

app.post('/', cors(corsOptions), function(req, res){
const msg = web3.sha3(nonce);
const sig = signature;
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(addr);
});
app.listen(8087);
  • It's hard to debug your code when you haven't shared it. – user19510 Apr 17 at 22:05
3

Did you try web3's web3.eth.personal.ecRecover?

For example, if you sign via

web3.eth.personal.sign("Hello world", "0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe", "test password!")
.then(console.log);

> "0x30755ed65396facf86c53e6217c52b4daebe72aa4941d89635409de4c9c7f9466d4e9aaec7977f05e923889b33c0d0dd27d7226b6e6f56ce737465c5cfd04be400"

You "recover" via...

web3.eth.personal.ecRecover("Hello world", "0x30755ed65396facf86c53e6217c52b4daebe72aa4941d89635409de4c9c7f9466d4e9aaec7977f05e923889b33c0d0dd27d7226b6e6f56ce737465c5cfd04be400").then(console.log);

> "0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe"

  • Sure I tried "web3.eth.personal.ecRecover", but it gives me error: "Cannot read property 'ecRecover' of undefined". Then I tried web3.personal.ecRecover, but this method produces error: "The method personal_ecRecover does not exist/is not available". So to me, it looks like the personal.ecRecover method works only in the browser, client-side, but not inside nodejs server-side. But after many hours I found a solution. – Cezary Stroczyński Apr 18 at 12:18
  • Interesting. The personal interactions are typically limited to a client-side solution (the personal is also used for creating accounts, signing transactions, etc. and is dangerous to have that happening on an open, server node.) I wonder why this is personal though. Regardless, can you please post an answer to your question as a new answer to help people who may have similar issues in the future? – tayvano Apr 18 at 18:29
0

So, after many hours, I found a solution, that works. To make it works I used method from ethereumjs-util - ecrecover. I had to add some prefixed message to signed nonce. Code looks like this:

function checkSignature(nonce, signature, res) {

  nonce = "\x19Ethereum Signed Message:\n" + nonce.length + nonce;
  nonce = util.keccak(nonce);
  const sig = signature;
  const {v, r, s} = util.fromRpcSig(sig);
  const pubKey  = util.ecrecover(util.toBuffer(nonce), v, r, s);
  const addrBuf = util.pubToAddress(pubKey);
  const addr    = util.bufferToHex(addrBuf);
  console.log(addr);

}

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.