Ethereum Whisper 노드 구축 및 테스트

Jin.S
Tokamak Network
Published in
9 min readSep 11, 2018

Geth를 이용하여 Ethereum 사설망을 구축하고, whisper 메시지를 전송해보는 테스트를 진행해보겠습니다. Ethereum 사설망 구축에 대해서는 온더의thomashin 님이 작성하신 Geth를이용한 private Ethereum chain 구축 을 참고하시면 좋습니다.

# 글 작성 기준, ethereum whisper v5 RPC API 문서 https://github.com/ethereum/go-ethereum/wiki/Whisper-v5-RPC-API 에 나와 있는 API 들이 변경되어 있음.

1. Intro : Whisper 란 …
- Ethereum P2P protocol 상에서 유저간 암호화 메시지 송수신 프로토콜.
— Ethereum blockchain과 동일 한 네트워크를 사용하며, whisper node간 모든 whisper 메시지를 공유한다.
— 공유 되는 메시지는 암호키를 가지고 있는 수신자만 확인이 가능하다.
— 1대1 또는1대N 메시지 전송 가능.

2. Whisper 메시지 구조
- 송신자는 목적지의 주소로서 PublicKey 또는 SymKeyID 를 가지고 있어햐 하며, Topic, payload 메시지를 삽입하여 전송 한다.
- 수신자는 자신의 노드에 filter를 설정해 둠으로써, PublicKey 해당 되는 , 또는 SymKeyID 매칭되는 메시지를 수신하여 callback function을 호출 한다.

< Whisper Message 예시, Public Key 사용 >

3. Whisper 활성화
go-ethtereum, Geth 실행시 ` — shh` 플래그로 whisper 기능을 활성화 시켜주어야 한다.

< Geth 실행 whisper 기능 활성화 예시 >

whisper 기능이 정상적으로 활성화 되었다면, geth node 실행시 “started whisper v.5.0” 이 출력된다.

4. Whisper Key 생성 및 송수신 명령어
송신측, 수신측에 사용되어지는 PublicKey or SymKeyID는 아래와 같이 geth console 명령어를 통해 생성 할 수 있다.

Whisper 메시지 송신 명령어

송신자는 목적지의 주소로서 PublicKey 또는 SymKeyID를 알고 있어야 한다.

ssh.post({ PublicKey or SymKey, ttl, topic, payload, powTime, powTarget})

: 도착지 주소의 PublicKey 또는 SymKey Required

- ttl : 메시지의 Time to Live, seconds
- Topic은 메시지 제목의 주제에 해당, 수신자 필터링 되는 조건에 맞춰짐.
- Payload : 실제 메시지의 전문 내용, hex encoding
- powTime, powTarget 노드에서 설정 수치 이상 적용

Whisper 메시지 수신측 설정 명령어

수신자는 자신의 노드에 filter를 설정해 둠으로써 publicKey 또는 SymKeyId에 해당하는 메시지가 수신되었을때 입력된 콜백함수를 실행한다.

ssh.newMessageFilter: function(options, callback, filterCreationErrorCallback)

- options 에 { privateKeyID, SymKeyID, Topic } 등 입력
- callback, filterCreationErrorCallback 함수 설정

[filterId가 부여된 객체 생성]

5. Whisper 프라이빗 노드 구성

< Ethereum Private Node for Whisper Test >

Whisper Node1 은 송신자, Whisper Node2는 수신자측 노드로 각각 설정.
( Geth를 이용한 Ethereum Node 구축에 대해서는 “ Geth를이용한 private Ethereum chain 구축”을 참고)

Node1과 Node2는 서로 연결이 되어 있지 않은 상태이므로, 메뉴얼로 두 노드를 서로 peer로 설정해 주어야 한다.

Whisper Node1 노드 설정

송신자로 사용될 Whisper Node1의 geth console 에 아래 명령어를 입력한다.
nodeinfo의 enode 주소를 저장해 놓는다. 해당 enode 주소는 Node2에서 peer 설정에 사용할것이다.

$geth — network 4382 — shh$geth attach /[data dir]/geth.ipc> admin.nodeInfo
#[capture peer node1 address] ad nodeInfo result
< Whisper Node1 의 주소 : “enode://aab0c … 807@[node1 ip address]:30303” >

Whisper Node2 노드 설정

수신자로 사용될 Node2의 geth console에 아래 명령어를 입력한다.
Node1의 enode 주소를 peer로 입력한다. 마지막 admin.peers로 Node1이 Node2의 peer로 설정되어 있는지 확인한다.

$geth — network 4382 — shh$geth attach ~/[datadir/geth.ipc> admin.addPeer(“enode://[node1 enode addr]@[whisper Node1 ip]:30303”)
< Node1이 peer로 정상적으로 적용된경우 >

6. Whisper Message 송수신테스트

Whisper Node1과 Whisper Node2가 서로 Peer로 설정된 이후, 수신자측으로사용될 노드인 Node2에 message filter를 설정해주어야한다.

Generating Keys
whisper 메시지 송신자가 사용할 pubkey 를 Node2에서 생성한다. 아래 명령어를 Node2의 geth console에입력하여 publicKey 를생성한다.

> keypair = shh.newKeyPair()
> pubkey = shh.getPublicKey(keypair)

Generating Filter & callback functions
수신자로 사용될 Node2에서 메시지 수신시 적용할 filter 를 생성한다. 이때 pubkey 를 위의 과정(Generating Keys)을 통해 먼저 생성해 놓아야 한다.
cbcbe 함수는 메시지수신시 filter 의조건에 맞는 메시지가 수신될때 작동하는 콜백 함수와 콜백 에러 처리함수이다.

> cb = function(err,messages){console.log(JSON.stringify(err||messages))}
> cbe = function(error){console.log(error)}
> filter = shh.newMessageFilter({privateKeyId: keypair}, cb, cbe)

filter 가 정상적으로 생성되었으면 아래와 같은 결과가 출력된다.

< Message Filter at Node2 >

filteroptions 내용이 노드의 필터로 적용되는 조건이며, 여기에 topic 과 같은 조건이 추가되면 publicKey and topic 으로 두 조건이 모두 해당되는 메시지만 콜백함수가 작동한다. (위 예시에 privateKeyId 가 실제로 publicKey 에해당한다)

Send Whisper Message From Node1
송신자로 설정한 Node1에서 shh.post 명령어를 통해 해당 publicKey 주소로 메시지를 전송한다. ( Node2에서 생성한 pubicKey 주소로 “0x ~” 로 시작한다.)

> shh.post({pubkey:”[ pubkey generated at node 2 ]”, ttl: 30, powTime: 1, powTarget: 0.201, payload : web3.fromAscii("message from sender")})
  • powTarget은 송신자로 선택한 Node1의최소요구치에 이상 설정해주어야한다. ( powTarget 의 default 값은 0.2 )
  • ttl 은 해당 메시지의 지속시간(초)으로 수치가 높을수록 높은 비용 (hash Power)가 요구된다.

Receive Message at Whisper Node 2
Node1에서 ssh.post 를 통해 메시지를 전송하면, 거의 동시에 Node2 콘솔에 아래와 같이 메시지가 출력된다.

< Node2’s Public Key & Received message from Node1 >

payload 로수신한 hex코드를 변환해 보면 송신자의 메시지를 확인해 볼 수 있다.

< Decode payload from hex encoded message >

Reference

--

--