20

Using the javascript web3 API I can create a signature like this:

> web3.eth.sign(eth.coinbase, "0xdeadbeef")
"0xd3fe64b6f0920593cc4afb1321d592ae91e25fe1a0216e9002a4a6580fb2698c5ec62491c62557b8cc8f64533a5097b3ffb68208952b30cb27ed0a56ae21682201"

Now I'd like to verify that the signature is correct; doing so in a contract is already documented elsewhere, but I am looking for a way to do this using web3. (How) can this be done?

eth
  • 85,679
  • 53
  • 285
  • 406
J-B
  • 8,941
  • 16
  • 46
  • 77
  • 1
    does this help ? http://ethereum.stackexchange.com/a/1794/54 – euri10 Apr 05 '16 at 09:16
  • @euri10 thanks, but I am looking for an answer that doesn't require a contract to verify – J-B Apr 06 '16 at 04:01
  • (not an answer to comment) But I am stuck with https://ethereum.stackexchange.com/questions/15461/ethereum-signature-verification-not-matching - any suggestions on what is wrong? many thanks – enrique_83 May 23 '17 at 08:07

2 Answers2

16

web3 does not support this feature yet, but it might be coming with web3 1.0.

In the meantime you can use ethereumjs-utils ecrecover feature. Note that this function expects v to be in {27, 28}, and since your signature comes from geth, (since it doesn't return signatures in the canonical format yet) you will have to add 27 to your v.

Given a signature sgn of a the hashed message msg, you can use the ethereumjs-util library like this:

r = utils.toBuffer(sgn.slice(0,66))
s = utils.toBuffer('0x' + sgn.slice(66,130))
v = utils.toBuffer('0x' + sgn.slice(130,132))
m = utils.toBuffer(msg)
pub = utils.ecrecover(m, v, r, s)
adr = '0x' + utils.pubToAddress(pub).toString('hex')

To do the verification in a solidity contract, check out this answer.

Miguel Mota
  • 5,143
  • 29
  • 47
MrChico
  • 1,786
  • 14
  • 19
  • 1
    While this answer may be technically correct, I didn't find it to be very useful. In particular, starting with 0xdeadbeef and 0xd3fe64b6f0920593cc4afb1321d592ae91e25fe1a0216e9002a4a6580fb2698c5ec62491c62557b8cc8f64533a5097b3ffb68208952b30cb27ed0a56ae21682201 it is very unclear how to use ecrecover in that library to actually validate the address that signed it. – Micah Zoltu Aug 10 '16 at 01:29
  • 1
    Updated the answer with more detail, hopefully that will be more clear now – MrChico Aug 10 '16 at 17:02
  • v = utils.toBuffer(27) //assuming that the given value was 0 should be 27 + the last hex value of the signature (0 or 1). – Micah Zoltu Aug 11 '16 at 06:56
  • Also worth noting that in utils, the v parameter should be a number, so the v line should read: v = utils.bufferToInt(utils.toBuffer('0x' + sgn.slice(130,132))) – DanF Feb 14 '17 at 05:31
  • 1
    I propose to change the title adding specifying it is for web3 0.* – Davide C Apr 05 '19 at 10:12
  • Is there now this functionality? – Suisse Apr 05 '21 at 15:20
7

Starting v1.0 you can use web3.eth.accounts.recover

// message, signature
web3.eth.accounts.recover('Some data', '0xb91467e570a6466aa9e9876cbcd013baba02900b8979d43fe208a4a4f339f5fd6007e74cd82e037b800186422fc2da167c747ef045e5d18a5f5d4300f8e1a0291c');
> "0x2c7536E3605D9C16a7a3D7b1898e529396a65c23"
Utgarda
  • 791
  • 5
  • 20