Skip to content

Instantly share code, notes, and snippets.

@YoshihitoAso
Last active September 11, 2017 07:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save YoshihitoAso/5b48db677a7aa06cd565a20449615e37 to your computer and use it in GitHub Desktop.
Save YoshihitoAso/5b48db677a7aa06cd565a20449615e37 to your computer and use it in GitHub Desktop.
BigchainDB Python Driver 導入メモ(bigchaindb v1.0.1)

BigchainDB Python Driver 導入&クイックスタート

1. Python用Driverのインストール

  • pip でインストールが可能。
$ pip install bigchaindb_driver

2. クイックスタート(Asset作成〜送信のサンプル)

  • 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'}
  • operationCREATE

  • asset,metadataには上で定義した情報が記録される。

  • idは transaction-id を意味する。トランザクション毎に異なる値が設定される。

  • transaction prepare 時の inputs には、平文の情報が格納されているのがわかる。 public_keyowners_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'}
  • inputsfulfillmentのフィールドが署名後のハッシュ情報に書き換えられているのがわかる。
  • この状態で、例えば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'}

3. Asset送信のサンプル

  • トランザクションの生成を行う。未利用の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'}
  • operationTRANSFER
  • assetフィールドのidはAsset作成時のtransaction-id
  • inputsには上述のtransfer_inputを署名した情報が設定される。transaction_idにはAsset作成時のtransaction-idが設定されていることが見て取れる。
  • outputspublic_keyには送信先(bob)のpublic_keyが設定される。

署名を行ったらネットワークにトランザクションを送信(send)する。

In [XX]: sent_transfer_tx = bdb.transactions.send(fulfilled_transfer_tx)

Asset作成時と同様、しばらくするとtransactionがvalidの状態になる。

このような状態でalice, bobの保有Assetの状態を確認してみる。

1. alice(public_key : 2acjECeGPGNv9Meod7up3YrTrcDB8vZKUpmjJMyrUZ9s

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を参照することができる。

2. bob(public_key : 9npkmGcQPFZJeHxSSQSjVRgSJ1RE75tXDDPcgNxfsLrF

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の未利用トランザクションに残ができているのが確認できる。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment