LoginSignup
16
19

More than 5 years have passed since last update.

BigchainDBでブロックチェインを体験する

Last updated at Posted at 2017-08-18

はじめはこの辺の記事を読み漁った。
https://www.slideshare.net/cookle/5-58379474
http://qiita.com/hshimo/items/1881fba8957c2a6e17ca
http://qiita.com/akitoh/items/bebf1bf3d71d3e4b96b0

で、ブロックチェインがすごくて役に立つのはわかった。

ざっくりしかわかってないが、ともかく動かしたい。間違ってたら突っ込んで頂ければと。
前から気になってたbigchaindbってライブラリを使ってみる。スケーラブルなブロックチェインdbだよと書いてある。
純粋なp2pって感じではなく分散DBとブロックチェーンが融合したライブラリ。

BigchainDB ユースケース

ライセンシングチェーンに沿ったプロパティアセットの追跡

BigchainDBは、クリエイターと視聴者を結ぶチャネルのライセンス争奪を減らし、デジタルアーチファクトに完璧な出資を提供します。 典型的な音楽サービスには3800万曲があります.BigchainDBはこの情報をハートビートで保存することができ、各曲のライセンス情報や加入者の使用に関する情報も保存できます。 別の例では、1日に100,000トランザクションを実行する中規模の写真市場を考えてみましょう。 これをBitcoinに適用すると、1日あたり10,000ドルの費用がかかり、Bitcoinネットワークが繋がります。

レセプト、および証明書。

BigchainDBは、電子的な行動の反駁できない証拠を提供することによって法的な摩擦を減らします。 また、BigchainDBは、ドキュメントにリンクしたり、ハッシュを格納したりするのではなく、レセプトや証明書(COA)などのサポート情報を直接格納することができます。

略〜

伝統的なブロックチェインとの違い

前回のブロックとハッシュで繋ぐ訳ではない。ブロック内部に投票リストというものを保持してる。署名ノードが投票する。ブロックの賛成投票の過半数を得たら有効になる。そして投票時に連鎖が起こる。

スクリーンショット 2017-08-30 21.12.20.png

専門用語

BigchainDB Node

BigchainDBノードは、MongoDBサーバー、BigchainDBサーバーを実行しているマシンのセットです。各ノードは、個人または組織によって制御されます。

BigchainDB Cluster

BigchainDBノードのセットは、相互に接続してBigchainDBクラスターを形成できます。
クラスタ内の各ノードは同じソフトウェアを実行します。クラスタには、1つの論理MongoDBデータストアが含まれています。

BigchainDB Consortium

クラスタ内でノードを実行する人や組織は、BigchainDBコンソーシアム(別の組織)に属します。コンソーシアムには、意思決定を行うためのガバナンス構造が必要です。ある企業がクラスタを運営している場合、「コンソーシアム」はその会社だけです。
クラスタは、接続されたノードの集まり。コンソーシアムは、クラスタを持ち、クラスタ内の各ノードに異なるオペレーターがある組織です。
オペレーターってなんだろう・・・
ともかくコンソーシアムの下にクラスタ、クラスタの下にノードがあるイメージと解釈。

ドキュメント構成

スクリーンショット 2017-08-19 3.20.30.png

上位レベルでは、BigchainDB Client-Server HTTP API、またはそのAPIのラッパー(BigchainDB Python Driverなど)を使用して、BigchainDBクラスター(ノードのセット)と通信できる。
BigchainDB Python DriverはBigchainDBノードへのトランザクションの準備、実行、および送信のサポート。idによるトランザクションの取得。 idでトランザクションのステータスを取得します。

サーバー側:server docs、server quickstart、http api docs
クライアント側:python driver docs
その他:comannd line tran... tool

環境

ubuntu14 or mac
python3
conda
DBはRethinkDB か MongoDBを選択だが、RethinkDBはまだサポートされるのか?

BigchainDB Serverの設定

サーバー側の設定であります。

python環境周りインストール

python3系じゃないと動かないので、condaでpython3系に切り替えた。

condaについてはこちら
http://qiita.com/miyamotok0105/items/5f26e4ae41f0e35ded16

sudo apt-get update
sudo apt-get install g++ python3-dev libffi-dev build-essential libssl-dev
sudo apt-get install python3-pip
sudo pip3 install --upgrade pip setuptools
sudo pip3 install bigchaindb
bigchaindb -y configure mongodb

