Go-Ethereum

Whisper:如何將消息從一個節點發送到位於不同主機上的另一個節點?

  • October 19, 2018
  • geth 版本:1.8.15-不穩定
  • 蟒蛇:3.5
  • 作業系統:osx/linux

我遵循了這個答案

在答案的方法上,我觀察到每個節點只能向自己發送消息,而其他節點不能過濾/查看這些消息。例如,當node-1向網路發送消息時;它不會出現在node-2節點 2web3.shh.info{memory}仍然為 0 的情況下,我假設它永遠不會擷取消息。


我已經嘗試使用Web3.js並且Web3.py在哪裡發送的消息Node_1沒有顯示在Node_2.

=> 這是我通過使用來的Web3.js

我開始的方式geth

geth --syncmode fast --cache=1024 --shh --datadir $DATADIR/private  --rpcaddr 127.0.0.1 --rpc --rpcport 8545 --rpccorsdomain="*" --networkid 12345 --rpcapi admin,eth,net,web3,debug,personal,shh

在 node-1 的 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))});

在 node-2 的 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))});

然後,node-1向網路發送消息,網路只node-1接收但node-2不接收。

以下程式碼執行在node-1's geth-client

給出了節點 1 symKeyID

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

=> 這是我通過使用來的Web3.py

Node_1執行shh_filter.get_new_entries()以擷取消息但len(received_messages)返回 0,其中沒有收到消息並web3.shh.info{memory}保持 0。

在節點 1 上:

from web3 import Web3, HTTPProvider
web3 = Web3(HTTPProvider('http://localhost:8545'))
from web3.shh import Shh
Shh.attach(web3, "shh")

import time, sys;

from hexbytes import (
   HexBytes,
)

receiver = web3.shh.newKeyPair()
receiver_pub = web3.shh.getPublicKey(receiver)
print('receiverPubK: ' + receiver_pub);

topic = '0x07678231'

shh_filter = web3.shh.newMessageFilter({
   'privateKeyID': receiver,
   'topics': [topic]
})

input("Press Enter to continue...");

received_messages = [];
received_messages = shh_filter.get_new_entries()
print(len(received_messages)) # Returns '0'
print(web3.shh.info.memory) # Returns '0'

輸出:

receiverPubK: 0x04226d96bf9857ac0ba429c1e8b480a2811ce47cb526dbd3829d7586e5cae740198ba291f3eca0f279f82db8a136be90ea9ec629ed6cd1d45cc7f873159811757d
Press Enter to continue...

AfterNode_1的消息被發送;我已將 print 複製receiverPublicKeyreceiver_pub以下程式碼的變數中。我在Node 2. Node 2向網路發送消息。後來我按輸入鍵Node_1,這些消息中的任何一條都不會顯示在Node_1

在節點 2 上:

from web3 import Web3, HTTPProvider
web3 = Web3(HTTPProvider('http://localhost:8545'))
from web3.shh import Shh
Shh.attach(web3, "shh")

import time, sys;

from hexbytes import (
   HexBytes,
)

receiver_pub='0x04226d96bf9857ac0ba429c1e8b480a2811ce47cb526dbd3829d7586e5cae740198ba291f3eca0f279f82db8a136be90ea9ec629ed6cd1'; # obtained from node_1 and assigned here.

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

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

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

**$$ Q $$**如何從一個節點向另一個節點發送耳語消息?我在方法上做錯了什麼?


shh.info.memory當發送者節點發布消息時,接收者保持為 0 。

請注意,我已經打開了問題Web3.pygo-ethereum但沒有人回复。我也試過一個節點,其中一個節點是bootnode,另一個需要在–bootnodes中有它的enode地址,這也不起作用。

網路中沒有以 開頭的節點bootnode。但我已經使用admin.addPeer().

有三個主要節點,它們enode是公開共享的,任何新的對等節點都使用admin.addPeer("mX_enode"). mX代表要麼m1m2要麼m3。此外,所有這 3 個節點也使用彼此連接admin.addPeer("mX_enode")。我添加了幾個連接到所有這 3 個節點的節點,這使網路更加穩定。

網路中的所有這三個節點都使用以下geth行,新連接的節點使用相同的行,沒有--nodiscover標誌:

geth --syncmode fast --cache=1024 --shh --datadir $DATADIR/private --rpcaddr 127.0.0.1 --rpc --rpcport 8545 --rpccorsdomain="*" --networkid 12345 --rpcapi eth,net,web3,personal,shh --nodiscover

請查看所有節點相互連接的圖像。

在此處輸入圖像描述

後來我選擇了一個發送者和接收者節點,它們都admin.peers返回其他節點的enode,所以我驗證選定的發送者和接收者節點是否在網路上相互連接。

**=>**接收方和發送方節點在其geth控制台上執行以下程式碼:

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

我已經儲存了發送者和接收者的symKeyID資訊,我將使用它來發布消息。發件人返回symKeyID的是321f3531fad3de1dd8344da26cba1a074ee3689acb796ecb8e5bdf8507b1a0ef. 接收方返回symKeyID的是ed30b966e40cec9088fb6054c1823d3ff36941aaa002ebd2eea9d5a6efd1a9fe

**=>**比發送者節點複製粘貼symKeyID到下面的程式碼片段來發布它的消息

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

**=>**接收器也這樣做。接收方將其複制粘貼symKeyID到相同的程式碼段中以發布其消息。

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

我可以在發送方和接收方節點的geth控制台上看到發送的消息。


我觀察到:

為了使用 Whisper 協議,不需要使用任何bootnode. 後來我嘗試在沒有--nodiscover並且仍然能夠在彼此之間發送和接收消息的情況下執行接收器和發送器節點。

引用自:https://ethereum.stackexchange.com/questions/57693