Beyond Blockchain One (BBc-1) のインストールと簡単な使い方

# はじめに
Beyond Blockchain One (BBc-1)とは、[一般社団法人ビヨンドブロックチェーン ](https://beyond-blockchain.org/)からリリースされた新しいブロックチェーン(ライクな何か)のオープン基盤です。BBc-1のリファレンス実装はPython3によるオープンソースでリリースされており、ちょこちょことアップデートされています([GitHub](https://github.com/beyond-blockchain/bbc1))。2018年1月28日現在でv0.8.0.1。

1つのチェーンが延々と繋がっていくブロック「チェーン」とは違い、BBc-1が構成するブロックごとのつながりはもう少し複雑なトレリス・メッシュ構造になっています。また、ブロックを閉じるために必要なのは、そのブロックに利害関係や責任関係を持つプレイヤーの正しい署名のみであり、パズルを解いた第三者の協力は不要です。詳細はGitHubにアップロードされている[ドキュメント](https://github.com/beyond-blockchain/bbc1/tree/develop/docs)を掘ってみると良いかと思いますが、要するに新しい構造を持つブロックチェーンです。あんまり正確ではありませんが、ざっと見ると[IOTAのtangle](https://iota.org/IOTA_Whitepaper.pdf)に近いっぽい気がします。

さて、この記事は[リファレンス実装のREADME.md](https://github.com/beyond-blockchain/bbc1/blob/develop/README.md)を参考に、そんなBBc-1のインストールと設定、そしてインターネット上の複数台のノードをつなげた簡単な使い方をまとめています。

# 環境

## ネットワーク環境
インターネット上に公開した複数のノードを接続することを目的としているので、まずはこの記事で想定しているネットワーク環境の前提条件を説明しましょう。大前提として、**IPv4環境を想定しています。** また、以下に図を書いていますが、

- 宅内LANに接続されたノード
- ロードバランサ経由で外部に公開されるAzureなどのクラウド上のノード

など、静的IPマスカレード(ポートフォワーディング)、あるいはNAT(Network Address Translation)が設定されており、グローバルアドレスの特定ポート経由でそれらへ疎通可能な環境のノードを想定しています。

```
node 1 [bbc1]
< ipv4 private address: A.A.A.A, exposed port: P1 >
   │
NAT gateway 1
< ipv4 global address: X.X.X.X, exposed port: P1 (forwarding to node 1) >
   │
The Internet
   │
NAT gateway 2
< IPv4 global address: Y.Y.Y.Y, exposed port: P2 (forwarding to node 2) >
   │
node 2 [bbc2]
< ipv4 private address: B.B.B.B, exposed port: P2 >
```

さてこのとき、それぞれのノード(`node 1`と`node 2`)は、非明示的には自身へ到達可能なグローバルアドレスを通知できない(そもそも意識しない)ため、相互接続するためには各ノードは明示的にそれらグローバルアドレスを他のノードへ通知する必要があります。BBc-1に限った話ではないのですが、グローバルアドレスを直に持っているようなノードは滅多に存在しないため、P2Pネットワークを構築するときにはこの機能が必須となります。BBc-1ではv0.8以降、この機能がサポートされるようになりました。[^NAPT]

[^NAPT]: NAPT(Network Address Port Translation)機能、即ち動的IPマスカレードはまだサポートされていません。

# ノードの準備
ノード(上の図の`node 1`と`node 2`)として、macOS High Sierra (10.13.3)、もしくはUbuntu 17.10を使います。Ubuntuについては16.04LTSでも良かったのですが、素で入れるとPythonパッケージが3.5だったりします。なので、[Readme.md](https://github.com/beyond-blockchain/bbc1/blob/develop/README.md)の要求条件に従って、Python3.6が使える17.10を使うこととしました。

各ノードでいくつか必要なパッケージを入れておき、BBc-1の設定準備をします。

macOS High Sierra:

```shell
$ brew update
$ brew install python3 libtool automake geth solidity pkg-config
```

Ubuntu17.10:

```shell
$ sudo apt-get update
$ sudo apt-get install -y git tzdata openssh-server python3 python3-dev python3-venv libffi-dev net-tools autoconf automake libtool libssl-dev make pkg-config
```

Ubuntu17.10では追加でpkg-configのインストールが必要です。


# BBc-1のインストールと起動準備
今回はソースをダウンロードしてセットアップする方法と、pip経由でインストールする方法を解説します。[^docker] これが終われば、ひとまずこれでスタンドアローンで動作するbbc1の環境が整います。

[^docker]: dockerコンテナを使ってもいいのですが、仮想ネットワーク上でさらにポートフォワードされることになり、余計な混乱を避けるため今回はスルーしています。

## ソースをダウンロードしてくる場合

1. まずは[GitHub](https://github.com/beyond-blockchain/bbc1)からソースをダウンロードしてきます。リリース向けの最新commitはdevelpブランチにあるようなので、そこを利用します。他に次期リリース向けの開発ブランチもあるようですので、最新機能に興味があればそこをチェックアウトするのが良いでしょう。

    ```shell
    $ git clone git@github.com:beyond-blockchain/bbc1.git
    $ cd bbc1
    $ git checkout develop
    ```

2. `bbc1/prepare.sh`を実行して、ブロックへ署名するのに利用されるOpenSSLをダウンロード・コンパイルします。

    ```shell
    $ bash prepare.sh
    ```

    少し時間がかかります……。

3. virtualenv環境を作成します。

    ```shell
    $ python3 -m venv .bbc1_venv
    $ source .bbc1_venv/bin/activate
    (.bbc1_venv)$ pip install --upgrade pip  ← pip自身のアップデート
    ```

    virtualenvは必須ではありませんが、環境整備のためにも利用したほうが良いでしょう。


4. virtualenv環境下で、必要なPyPIパッケージをインストールします。

    ```shell
    (.bbc1_venv)$ pip install -r requirements.txt
    ```

## pipを利用する場合
BBc-1はpip経由での簡単インストールも可能です。(bbc1>=0.8.0.1a0を利用しましょう)


1. virtualenv環境を作成します。

    ```shell
    $ python3 -m venv .bbc1_venv
    $ source .bbc1_venv/bin/activate
    (.bbc1_venv)$ pip install --upgrade pip  ← pip自身のアップデート
    ```

2. virtualenv環境下で、bbc1をインストールします。

    ```shell
    (.bbc1_venv)$ pip install wheel bbc1
    ```

    インストール中にOpenSSLのコンパイルが実行されるので、少し時間がかかります。

pipでインストールした場合、BBc-1の主要コマンドが実行可能な形式でvirtualenvへ導入されます。


# ノード同士の接続
さて、いよいよノード同士をBBc-1で接続します。早速デーモンを起動して……の前に、BBc-1の構成するネットワークについてちょっと理解が必要です。

BBc-1のデーモンは、互いにつながりIPネットワーク上に複数のオーバレイネットワークを作り出します。このとき、個々のオーバレイネットワークは「ドメイン(domain)」と呼ばれます。このドメインというのは、例えば会社内ネットワークなどに相当すると思えばいいでしょう。多分。そして、ドメイン指定で送信されたデータは、そのドメイン内でのみ流通されます。

BBc-1のデーモンを起動した直後、そのデーモンは何のドメインも作っておらず、また既存のドメインへも接続していません。この状態では何のデータのやり取りもなくただ止まっているだけです。従って、複数のノードをとりあえず接続するには、まずは各ノードが同じドメインへ参加できるようにドメイン設定を入れてやることになります。まずはこのドメイン設定例を紹介します。

## ドメイン設定
**最低限** のドメイン設定ファイルは以下のようなものになります。詳細なオプションは[Github (bbc1/utils/README.md)](https://github.com/beyond-blockchain/bbc1/blob/develop/utils/README.md)を参照してください。このとき重要なのは、１番はじめのkeyである`b7035...`です。これは *domain id* と呼ばれ、各BBc-1ノードで一致している必要があります。

```json:config.json
{
  "da799b7ffbf94e7908982c36e7ebfa6a1ae6c9744b4d24d241f711a5d6d0eacd": {
    "module": "simple_cluster",
    "asset_group_ids": {
    },
    "static_nodes": {
    }
  }
}
```
上記の設定ファイル config.json は、各ノード(`node 1`と`node 2`)へコピーして共有してください。

domain idは単純にhexで作ってもいいんですが、法則性をもたせたいのであれば、可読性のある名称(e.g., example.com)のハッシュ値などを利用するのが良いでしょう。このために、BBc-1ではハッシュ値生成の機能が用意されています。


ソースからインストールした場合:

```shell
$ cd /path/to/bbc1
$ source .bbc1_venv/bin/activate
(.bbc1_venv)$ cd utils
(.bbc1_venv)$ python bbc_system_conf.py -i "desired string"
da799b7ffbf94e7908982c36e7ebfa6a1ae6c9744b4d24d241f711a5d6d0eacd
```

pipでインストールした場合:

```shell
$ source .bbc1_venv/bin/activate
(.bbc1_venv)$ bbc_system_conf.py -i "desired string"
da799b7ffbf94e7908982c36e7ebfa6a1ae6c9744b4d24d241f711a5d6d0eacd
```


## ノード同士の接続
さて、準備が整いました。BBc-1デーモン(`bbc_core.py`)を起動しましょう。起動方法は、ざっくり以下となります。

```shell
# ソースからインストールした場合
(.bbc1_venv)$ python ./bbc_core.py -pp <exposed port> --ip4addr <ipv4 address reachable to the node>

# pipからインストールした場合
(.bbc1_venv)$ bbc_core.py -pp <exposed port> --ip4addr <ipv4 address 
reachable to the node>
```

ここで、`-pp`は、外部から接続するために公開するためのポートです。同様に、`--ip4addr`は外部から接続可能なグローバルアドレスです。詳細な起動オプションは`bbc_core.py -h`で確認することが出来ます。

また、ドメイン設定ファイルを内部へ読み込む方法は以下の通りです。

```shell
# ソースからインストールした場合
(.bbc1_venv)$ python ./bbc_system_conf.py <configuration file>

# pipからインストールした場合
(.bbc1_venv)$ bbc_system_conf.py <configuration file>
```

冒頭の図の`node 1`と`node 2`であれば、`node 1`は`X.X.X.X:P1`で、`node 2`は`Y.Y.Y.Y:P2`で外部から接続可能です。これより、実行するコマンドは以下の通りです。

- `node 1`:

```shell
$ source .bbc1_venv/bin/activate
# ソースからインストールした場合
(.bbc1_venv)$ cd bbc1/core
(.bbc1_venv)$ python ./bbc_core.py -d -pp P1 --ip4addr X.X.X.X -l /var/tmp/bbc1.log
(.bbc1_venv)$ cd ../../utils/
(.bbc1_venv)$ python ./bbc_system_conf.py /path/to/config.json

# pipからインストールした場合
(.bbc1_venv)$ bbc_core.py -d -pp P1 --ip4addr X.X.X.X -l /var/tmp/bbc1.log
(.bbc1_venv)$ bbc_system_conf.py /path/to/config.json
```

- `node 2`:

```shell
$ source .bbc1_venv/bin/activate
# ソースからインストールした場合
(.bbc1_venv)$ cd bbc1/core
(.bbc1_venv)$ python ./bbc_core.py -d -pp P2 --ip4addr Y.Y.Y.Y -l /var/tmp/bbc1.log
(.bbc1_venv)$ cd ../../utils/
(.bbc1_venv)$ python ./bbc_system_conf.py /path/to/config.json

# pipからインストールした場合
(.bbc1_venv)$ bbc_core.py -d -pp P2 --ip4addr Y.Y.Y.Y -l /var/tmp/bbc1.log
(.bbc1_venv)$ bbc_system_conf.py /path/to/config.json
```

ここで、`bbc_core.py`の起動オプションに`-d`および`-l /var/tmp/bbc1.log`を追加設定することで、それぞれバックグラウンド動作（デーモン化）とログ出力を行っています。

さて、片一方のノードから`bbc_ping.py`を当該のdomain idを含めて他方へ打ち込んでやることで、そのドメインにおいて両者を接続します。

```shell
# ソースからインストールした場合
$ python bbc_ping.py <domain id> <destination address> <destination address>

# pipからインストールした場合
$ bbc_ping.py <domain id> <destination address> <destination address>
```

今回の例で、`node 1`から`node 2`へ打ち込む場合には、`node 1`において以下を実行します。

```shell
# ソースからインストールした場合
(.bbc1_venv)$ python bbc_ping.py da799b7ffbf94e7908982c36e7ebfa6a1ae6c9744b4d24d241f711a5d6d0eacd Y.Y.Y.Y P2

# pipからインストールした場合
(.bbc1_venv)$ bbc_ping.py da799b7ffbf94e7908982c36e7ebfa6a1ae6c9744b4d24d241f711a5d6d0eacd Y.Y.Y.Y P2
```


## ステータス確認
最後に接続ステータスの確認をしましょう。`bbc_system_conf.py -l`を利用することで、そのノードが参加している各ドメインにおける接続ノードの一覧を出力することができます。今回の例で、`node 1`では以下のようになります。

```shell
# ソースからインストールした場合
(.bbc1_venv)$ python ./bbc_system_conf.py -l

# pipからインストールした場合
(.bbc1_venv)$ bbc_system_conf.py -l
b'\xda\x79\x9b\x7f\xfb\xf9\x4e\x79\x08\x98\x2c\x36\xe7\xeb\xfa\x6a\x1a\xe6\xc9\x74\x4b'
====== peer list of domain:da799b7ffbf94e7908982c36e7ebfa6a1ae6c9744b4d24d241f711a5d6d0eacd =====
*myself*    b'afee3ecc', X.X.X.X, ::, P1
            b'bce7091e', Y.Y.Y.Y, ::, P2
```

# サンプルプログラム(file_proof.py)の動作
さて、今度は複数ノード間でサンプルプログラム`file_proof.py`を動作させてみましょう。この`file_proof.py`というのは、BBc-1のアプリケーション(bbc_app)という位置づけになります。`bbc_core.py`のデーモンのAPIを叩いて、ファイルをトランザクションとしてBBc-1のネットワークへ登録、そして更新することができます。ただし、実際にトランザクションとして登録されるのはファイルのハッシュ値になります。そのため、他のノードへファイルの実体がコピーされるわけではありません。巨大なファイルを送りつけられても困りますよね。ですが、登録されたファイルの実体もBBc-1のネットワークを通してドメインの他のノードと送受信（移転）が可能です。そして **送信されてきたファイルが正しいものかどうかをBBc-1に登録されたトランザクションを検証することで確認することができます。**

ブロックチェーンは取引履歴を連鎖させて記録していくもので、その連鎖を検証することで現在の取引が正しいものかどうかを確認するシステムです。BBc-1のこのサンプルプログラムは、その取引履歴をファイルそのものへと概念拡張したものに当たります。即ち、**ファイルそのものが正しいものかどうか検証すること、そしてファイルに対して為されてきた操作のログを検証することを実現しています。** (ただし、`file_proof.py`はあくまで簡易版です。)

## 準備
BBc-1が動いていて、適切なvirtualenvを有効化している前提で、参加する *全ノード* で以下の準備を行います。

1. BBc-1のノードは自分自身に固有の公開鍵・秘密鍵のペアを持ちます。これにより、トランザクションに対する署名と、その検証を実行するわけですね。なにはともあれ、まずはそれを作成することが必要です。

    ```shell
    # ソースからインストールした場合
    (.bbc1_venv)$ python file_proof.py keypair
    created private_key and public_key : .private_key, .public_key

    # pipからインストールした場合
    (.bbc1_venv)$ file_proof.py keypair
    created private_key and public_key : .private_key, .public_key
    ```


2. 続いて、domain idと登録するファイルのグループ (asset group) を作成します。ドメインはデータの物理的な流通範囲、asset groupは流通されるデータの種類を表すと考えれば良いようです。

    ```shell
    # ソースからインストールした場合
    (.bbc1_venv)$ python file_proof.py setup
    Domain df6b3b7e and asset_group 45b2a200 are created.
    Setup is done.

    # pipからインストールした場合
    (.bbc1_venv)$ file_proof.py setup
    Domain df6b3b7e and asset_group 45b2a200 are created.
    Setup is done.
    ```

    domain idとasset groupが作成されました。

3. 前節では、domainを作成・指定した上で他方のノードに対して`bbc_ping.py`を打ち込んでいましたが、今回も同じように片方から打ち込んでこのドメイン内で全ノードを接続しておきます。`node 1`から`node 2`へ以下のように打ち込みます。

    ```shell
    # ソースからインストールした場合
    (.bbc1_venv)$ python bbc_ping.py df6b3b7efd636294a428a0a9d5d0c1a0723b1b64f61a754486ad4954e6c3831f Y.Y.Y.Y P2

    # pipからインストールした場合
    (.bbc1_venv)$ bbc_ping.py df6b3b7efd636294a428a0a9d5d0c1a0723b1b64f61a754486ad4954e6c3831f Y.Y.Y.Y P2
    ```

    念のため、`bbc_system_conf.py -l`で確認しておきましょう。

    ```
    b'\xdfk;~\xfdcb\x94\xa4(\xa0\xa9\xd5\xd0\xc1\xa0r;\x1bd\xf6\x1auD\x86\xadIT\xe6\xc3\x83\x1f'
    ====== peer list of domain:df6b3b7efd636294a428a0a9d5d0c1a0723b1b64f61a754486ad4954e6c3831f =====
    *myself*    b'e8855c2b', X.X.X.X, ::, P1
                b'96785a4a', Y.Y.Y.Y, ::, P2
    ```

    接続されました。

## ファイルの登録・更新

さて、まずは`node 1`でサンプルファイルを作って、それを実際に登録してみましょう。

```shell
(.bbc1_venv)$ echo "this is the first sample." > sample.txt

# ソースからインストールした場合
(.bbc1_venv)$ python file_proof.py store sample.txt -o node-1

# pipからインストールした場合
(.bbc1_venv)$ file_proof.py store sample.txt -o node-1
```

ここでは、`-o node-1`で、ユーザ名`node-1`を指定して登録しています（これは本来不要です）。
上記作業により、BBc-1のトランザクションに`sample.txt`のハッシュ値が`node 1`の署名付きで登録されました。同時に、BBc-1の一時ディレクトリ(`bbc_core.py`を起動したディレクトリ内の`.bbc1`)に`sample.txt`の実体がコピーされています。

ファイル更新に伴うトランザクション登録は、同様に以下のように行なえます。

```shell
(.bbc1_venv)$ echo "this is the second sample." > sample.txt

# ソースからインストールした場合
(.bbc1_venv)$ python file_proof.py update sample.txt -o node-1

# pipからインストールした場合
(.bbc1_venv)$ file_proof.py update sample.txt -o node-1
```

この操作により、前回登録のトランザクションからハッシュチェーンで繋がった新しいトランザクションを生成、登録しています。

## ファイルの移転
続いて、このファイルを`node 1`から`node 2`へ送って（移転させて）みましょう。

1. まず、`node 2`で待ち受けます。

    ```shell
    # ソースからインストールした場合
    (.bbc1_venv)$ file_proof.py wait -o node-2

    # pipからインストールした場合
    (.bbc1_venv)$ file_proof.py wait -o node-2
    Your name is [ node-2 ] and user_id is [ 1779f59f4df251f6b81aeb08fb52a5d84ad4eef833c7fdf0bc576cd1aab11d24 ]
    Waiting for file transfer.....
    ```

    この時、ユーザ名を`node-2`としていることに注意してください。

2. そして`node 1`で、ユーザ名`node-2`のノードへファイル`sample.txt`を送信します。
対話型で送信先ユーザ名を聞かれるので、`node-2`と入力します。

    ```shell
    # ソースからインストールした場合
    (.bbc1_venv)$ python file_proof.py send sample.txt -o node-1

    # pipからインストールした場合
    (.bbc1_venv)$ file_proof.py send sample.txt -o node-1
    Your name is [ node-1 ] and user_id is [ 35971be6e9bb024a895582fe0e42e04848a86da550aaef0fccbfba86f99f617d ]
    Please enter the receiver user_id for file sample.txt.
    >> node-2
    Insert the transaction into BBc-1
    Transfer is done.....
    ```

    この操作により、まず`node 1`は自分の秘密鍵により署名されたトランザクションの元を作成します。それを`node 2`へと送りつけ、`node 2`の署名を求めることとなります。
このステップで、`node 1`が自分の署名を付与することは、`node 1`にとって、**当該のファイルの所有権を移転することを同意する** ということを意味します。

3. `node 2`では、以下のようなメッセージが出てきます。
BBc-1に記録されているファイルのハッシュ値と、送信されてきたファイル自身から計算されたハッシュ値とが出てくるので、それを見比べて「Y」をプレスしてファイルを受信します。

    ```shell
    --------------------------
    File digest written in the transaction data:   4d59db35d38ae507a96c375eb7b1bf95580f598990e1be5ac82467c5611c0e66
    File digest calculated from the received file: 4d59db35d38ae507a96c375eb7b1bf95580f598990e1be5ac82467c5611c0e66
    --------------------------
    ====> Do you want to accept the file?
    (Y/N) >> Y
    Waiting for the message from the sender...
    --> file name is sample.txt and the transaction_id is 323410bf8b012a15865538c217a38c85e58b5220d7d23b8343b9e7a1983eb0b3
    ```

    注意すべきは、このファイルの送信そのものも「ファイルの所有権の移転」という形でトランザクションとして記録されていることです。

    送受信によって`node 1`と`node 2`の同意の元に`node 2`へと所有権が移転され、`node 1`と`node 2`の署名が付与されたトランザクションを生成、`node 1`はそのトランザクションをBBc-1へ記録することになります。この最後のステップにおいて「Y」をプレスする行為は、`node 2`にとって **当該のファイルの所有権を移転することを同意する** ということを意味し、その同意の結果としての署名付与となるわけです。


## 取得・検証
`node 2`で受信したファイルは、そのままカレントディレクトリに保存されるわけではなく、やはりBBc-1の一時ディレクトリ`.bbc1`に保存されます。
今度はそのファイルを取り出して、BBc-1のトランザクションを検証、正しく自分の署名がついている（所有権は正しく自分に移った）のかどうか検証してみましょう。

以下のコマンドを実行することで、カレントディレクトリに`sample.txt`がコピーされます。

```shell
# ソースからインストールした場合
(.bbc1_venv)$ python file_proof.py get sample.txt

# pipからインストールした場合
(.bbc1_venv)$ file_proof.py get sample.txt
done get sample.txt
```

それでは、取得したファイルを検証してみます。

`sample.txt`のハッシュ値を入れたBBc-1のトランザクションデータには、`node 1`の公開鍵も含まれており、それ込みで署名が為されています。

```shell
# ソースからインストールした場合
(.bbc1_venv)$ python file_proof.py verify sample.txt

# pipからインストールした場合
(.bbc1_venv)$ file_proof.py verify sample.txt
sample.txt is valid
done verify sample.txt
Content of the transaction:::
------- Dump of the transaction data ------
transaction_id: b'323410bf8b012a15865538c217a38c85e58b5220d7d23b8343b9e7a1983eb0b3'
version: 0
timestamp: 1517080586
Event[]:
[0]
  asset_group_id: b'45b2a200ccdcdcc3fb80cc9d423e1069f3ca726157f6492b4a70a48e4a1713ab'
  reference_indices: []
  mandatory_approvers: ← このトランザクションを引き継いで次のトランザクションにつなげる際、次のトランザクションに必要な利害関係者のリスト
    -  b'1779f59f4df251f6b81aeb08fb52a5d84ad4eef833c7fdf0bc576cd1aab11d24' ← node 2のユーザID、所有権がnode 2に移るので次はnode 2が責任を持つ
  option_approvers:
    - NONE
  option_approver_num_numerator: 0
  option_approver_num_denominator: 0
  Asset:
     asset_id: b'8120f01b8824ed01a928f6b9ba37031501221f2ffc81aacda075ad0a8df02c1d'
     user_id: b'1779f59f4df251f6b81aeb08fb52a5d84ad4eef833c7fdf0bc576cd1aab11d24'
     nonce: b'2af0862b6f73c1b0'
     file_size: 27
     file_digest: b'4d59db35d38ae507a96c375eb7b1bf95580f598990e1be5ac82467c5611c0e66'
     body_size: 45
     body: b'Ownership is transfered from node-1 to node-2'
Reference[]: 1
[0]
  asset_group_id: b'45b2a200ccdcdcc3fb80cc9d423e1069f3ca726157f6492b4a70a48e4a1713ab'
  transaction_id: b'82ab430cec10101be5f22a239ff32f27f14e6c54a3e82606360227750fa96d01' ← 前のトランザクション
  event_index_in_ref: 0
  sig_index: [0]
Cross_Ref[]: 0
  None
Signature[]:
[0]
  type: 1
  signature: b'2ac0b3e1c7e182aacf040f73285ae9de91ef8584d23f0333cabfe66ae31fad3f5437510a9481e5cbc2a5ec07c6d312675677c471e4556dbb455f8e179bd045b1' ← node 1による署名
  pubkey: b'04170e4a803fcd57554539eb7551427f23c0363651a2cc469d536cd1fc9029b5cfab2100013efc70f0ddc8c02b72696bfb2aa6b619aace2744c46f47b5b8c3844b' ← node 1の公開鍵
[1]
  type: 1
  signature: b'd427e81be2fd86025c97e953c2cd189d04d405f1967ecc021ed88d5b329496407b4e7b7a8e58a5c14622ce5b90278682608e1e00777e9a9b13dd4fe7e6a54273' ← node 2による署名
  pubkey: b'049ffdabb3b9774de98c9073eaf3dff89ceb4ac8d94a634830e701645f7d41833050d6c3f29d8593d507b5d8522565786ff116d5ce1ffd2ca7e2bb47593463ec55' ← node 2の公開鍵
```

上記のように、`node 1`および`node 2`の公開鍵でトランザクションを検証して、その結果が正しいという`sample.txt is valid`の表示と同時に、検証したトランザクションの中身が表示されます。

それぞれのフィールドにどういう意味があるかという詳細は、[GitHub](https://github.com/beyond-blockchain/bbc1) の公式ドキュメントを参照してください。

※ [2018-1-28現在] 上記は、手元で若干修正した`file_proof.py`を利用しています。現在リリースされている公式バージョンでは`node 2`の署名が付与されないバグがあります。そのうち修正が反映されると思います。



# まとめと雑感
触っていて色々足りないなーって思うことがありました。例えばネットワーク周りでは

- FQDNへの対応 (IPv4アドレス直打ちよりハートに優しい)
- NAPTへの対応

とか。DHCPで外向きのアドレスが変わるような環境を考慮すると現状バージョンではなかなか厳しそうで、将来的にはもう少し考慮が必要そうです。

他にはそもそもブロックチェーンじゃないというものもあり、中身を理解するのが結構大変な印象です。もっとキャッチーに理解できるようにしたり、どこか接続できる公開ノードを用意したほうがいいですね。この辺はボランティアベースなのかしら。

と、普及方法が若干難ありなものの、思想や作り自体は、「やり取りしているプレイヤー同士の合意」のみで成り立っているというブロックチェーンの要素を抜き出してきたようなものでもあり、とても面白いです。おそらく利用シーンは素のブロックチェーンを使うよりも遥かに広いでしょう。[^incentive] 個人的にも引き続きBBc-1を触り続けて遊んでみます。

[^incentive]: インセンティブもないようなシステムにマイニング入れようとしてる人たちは一回ドキュメントでも読めばいいです。また、インセンティブなしで誰が公開システムに参加するのかも考えたほうがいいです。