mongo3.4以上を入れる

そもそもmongoとはこちら。JSONベースのdbで、型とか考えなくて放り込めます。
http://qiita.com/saba1024/items/f2ad56f2a3ba7aaf8521

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6
echo "deb [ arch=amd64 ] http://repo.mongodb.org/apt/ubuntu precise/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list
sudo apt-get update
sudo apt-get install -y mongodb-org
mongo --version
sudo mkdir -p /data/db
sudo chmod -R 700 /data/db

設定

サーバーで動かしてる場合はipかドメインの部分を変更

sudo emacs ~/.bigchaindb

"server": {"bind": "localhost:9984", ... }
to
"server": {"bind": "0.0.0.0:9984", ... }

0.0.0.0を自分のサーバーの情報へ

参照
https://docs.bigchaindb.com/projects/server/en/latest/production-nodes/setup-run-node.html

起動

MongoDB起動

sudo mongod --replSet=bigchain-rs

これでエラーになった。ならない人は読み飛ばしてOK。
前に入れたmongoが邪魔してる。下記で解決。
http://kiita312.hatenablog.com/entry/2013/03/03/130935

bigchain-rsを起動した状態でコンソールをもう一個立てる。

BigchainDB Server起動

bigchaindb start

ドワーっとログが出て動く。
こ。こいつ動くぞ。

****************************************************************************
*                                                                          *
*   Initialization complete. BigchainDB Server is ready and waiting.       *
*   You can send HTTP requests via the HTTP API documented in the          *
*   BigchainDB Server docs at:                                             *
*    https://bigchaindb.com/http-api                                       *
*                                                                          *
*   Listening to client connections on: localhost:9984                     *
*                                                                          *
****************************************************************************
 (MainProcess - pid: 15547)
======== Running on http://localhost:9985 ========
(Press CTRL+C to quit)
[2017-08-19 02:47:02] [INFO] (gunicorn.error) Starting gunicorn 19.7.1 (webapi     - pid: 15680)
[2017-08-19 02:47:02] [INFO] (gunicorn.error) Listening at: http://127.0.0.1:9984 (15680) (webapi     - pid: 15680)
[2017-08-19 02:47:02] [INFO] (gunicorn.error) Using worker: sync (webapi     - pid: 15680)
[2017-08-19 02:47:02] [INFO] (gunicorn.error) Booting worker with pid: 15685 (webapi     - pid: 15685)
[2017-08-19 02:47:02] [INFO] (gunicorn.error) Booting worker with pid: 15686 (webapi     - pid: 15686)
[2017-08-19 02:47:02] [INFO] (gunicorn.error) Booting worker with pid: 15687 (webapi     - pid: 15687)
[2017-08-19 02:47:02] [INFO] (gunicorn.error) Booting worker with pid: 15688 (webapi     - pid: 15688)
[2017-08-19 02:47:03] [INFO] (gunicorn.error) Booting worker with pid: 15689 (webapi     - pid: 15689)
[2017-08-19 02:47:07] [INFO] (bigchaindb.backend.mongodb.connection) Closing initial connection to MongoDB (Process-16 - pid: 15659)


localhost:9984の部分にアクセス。

ブラウザで叩くと何かしら返って来る

{
  "api": {
    "v1": {
      "assets": "/api/v1/assets/", 
      "docs": "https://docs.bigchaindb.com/projects/server/en/v1.0.1/http-client-server-api.html", 
      "outputs": "/api/v1/outputs/", 
      "statuses": "/api/v1/statuses/", 
      "streams": "ws://localhost:9985/api/v1/streams/valid_transactions", 
      "transactions": "/api/v1/transactions/"
    }
  }, 
  "docs": "https://docs.bigchaindb.com/projects/server/en/v1.0.1/", 
  "keyring": [], 
  "public_key": "HPxXw3Kbkj8BVvgR49xa7jaUkHpmmqwL39pmk5qpbdjQ", 
  "software": "BigchainDB", 
  "version": "1.0.1"
}

BigchainDB Python Driver

クライアント側から叩く。

インストール

pip3 install bigchaindb_driver
or
pip install bigchaindb_driver

Asset Creation & Transfer アセットクリエーションと転送

