26

Is there a js library or even just pure js where I can sign and verify I own an Ethereum address?

Patoshi パトシ
  • 4,800
  • 7
  • 45
  • 93

6 Answers6

24

You can sign a string of data using web3.eth.sign

The address you use needs to be unlocked and you can sign text like this:

> web3.eth.sign(<your address>, web3.sha3("Some text"))

0x32f689696d855dd79c73acd94b2374461261b6f3d00e758fa23d35607c0be3175cbc7a7ea02c7f23cd7ef9334b4718a3363dfe12c1c1de24da5f94eb68a67b6000"

The returned 130byte string is the concatenated r,s,v ECDSA values with the mapping:

r = signature[0:64]
s = signature[64:128]
v = signature[128:130]

While web3.js has no verification functions, Solidity has ecrecover call in the form:

ecrecover([sha3 hash of data], v, r, s)

This question explores usage of ecrecover.

Further, there is another thread on the forum in which the OP uses the Python Bitcoin module to verify signed data.


Update: Since v1.0 web3.js has verification functions. See the other answers here (eg. web3.eth.accounts.recover)

Ismael
  • 30,570
  • 21
  • 53
  • 96
o0ragman0o
  • 4,320
  • 18
  • 35
14

You can now verify signatures in web3 1.0 using web3.eth.accounts.recover

const account = web3.eth.accounts[0];
const signature = await web3.eth.sign("Hello world", account);
const signingAddress = web3.eth.accounts.recover("Hello world", 
signature);
// account === signingAddress
David Mihal
  • 397
  • 1
  • 3
  • 10
  • What does the comment // account === signingAddress mean? – John Murphy Jul 25 '18 at 11:02
  • 1
    @JohnMurphy It's just a comment explaining that at the end, the variables account and signingAddress are equal addresses – David Mihal Jul 25 '18 at 14:47
  • what if the data to be recovered is dynamic or not known on the backend? why is that an necessary argument? – Jim Sep 27 '21 at 18:21
  • @Jim The backend does need to know the message being signed. However, it doesn't need to be hardcoded, you can have your API receive the signature + the data that was signed. – David Mihal Sep 27 '21 at 20:34
6

Notice that web3js will always prefix the string with "\x19Ethereum Signed Message:\n" before signing it. If you want to create a signature without this prefix, you could use eth-crypto.

pubkey
  • 1,157
  • 1
  • 10
  • 15
  • 1
    Note that currently web3 also concatenates message length when signing a message. So the final format is this: \x19Ethereum Signed Message:\n" + message.length + message. See it here: https://web3js.readthedocs.io/en/v1.2.0/web3-eth-accounts.html#id16 – Renato Gama Aug 05 '21 at 17:53
1

Yes, you can.

Proving or verifying that you own a public address is simply a matter of verifying that you have the private key for that address.

eth-lightwallet will do that for you in JavaScript.

This is done completely "offline", as in the sense that you do not need to be connected to the Ethereum network, and eth-lightwallet does not provide such a feature.

To communicate with the Etherum network one still needs a connection to a node. This can be done on a back-end server by using Web3js and Geth, or on the front-end by using Web3js and MetaMask.

RFV
  • 633
  • 7
  • 16
1

Solution for ethers.js users:

const hexPrivateKey = "0xae78c8b502571dba876742437f8bc78b689cf8518356c0921393d89caaf284ce";
const signingKey = new ethers.utils.SigningKey(hexPrivateKey);
const digest = ethers.utils.id("Some message");

const signature = signingKey.signDigest(digest); const joinedSignature = ethers.utils.joinSignature(signature); // 0xf0a760680a88ec3efff6e68ebce051b948cffd51d5814a448c0b32e35f2c753a6862077f01ae8edfccd524ba843b9340bcedfeafe62167fdd8517ca8528f398b1c

const recoveredAddress = ethers.utils.recoverAddress(digest, signature); // 0x2f112ad225E011f067b2E456532918E6D679F978

Credits to ricmoo for the first part of the code snippet.

Paul Razvan Berg
  • 17,902
  • 6
  • 73
  • 143
-3

I dont think so.

So far, we have ethereum-lightwallet that relies on a RPC-open node to handle the block.

I think that there are some efforts to make a full-js client but, until now, you can't handle a wallet through pure JS.