- pip でインストールが可能。
$ pip install bigchaindb_driver
- BigchainDBへの接続は以下のようにして行う。
In [XX]: from bigchaindb_driver import BigchainDB
In [XX]: bdb = BigchainDB('http://localhost:9984')
- Asset定義はJSON記法で定義する。ここでは例として「bicycle」アセットを定義する。
- dataフィールドに独自のアセット定義する。
- メタ情報は任意設定である。設定しなくてもいい。
In [XX]: bicycle = {
...: 'data': {
...: 'bicycle': {
...: 'serial_number': 'abcd1234',
...: 'manufacturer': 'bkfab',
...: },
...: },
...: }
...:
In [XX]: metadata = {'planet': 'earth'}
- 鍵の生成を行う。2人分(例ではaliceとbob)まとめてだと下記のようにして生成する。
In [XX]: from bigchaindb_driver.crypto import generate_keypair
In [XX]: alice, bob = generate_keypair(), generate_keypair()
- それぞれの鍵情報をprintしてみると下記のような出力が得られる。本番運用では、秘密鍵(private_key)の情報はセキュアな格納先に保存する。
In [XX]: print(alice)
CryptoKeypair(private_key='GWNWLC5n92GP6u2NoCG12zf1e38fyb4cCq47zyEPwiiR', public_key='2acjECeGPGNv9Meod7up3YrTrcDB8vZKUpmjJMyrUZ9s')
In [XX]: print(bob)
CryptoKeypair(private_key='6QBdCDUEVDRiTpQP8EVx9XDYsdug2FUPFUVrE34cdFwc', public_key='9npkmGcQPFZJeHxSSQSjVRgSJ1RE75tXDDPcgNxfsLrF')
- Asset作成用のトランザクションを生成する。
- Asset作成はaliceが自身を送付先とするトランザクションを起こすことで実現する。
In [XX]: prepared_creation_tx = bdb.transactions.prepare(
...: operation='CREATE',
...: signers=alice.public_key,
...: asset=bicycle,
...: metadata=metadata,
...: )
...:
- 生成したトランザクション(
prepared_creation_tx
)の内容を見てみる。
In [XX]: prepared_creation_tx
Out[XX]:
{'asset': {'data': {'bicycle': {'manufacturer': 'bkfab',
'serial_number': 'abcd1234'}}},
'id': '34be88811a133aae6ef1877f7c4001f2b58221e016bfa72cef1c3765d13f1f45',
'inputs': [{'fulfillment': {'public_key': '2acjECeGPGNv9Meod7up3YrTrcDB8vZKUpmjJMyrUZ9s',
'type': 'ed25519-sha-256'},
'fulfills': None,
'owners_before': ['2acjECeGPGNv9Meod7up3YrTrcDB8vZKUpmjJMyrUZ9s']}],
'metadata': {'planet': 'earth'},
'operation': 'CREATE',
'outputs': [{'amount': '1',
'condition': {'details': {'public_key': '2acjECeGPGNv9Meod7up3YrTrcDB8vZKUpmjJMyrUZ9s',
'type': 'ed25519-sha-256'},
'uri': 'ni:///sha-256;RnubGL2YaZV0IW7jlzChuVDDFPlXMgI4ZzW2Va4QG9w?fpt=ed25519-sha-256&cost=131072'},
'public_keys': ['2acjECeGPGNv9Meod7up3YrTrcDB8vZKUpmjJMyrUZ9s']}],
'version': '1.0'}
-
operation
はCREATE
-
asset
,metadata
には上で定義した情報が記録される。 -
id
は transaction-id を意味する。トランザクション毎に異なる値が設定される。 -
transaction prepare 時の
inputs
には、平文の情報が格納されているのがわかる。public_key
、owners_before
には作成者(今回の場合、alice)の public_key が設定される。 -
今回の例では、 alice 1人を宛先にしているので、
outputs
の list は alice 向けの1つのみである。public_key
として 、 alice の public_key が設定される。 -
次に、 alice の秘密鍵(
alice.private_key
)でトランザクションを署名する。
In [XX]: fulfilled_creation_tx = bdb.transactions.fulfill(
...: prepared_creation_tx, private_keys=alice.private_key)
...:
- 署名後のトランザクションの状態は以下のようになる。
In [XX]: fulfilled_creation_tx
Out[XX]:
{'asset': {'data': {'bicycle': {'manufacturer': 'bkfab',
'serial_number': 'abcd1234'}}},
'id': '34be88811a133aae6ef1877f7c4001f2b58221e016bfa72cef1c3765d13f1f45',
'inputs': [{'fulfillment': 'pGSAIBd4QGCf9TOBun18reMl0SbWm_4GQ_4FzLrI6avAHslKgUBycAmo9ecDDNhYN2UhM6utgDEYw6Fa1cs4vmkyZ0126v3y1xBEFOJb2ezyMT_nuIGH1ZKcHBBGnruxwf6xP_4M',
'fulfills': None,
'owners_before': ['2acjECeGPGNv9Meod7up3YrTrcDB8vZKUpmjJMyrUZ9s']}],
'metadata': {'planet': 'earth'},
'operation': 'CREATE',
'outputs': [{'amount': '1',
'condition': {'details': {'public_key': '2acjECeGPGNv9Meod7up3YrTrcDB8vZKUpmjJMyrUZ9s',
'type': 'ed25519-sha-256'},
'uri': 'ni:///sha-256;RnubGL2YaZV0IW7jlzChuVDDFPlXMgI4ZzW2Va4QG9w?fpt=ed25519-sha-256&cost=131072'},
'public_keys': ['2acjECeGPGNv9Meod7up3YrTrcDB8vZKUpmjJMyrUZ9s']}],
'version': '1.0'}
inputs
のfulfillment
のフィールドが署名後のハッシュ情報に書き換えられているのがわかる。- この状態で、例えばtransaction-id(
id
)は以下のようにして取得できる。
In [XX]: txid = fulfilled_creation_tx['id']
In [XX]: txid
Out[XX]: '34be88811a133aae6ef1877f7c4001f2b58221e016bfa72cef1c3765d13f1f45'
- 署名を行ったらネットワークにトランザクションを送信(
send
)する。
In [XX]: sent_creation_tx = bdb.transactions.send(fulfilled_creation_tx)
- ネットワーク上でコンセンサスされると、トランザクションが
valid
の状態になる。 - トランザクションの状態(status)はtransaction-idを指定して、以下のように取得できる。
In [XX]: bdb.transactions.status(txid)
Out[XX]: {'status': 'valid'}
- トランザクションの生成を行う。未利用のtransactionはtransaction-idを指定して、以下のように取得できる。
- ※下記例では上述のAsset作成時に利用した変数
txid
を指定しているが、当然ながらAsset作成と送信が別処理・プログラムとなる場合には、再度txid
の設定が必要である。
In [XX]: creation_tx = bdb.transactions.retrieve(txid)
- Asset情報の付与を行う。
- asset_idとして上記でも利用したtransaction-idを利用する。
- ※Asset定義として、再定義を行うわけではなく、元々の定義をそのまま引き継ぐ意味。Asset作成以降は改竄ができない。Assetの定義を知りたい場合は、もともとのtransaction-idのAsset定義(
asset
フィールド)を参照する
In [XX]: asset_id = creation_tx['id']
In [XX]: transfer_asset = {
...: 'id': asset_id,
...: }
...:
- 送信のinput(
inputs
)を定義する。
In [XX]: output_index = 0
In [XX]: output = creation_tx['outputs'][output_index]
In [XX]: transfer_input = {
...: 'fulfillment': output['condition']['details'],
...: 'fulfills': {
...: 'output_index': output_index,
...: 'transaction_id': creation_tx['id'],
...: },
...: 'owners_before': output['public_keys'],
...: }
- トランザクションを生成する。
- ※
bob.public_key
は上述したAsset作成時に取得したもの。処理・プログラムがまたぐ場合は、再度設定する必要がある。
prepared_transfer_tx = bdb.transactions.prepare(
operation='TRANSFER',
asset=transfer_asset,
inputs=transfer_input,
recipients=bob.public_key,
)
- Asset保有者(ここではalice)の署名を行う。
- ※
alice.private_key
は上述したAsset作成時に取得したもの。処理・プログラムがまたぐ場合は、再度設定する必要がある。
In [XX]: fulfilled_transfer_tx = bdb.transactions.fulfill(
...: prepared_transfer_tx,
...: private_keys=alice.private_key,
...: )
署名後のトランザクション情報は以下のようになる。
In [XX]: fulfilled_transfer_tx
Out[XX]:
{'asset': {'id': '34be88811a133aae6ef1877f7c4001f2b58221e016bfa72cef1c3765d13f1f45'},
'id': '7bc57befafbf259bbeeab94c019b817f735fee5f151aea154b2892c4281637fc',
'inputs': [{'fulfillment': 'pGSAIBd4QGCf9TOBun18reMl0SbWm_4GQ_4FzLrI6avAHslKgUBHbu0V6GbvIm01vFqh65Skh2PbwH1uSShkPHa5Wkl-fKb8cStnT9hMNuyvcLugg0VWPBEDn0OlzGivqzol6z8J',
'fulfills': {'output_index': 0,
'transaction_id': '34be88811a133aae6ef1877f7c4001f2b58221e016bfa72cef1c3765d13f1f45'},
'owners_before': ['2acjECeGPGNv9Meod7up3YrTrcDB8vZKUpmjJMyrUZ9s']}],
'metadata': None,
'operation': 'TRANSFER',
'outputs': [{'amount': '1',
'condition': {'details': {'public_key': '9npkmGcQPFZJeHxSSQSjVRgSJ1RE75tXDDPcgNxfsLrF',
'type': 'ed25519-sha-256'},
'uri': 'ni:///sha-256;Vvqa97CzxphYSukn2LFppCq5dYUscpY1wyoR8CEJTmE?fpt=ed25519-sha-256&cost=131072'},
'public_keys': ['9npkmGcQPFZJeHxSSQSjVRgSJ1RE75tXDDPcgNxfsLrF']}],
'version': '1.0'}
operation
はTRANSFER
asset
フィールドのid
はAsset作成時のtransaction-id- inputsには上述の
transfer_input
を署名した情報が設定される。transaction_id
にはAsset作成時のtransaction-idが設定されていることが見て取れる。 outputs
のpublic_key
には送信先(bob)のpublic_keyが設定される。
署名を行ったらネットワークにトランザクションを送信(send
)する。
In [XX]: sent_transfer_tx = bdb.transactions.send(fulfilled_transfer_tx)
Asset作成時と同様、しばらくするとtransactionがvalid
の状態になる。
このような状態でalice, bobの保有Assetの状態を確認してみる。
In [41]: bdb.outputs.get(public_key='2acjECeGPGNv9Meod7up3YrTrcDB8vZKUpmjJMyrUZ9s', spent=True)
Out[41]:
[{'output_index': 0,
'transaction_id': '34be88811a133aae6ef1877f7c4001f2b58221e016bfa72cef1c3765d13f1f45'}]
In [XX]: bdb.outputs.get(public_key='2acjECeGPGNv9Meod7up3YrTrcDB8vZKUpmjJMyrUZ9s', spent=None)
Out[XX]:
[{'output_index': 0,
'transaction_id': '34be88811a133aae6ef1877f7c4001f2b58221e016bfa72cef1c3765d13f1f45'}]
spent=True
は利用済みトランザクション(他人に譲渡してしまったAsset)を取得するためのオプションである。すでにbobに受け渡しが完了した状態なので、データが取得できる。spent
オプションを設定しない場合(デフォルトはNone
)、unspentなものも含め、全Assetを参照することができる。
In [XX]: bdb.outputs.get(public_key='9npkmGcQPFZJeHxSSQSjVRgSJ1RE75tXDDPcgNxfsLrF', spent=True)
Out[XX]: []
In [XX]: bdb.outputs.get(public_key='9npkmGcQPFZJeHxSSQSjVRgSJ1RE75tXDDPcgNxfsLrF', spent=None)
Out[XX]:
[{'output_index': 0,
'transaction_id': '7bc57befafbf259bbeeab94c019b817f735fee5f151aea154b2892c4281637fc'}]
- bobの未利用トランザクションに残ができているのが確認できる。