アセットって資産的な意味があるので、データは資産ってイメージ?
モォ眠い。
bikeはAliceさんのものでBobさんに渡す処理を仮定する。
コメントに処理の解釈を記載した。

# -*- coding: utf-8 -*-
from bigchaindb_driver import BigchainDB
from bigchaindb_driver.crypto import generate_keypair
from time import sleep
from sys import exit

#暗号ペア生成
alice, bob = generate_keypair(), generate_keypair()

bdb_root_url = 'http://0.0.0.0:9984'  # BigchainDB Root URLに書き換えて!!

bdb = BigchainDB(bdb_root_url)

#アセット定義
bicycle_asset = {
    'data': {
        'bicycle': {
            'serial_number': 'abcd1234',
            'manufacturer': 'bkfab'
        },
    },
}
#オプションでメタデータをトランザクションに追加できる
bicycle_asset_metadata = {
    'planet': 'earth'
}

#Assetクリエーション
#RDBのレコードの代わりにbigchainではtransaction単位でデータが保存される。
#transactionの用意をしている。
prepared_creation_tx = bdb.transactions.prepare(
    operation='CREATE',
    signers=alice.public_key,
    asset=bicycle_asset,
    metadata=bicycle_asset_metadata
)

#トランザクションは、Aliceの秘密鍵で署名することで実現する必要があります。
fulfilled_creation_tx = bdb.transactions.fulfill(
    prepared_creation_tx,
    private_keys=alice.private_key
)

#BigchainDBノードに送信!!!
sent_creation_tx = bdb.transactions.send(fulfilled_creation_tx)

txid = fulfilled_creation_tx['id']

#トランザクションが有効になるまでトランザクションのステータスをチェックし続ける
trials = 0
while trials < 60:
    try:
        if bdb.transactions.status(txid).get('status') == 'valid':
            print('Tx valid in:', trials, 'secs')
            break
    except bigchaindb_driver.exceptions.NotFoundError:
        trials += 1
        sleep(1)

if trials == 60:
    print('Tx is still being processed... Bye!')
    exit(0)

asset_id = txid

transfer_asset = {
    'id': asset_id
}

output_index = 0
output = fulfilled_creation_tx['outputs'][output_index]

transfer_input = {
    'fulfillment': output['condition']['details'],
    'fulfills': {
        'output_index': output_index,
        'transaction_id': fulfilled_creation_tx['id']
    },
    'owners_before': output['public_keys']
}

#アセットクリエーション
prepared_transfer_tx = bdb.transactions.prepare(
    operation='TRANSFER',
    asset=transfer_asset,
    inputs=transfer_input,
    recipients=bob.public_key,
)

fulfilled_transfer_tx = bdb.transactions.fulfill(
    prepared_transfer_tx,
    private_keys=alice.private_key,
)

sent_transfer_tx = bdb.transactions.send(fulfilled_transfer_tx)

print("Is Bob the owner?",
    sent_transfer_tx['outputs'][0]['public_keys'][0] == bob.public_key)

print("Was Alice the previous owner?",
    fulfilled_transfer_tx['inputs'][0]['owners_before'][0] == alice.public_key)


bikeはbobの元にある。
前のオーナーはaliceだよ。って結果が見れた。

Tx valid in: 0 secs
Is Bob the owner? True
Was Alice the previous owner? True

概要はprepareしてfulfillしてsendする。

Library Reference

  • class bigchaindb_driver.BigchainDB

BigchainDB driver class

bigchaindb_driver.driver.TransactionsEndpoint

  • fulfill

指定のトランザクションを実行する。

返り値:fulfilled(完了した)トランザクションペイロードは、BigchainDBフェデレーションに送信する準備のdict

  • prepare

トランザクションペイロードの準備、fulfilledに備える。
operationでCREATEかTRANSFERが選べる。

返り値:prepared transactionのdict

  • send

フェデレーションに取引を提出する。

返り値:フェデレーションノードに送信されたトランザクションのdict

他にもあるが詳細は下記
https://docs.bigchaindb.com/projects/py-driver/en/latest/libref.html?highlight=prepare#driver

最後に

次に記事を書くときはモォ少し取引の転送とかapi周りについて深ぼってみる予定。

ps

nodeバージョンもdockerでバッチリdemoが動きました。
https://github.com/bigchaindb/bigchaindb-examples

16
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
19