4

From Whisper wiki:

Low-latency, 1-1 or 1-N signalling messages.

Shh.post(self, message:) and Whisper Usage / shh.post

Creates a whisper message and injects it into the network for distribution.

Example usage of web3.shh.post, for more details please see this answer:

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

When I remove pubKey from web3.shh.post as arguments; it says: Error: specify either a symmetric or an asymmetric key.

shh.post({ "topic": t, "payload": p }); No signature, no encryption: Anonymous broadcast; a bit like an anonymous subject-filtered twitter feed.

[Q] Since web3.shh.post()requires us to provide single public key of the receiver; is it possible to send 1-N or broadcast message using whisper protocol? If yes, how?

2
  • I wrote the implementation on python3 here it is Commented Jul 3, 2018 at 10:17
  • Your answer does not sent 1-N messages. @Sergey Zaharov
    – alper
    Commented Jul 3, 2018 at 15:08

2 Answers 2

3
+50

I would recommended to use this documentation : https://github.com/ethereum/go-ethereum/wiki/Whisper

Whisper usage

your posted links are outdated and moreover are for Whisper v 2.0

Answer: It's possible 1:N message if you provide identical symKey for all recipients.

P.S. My posted links are for Whisper 5.0 , current version of Whisper is 6.0 but but the API for v6 is almost identical to v5 anyway.


On node-1's geth-client:

generatedSymKey=shh.generateSymKeyFromPassword("hello");    
symKey=shh.getSymKey(generatedSymKey)    
symKeyID=shh.addSymKey(symKey) //ex: "d5212e736703afbb21246e8acd192e4345ea910398544d765ed6b49f0ec524b5"
filter = web3.shh.newMessageFilter(
        {symKeyID:symKeyID, topic: '0x07678231'}, 
        function(err, res) {console.log(web3.toUtf8(res.payload))});

On node-2's geth-client:

generatedSymKey=shh.generateSymKeyFromPassword("hello")    
symKey=shh.getSymKey(generatedSymKey)    
symKeyID=shh.addSymKey(symKey) //ex: "c4c4cecf6ad9499c2386b8ce6416f44684e042e491726b38315646c0b4afadc6"
filter = web3.shh.newMessageFilter(
        {symKeyID:symKeyID, topic: '0x07678231'}, 
        function(err, res) {console.log(web3.toUtf8(res.payload))});

Than, sending message on another node and both messages show up on node-1 and node-2 even if symKeyID is either node-1's or node-2's on shh.post() function.

Following code is run on node-1's geth-client:

node-1's symKeyID is given:

web3.shh.post({
  symKeyID: 'd5212e736703afbb21246e8acd192e4345ea910398544d765ed6b49f0ec524b5', //symKeyID of the node-1
  ttl: 10,
  topic: '0x07678231',
  powTarget: 2.01,
  powTime: 2,
  payload: web3.fromAscii("Hello there!")
  });

OR


Following code is run on node-2's geth-client:

node-2's symKeyID is given:

web3.shh.post({
  symKeyID: 'c4c4cecf6ad9499c2386b8ce6416f44684e042e491726b38315646c0b4afadc6', //symKeyID of the node-2
  ttl: 10,
  topic: '0x07678231',
  powTarget: 2.01,
  powTime: 2,
  payload: web3.fromAscii("Hello there!")
  });
13
  • Thanks for the updated links. But how could recipients have identical symKey or publicKey since they are unique for each recipient? @Baracuda
    – alper
    Commented Jul 8, 2018 at 17:29
  • I have just pushed working ssh demo: github.com/achiko/whisper-v6-test I used shh.generateSymKeyFromPassword('....' ) method with one password.
    – Archi
    Commented Jul 8, 2018 at 17:37
  • 1
    I am pretty sure each receipt should have a unique symKey. What do you get symKey with following: shh.generateSymKeyFromPassword("hello") which I get : a0ce4c9103be09614d59103ca5aeee0bda8e59e9f6112f6c0b40f439ab0b4ab9 for receipt-1 and for another receipt I get different one. 4a6c15f288bfa9949702aa9a5e5bd305b6f48681513a266e8a3c42e58433f859 .
    – alper
    Commented Jul 8, 2018 at 17:43
  • generateSymKeyFromPassword Generates the key from password, stores it, and returns its id. github.com/ethereum/go-ethereum/wiki/… Its just ID stored locally.
    – Archi
    Commented Jul 9, 2018 at 9:55
  • 1
    I got your point, I added your answer with a tutorial code. @Baracuda
    – alper
    Commented Jul 9, 2018 at 12:51
3

Solution using Web3.py:

I have followed following ssh-mode code.


receiver.py that runs on node-1:

from os.path import expanduser
from web3 import HTTPProvider, Web3
import asyncio
import time


def handle_event(event):
    print(f"recipientPublicKey={event['recipientPublicKey'].hex()}")
    print(event["payload"].decode("utf-8"))


async def log_loop(filter_id, poll_interval):
    while True:
        for event in w3.geth.shh.getMessages(filter_id):  # event_filter.get_new_entries():
            handle_event(event)  # TODO: add try catch
        await asyncio.sleep(poll_interval)
        time.sleep(0.1)

if __name__ == "__main__":
    w3 = Web3(HTTPProvider("http://localhost:8545"))
    home = expanduser("~")
    topic = "0x07678231"

    print("Initializing...")
    key_id = w3.geth.shh.newKeyPair()  # generates a new public and private key pair for message decryption and encryption.
    public_key = w3.geth.shh.getPublicKey(key_id)
    filter_id = w3.geth.shh.new_message_filter({"topic": topic, "privateKeyID": key_id, "recipientPublicKey": public_key})
    print(f"my_public_key={public_key}")

    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(asyncio.gather(log_loop(filter_id, 2)))
    finally:
        loop.close()

Output:

my_public_key=0x0429824f14966d802e8a12b09c276361cdf13eda4dd5f4f776d0a2a4db61ba4e24683be84df2b521ff8c6290e3851bf9b59a8e9a7e13345fee603de9be862f5ef3

After Node_1's messages are sent; I have copied printed receiverPublicKey into receiver_pub variable on the following code. I run following code on Node 2. Node 2 sends a message to the network. Later I press enter on the Node_1 and Node_1 prints the message

from web3 import Web3, HTTPProvider
web3 = Web3(HTTPProvider('http://localhost:8545'))

# obtained from node_1 and assigned here.
receiver_pub =
"0x0429824f14966d802e8a12b09c276361cdf13eda4dd5f4f776d0a2a4db61ba4e24683be84df2b521ff8c6290e3851bf9b59a8e9a7e13345fee603de9be862f5ef3"

topic = '0x07678231'
payloads = [web3.toHex(text="test message :)"), web3.toHex(text="2nd test message")]

web3.geth.shh.post(
    {"powTarget": 2.5, "powTime": 2, "ttl": 60, "payload": payloads[0], "topic": topic, "pubKey": receiver_pub}
)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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