Raspberry Pi でブロックチェーンの実証実験を行う(その2)

**はじめに**
CQ出版社刊：「ラズパイで作るブロックチェーン暗号化コンピュータ(2020年3月1日 初版) を参考にして
ブロックチェーンの実証実験を行った。
[(その１)は、こちらから](https://qiita.com/ytetsuo/items/8ebfdfbafcbad61e9b73)

今回は、Windows側から / Raspberry Pi側から ブロックチェーンへのアクセス(制御) について記す。
※参考にした書籍は、MACを使ってのアクセス方法のみ！を記述している。

---
**Windows側の準備**
ブロックチェーン (少なくともこの書籍で) は、JSON(JavaScript Object Notation)の記述を用いて
いるので WindowsPCを使える様に jq.exe を [https://stedolan.github.io/jq/](https://stedolan.github.io/jq/)からダウンロードする。
私は、とりあえず jq.exe を ルート C:&yen;> に置き、C:&yen;>から コマンドラインで動かした。
※jq-win64.exe を jq.exe と Rename をして使用した
※本来は、置き場所への PATH を切り 任意の場所からコマンドを動かせれば良いのでしょうね・・・

**Raspberry Pi側の準備**
Raspberry Pi に 標準で入っていた Thonny を用いて Python でプログラミングを行ったので
特に何もする必要がなかった。

---
**①P2Pネットワークに参加するサーバーを登録**
(書籍の P.199 に MACでの方法について記載されている)
※IPアドレス xx.xx.xx.xx1 に対して IPアドレス xx.xx.xx.xx2 を参加させる
※'\' = '&yen;' であることに注意 (日本語環境において)
※[P2Pの状態を確認]をすると、xx.xx.xx.xx1 と xx.xx.xx.xx2 がお互いに接続されていることが分かる

 &emsp;1. WindowsPCからP22に参加させる場合

~~~
C:\> curl -X POST http://xx.xx.xx.xx1:3000/node/ -H "Content-Type: application/json" -d "{\"host\":\"xx.xx.xx.xx2\",\"api_port\":3000, \"p2p_port\":4000}"
~~~

 &emsp;2. Raspberry Pi から　Python のプログラムを使う場合

~~~
#----------------------------------------------------
# 相手側(xx.xx.xx.xx2) に自分自身(xx.xx.xx.xx1) を
# 通知することで お互いが P2P 接続される
#----------------------------------------------------
import requests
import json

api_host = "xx.xx.xx.xx1" #自分自身のIPアドレス
api_port = "3000"
url = "http://" + api_host + ":" + api_port

def Post_data(key1, value1, key2, value2, key3, value3):

    Post_data = {key1:value1, key2:value2, key3:value3}
    out = json.JSONEncoder().encode(Post_data)
    print(out)
    
    resp = requests.post(url + "/node/", data=out, headers={'content-type': 'application/json'})

    #print(resp) #(error Code) or (if Code=200 then Success!!)
    return

#Post_data('host', '相手側のIPアドレス', 'api_port', 3000, 'p2p_port', 4000)
Post_data('host', 'xx.xx.xx.xx2', 'api_port', 3000, 'p2p_port', 4000)
~~~

---
**②P2Pの接続情報を取得**
(書籍の P.182 に MACでの方法について記載されている)
※xx.xx.xx.xxx1 に対して P2Pの接続情報を得る方法
 &emsp;1. WindowsPCの場合

~~~
C:\> curl http://xx.xx.xx.xx1:3000/nodes | jq
~~~

 &emsp;2. Raspberry Pi から　Python のプログラムを使う場合

~~~
#----------------------------------------------------
# xx.xx.xx.xxx1 からP2Pの接続情報を得る
#----------------------------------------------------
import requests

api_host = "xx.xx.xx.xxx1"
api_port = "3000"

url = "http://" + api_host + ":" + api_port + "/nodes"

resp = requests.get(url)
print(resp.text)
~~~

 &emsp;3. 下記の様に P2Pの接続情報が得られた

~~~
C:\>curl http://xx.xx.xx.1:3000/nodes | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   165  100   165    0     0    165      0  0:00:01 --:--:--  0:00:01 11000
[
  {
    "host": "xx.xx.xx.1",
    "api_port": 3000,
    "p2p_port": 4000
  },
  {
    "host": "xx.xx.xx.2",
    "api_port": 3000,
    "p2p_port": 4000
  },
  {
    "host": "xx.xx.xx.3",
    "api_port": 3000,
    "p2p_port": 4000
  }
]
~~~

---
**③データをブロックチェーンで暗号化する**
(書籍の P.172 に記載されている)
 &emsp;1. WindowsPCから行う場合

 &emsp; &emsp;a)直接データを登録する場合

~~~
curl -X POST http://xx.xx.xx.x1:3000/block/ -H "Content-Type: application/json" -d "{\"data\":\"date=20211028, slope=1.07, intercept=-0.12\"}"
~~~

 &emsp; &emsp;b)データをあらかじめ(test.jsonとして) 準備する場合

~~~
curl -X POST http://xx.xx.xx.xx:3000/block/ -H "Content-Type: application/json" -d @test.json
~~~

 &emsp; &emsp; test.json は、例えば 下記の様なデータ

~~~
{
  "host": "date=20211028, slope=1.07, intercept=-0.12"
}
~~~

 &emsp;2. Raspberry Pi から　Python のプログラムを使う場合

~~~
#---------------------------------------------------------
# データをハッシュ関数に変換してブロックチェーンで保存する
#---------------------------------------------------------
import requests
import json

api_host = "xx.xx.xx.1"
api_port = "3000"
url = "http://" + api_host + ":" + api_port

def save_data(data):

    #Prepare Data
    savedata = {"data":json.JSONEncoder().encode(data)}

    #print(savedata)
    out = json.JSONEncoder().encode(savedata)
    print(out)
    
    #ハッシュ関数の作成
    resp = requests.post(url + "/block/", data=out,
                         headers={'content-type': 'application/json'})
    print(resp)
    return

#ブロックチェーンで保存するデータ
save_data('Serial=xxxxx, slope=xx, intercept=xx, variance=xx')
~~~

 &emsp;3. ブロックチェーンの情報を得る

~~~
curl http://xx.xx.xx.xx1:3000/blocks | jq
~~~

 &emsp;4. ブロックチェーンの情報の例

~~~
100   529  100   529    0     0    529      0  0:00:01 --:--:--  0:00:01  6782
[
  {
    "hight": 0,
    "prev": "",
    "hash": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1",
    "nonce": "",
    "powcount": 0,
    "data": "Genesis Block",
    "timestamp": 0,
    "Child": null,
    "Sibling": null
  },
  {
    "hight": 1,
    "prev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1",
    "hash": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx2",
    "nonce": "&{xxxxxxx xxxxxxx x x}",
    "powcount": 59,
    "data": "\"Serial=xxxxx, slope=xx, intercept=xx, variance=xx\"",
    "timestamp": xxxxxxxxxx,
    "Child": [],
    "Sibling": []
  }
]
~~~

---
☆2021年11月 2日(火) 午前11時25分 初版(Ver1.00) 作成
☆2021年12月16日(木) 午後 2時50分 Ver1.01(Python プログラムにコメントを追加)
☆2021年12月17日(金) 午後 3時00分 Ver2.00(内容を再構成)
☆2021年12月20日(月) 午後10時35分 Ver2.10(③データをブロック・・・ に追加)

---