My goal is to send a message from one ethereum node to another one by using same public key of the receiver. In order to accomplish it, I have followed this guide that uses Whisper Protocol. But after geth on receiver is restarted its keyPair is lost and it says Error: invalid id for it when I tried to use it again.

In summary approach I followed from the linked answer above that successfully works within the geth session:

On the receiver node:

> kId = web3.shh.newKeyPair(); //"d4a2504d22955f20156c75bfce5c7f273865f7d8976de5eed3a48a103e4e6d2d"
> web3.shh.hasKeyPair(kId) //true
> web3.shh.newMessageFilter(
    {privateKeyID:kId}, 
    function(err, res) {console.log(web3.toUtf8(res.payload))});
> web3.shh.getPublicKey(kId) //returns PUBLIC_KEY_OF_THE_RECEIVER

> stored_kId = web3.shh.addPrivateKey(shh.getPrivateKey(kId)); //"b8a8344ae7010b8453e47c31d5cb99edbc7adce5ae3fe8ece2ee90dd0bcf446c"    
> web3.shh.hasKeyPair(stored_kId) //true   

On the sender node:

web3.shh.post({
  pubKey: 'PUBLIC_KEY_OF_THE_RECEIVER',
  ttl: 7, //Time-to-live in seconds (7 seconds).
  topic: '0x07678231',
  powTarget: 2.01,
  powTime: 2,
  payload: web3.fromAscii("Hello there!")
  });

The problem I am facing is when I restart the geth on the receiver node; I cannot reuse the kId(web3.shh.newKeyPair()) that is already created on the receiver before geth is restarted. So I need to regenerate shh.newKeyPair() and share its public key with the sender all over again (which seems inefficient).

The error I am receiving after geth is restarted.

> kId ="d4a2504d22955f20156c75bfce5c7f273865f7d8976de5eed3a48a103e4e6d2d" //web3.shh.newKeyPair() that is created before geth is restarted.
> web3.shh.getPublicKey(kId)
Error: invalid id
> web3.shh.hasKeyPair(kId) //false

So I have to create newKeyPair() all over again and share its public key with the sender.

  • This creates additional issue where, if receiver's geth node is restarted, sender's messages will not be received on receiver's end and sender will need to resent those messages into receiver with receiver's newly created public key all over again.

Please note that I observe similar issue on newSymKey().

Example:

> shh.newSymKey()
"2d97351f0c7394679c70472b9b3a2abf3a22b6cdc9815574b103b92e1f1bfde1"
> shh.getSymKey("2d97351f0c7394679c70472b9b3a2abf3a22b6cdc9815574b103b92e1f1bfde1")
"0x1edddb4ec019ce0f31e8a4a381c9b436476b547317d9508ce9dac1fb146a65f0"

restart the geth node and I tried to getSymKey(). with already generated symKey:

> shh.getSymKey("2d97351f0c7394679c70472b9b3a2abf3a22b6cdc9815574b103b92e1f1bfde1")
Error: non-existent key ID

More depth analysis:

From: Whisper v5 RPC API

shh_addPrivateKey

Stores the key pair, and returns its ID.

Parameters

String: private key as HEX bytes.
Returns

String: Key ID on success and an error on failure.

I have also tried shh_addPrivateKey to store the key pair. But after geth is restarted it seems like store key pair also lost and I cannot restore it.

Following line is used as the last line on the receiver node.

> shh.addPrivateKey(shh.getPrivateKey(kId))
"b8a8344ae7010b8453e47c31d5cb99edbc7adce5ae3fe8ece2ee90dd0bcf446c"

After geth is restarted still I cannot restore the keys with already added private-key's Key ID:

> kId='b8a8344ae7010b8453e47c31d5cb99edbc7adce5ae3fe8ece2ee90dd0bcf446c'
> shh.getPublicKey(kId)
Error: invalid id
> web3.shh.hasKeyPair(kId) //false

[Q] How could I handle this issue, where restoring already generated key pair (shh.newKeyPair() or shh.newSymKey()) after geth is restarted?

up vote 0 down vote accepted

Finally I was able to solve it.

After geth is restarted we need to call shh.addPrivateKey(). I guess add is meant for load the key pair. I was confused that I thought shh.addPrivateKey() was meant for save the key pairs.

> kId = web3.shh.newKeyPair() //create new key-pair
  "dcc9b5c6cc7110e118b45e5c6bec9b5755a02da6e57cb62a9ac1ce57e0aac41b"
> shh.getPrivateKey(kId) //Store this, it will be used on geth's new session
  "0x41a31ffc64eab3a672c408f77a82895d63623e6ccb1d08b5859f72fd6eb2e0fb"
> shh.getPublicKey(kId);   
  "0x04ed41f7ce2a44264224c34d6f2b1f9fdf00dbdb812d1e7174aec9835e80b72dc8a75113a359a8abdccac518a389c8756bb285563cb73d45abb3723c3c9c5392bc"
> web3.shh.hasKeyPair(kId) //true
> web3.shh.newMessageFilter(
    {privateKeyID:kId}, 
    function(err, res) {console.log(web3.toUtf8(res.payload))});

After geth restarted call shh.addPrivateKey() function with argument previously(before geth was closed) created key pair's private key:

On Reciever:

> privateKey = '0x41a31ffc64eab3a672c408f77a82895d63623e6ccb1d08b5859f72fd6eb2e0fb'; //From previous geth session
> kId=shh.addPrivateKey(privateKey) //Loads the key-pair
  "5c987a5999f3214f34c778a390e338583dd7a3b2837967158bf55af2306ea641"
> shh.hasKeyPair(kId); //true
> shh.getPublicKey(kId); //Same public key is received that is also obtained before geth is closed. 
 "0x04ed41f7ce2a44264224c34d6f2b1f9fdf00dbdb812d1e7174aec9835e80b72dc8a75113a359a8abdccac518a389c8756bb285563cb73d45abb3723c3c9c5392bc"
> web3.shh.newMessageFilter(
        {privateKeyID:kId}, 
        function(err, res) {console.log(web3.toUtf8(res.payload))});

On Sender:

web3.shh.post({
  pubKey: '0x04ed41f7ce2a44264224c34d6f2b1f9fdf00dbdb812d1e7174aec9835e80b72dc8a75113a359a8abdccac518a389c8756bb285563cb73d45abb3723c3c9c5392bc',
  ttl: 7,
  topic: '0x07678231',
  powTarget: 2.01,
  powTime: 2,
  payload: web3.fromAscii("Hello there!")
  });

  • Please note that I am still working on have to retrieve messages that are sent when geth was closed.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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