[Hyperledger Iroha]Pythonのlibraryを使ってアカウントを作成する

# 記事の内容
Hyperledger IrohaのPythonライブラリを使ってアカウントを作成します。

# 準備
アカウントのキーペア作成に必要になるライブラリをインストールしておきます

~~~
pip install ed25519
~~~

# 実装
## アカウントの作成
早速アカウントを作成するコードです

~~~ create_account.py
from iroha import Iroha, IrohaCrypto, IrohaGrpc
import ed25519
import iroha_config

# irohaへの接続情報
net = IrohaGrpc(iroha_config.IROHA_HOST)
iroha = Iroha(iroha_config.ADMIN_ACCOUNT)

# キーペアの作成
signing_key, verifying_key = ed25519.create_keypair()

# 作成したキーペアを保存
open("iroha@test.prib","wb").write(signing_key.to_ascii(encoding="hex"))
open("iroha@test.pub","wb").write(verifying_key.to_ascii(encoding="hex"))

# バイナリから16進数に変換
vkey_hex = verifying_key.to_ascii(encoding="hex")

# Transactionの作成
transfer_tx = iroha.transaction(
 [iroha.command(
    'CreateAccount',
    account_name ='iroha',
    domain_id = 'test',
    public_key = vkey_hex
 )]
)

# Transactionの署名
IrohaCrypto.sign_transaction(transfer_tx, iroha_config.ADMIN_PRIV_KEY)

# Transactionの送信
net.send_tx(transfer_tx)

# 結果の確認
for status in net.tx_status_stream(transfer_tx):
    print(status)
~~~

iroha-cliを使ってアカウントを作成すると鍵情報も一緒に作成されますが、ライブラリからアカウントを作成する場合は自分で作成する必要があります。
作成には「ed25519」というライブラリを使っています。

### 実行結果
以下の結果が出力されれば成功です

~~~
('ENOUGH_SIGNATURES_COLLECTED', 9, 0)
('STATEFUL_VALIDATION_SUCCESS', 3, 0)
('COMMITTED', 5, 0)
~~~
ブロックの中身も確認してみます。

~~~
{
  "blockV1": {
    "payload": {
      "transactions": [
        {
          "payload": {
            "reducedPayload": {
              "commands": [
                {
                  "createAccount": {
                    "accountName": "iroha",
                    "domainId": "test",
                    "publicKey": "efdc215eab6dd2c4435d370da73e4b88350e1fed9d39afed503fcbee985fce1f"
                  }
                }
              ],
              "creatorAccountId": "admin@test",
              "createdTime": "1594016319157",
              "quorum": 1
            }
          },
          "signatures": [
            {
              "publicKey": "313a07e6384776ed95447710d15e59148473ccfc052a681317a72a69f2a49910",
              "signature": "429bf3ae70b60d31ab3fc3c15fa11cb8155b6a824f831652c1c46068feaeb866846b8048e0959cbcbeed532423f050e77d2fe192ea90d0827a6f1489bf67ec0a"
            }
          ]
        }
      ],
      "height": "4",
      "prevBlockHash": "039c70e4d990318c7373a59b14f39c9dd6199b949f1ba74b28c44d100adf8218",
      "createdTime": "1594016319568"
    },
    "signatures": [
      {
        "publicKey": "bddd58404d1315e0eb27902c5d7c8eb0602c16238f005773df406bc191308929",
        "signature": "e2a7dc68e837fc4bdefc2e7f60131661c9567f0f2b19af7e0069ced69a4054f7402fb93abd38e96aef850d865c760f3983632654db61fc0ab0181224e44fb20d"
      }
    ]
  }
}
~~~
createAccountコマンドのトランザクションがブロックに取り込まれていることを確認できました。

同一ユーザー名、同一ドメインを登録できないので同じ内容で実行すると以下の結果となり、トランザクションがリジェクトされています。

~~~
('ENOUGH_SIGNATURES_COLLECTED', 9, 0)
('STATEFUL_VALIDATION_FAILED', 2, 4)
('REJECTED', 4, 0)
~~~

~~~
{
  "blockV1": {
    "payload": {
      "height": "5",
      "prevBlockHash": "fe0c9b0e59efe7de5f67710ad66fdb5aab3f1e41b79bed8eda13f9c3d122d8cf",
      "createdTime": "1594017524600",
      "rejectedTransactionsHashes": [
        "ef17d5f4e82c7e9690676110b3d84c9ff721fd2ac78678e1b893cf3c024c5156"
      ]
    },
    "signatures": [
      {
        "publicKey": "bddd58404d1315e0eb27902c5d7c8eb0602c16238f005773df406bc191308929",
        "signature": "0ea48cca0b0db7ee525edafa961e6f2469989cbbb1346cc31e140a98b8260693ef939fe30bc9ef10a5ab4d0a6e7ffeccc1cc15124cb472be1d4f658b5aac1b0d"
      }
    ]
  }
}
~~~
## アカウント情報の取得

~~~ get_account.py
from iroha import Iroha, IrohaCrypto, IrohaGrpc
import iroha_config

net = IrohaGrpc(iroha_config.IROHA_HOST)

iroha = Iroha(iroha_config.ADMIN_ACCOUNT)
admin_priv_key = iroha_config.ADMIN_PRIV_KEY

# Queryの作成
get_block_query = iroha.query(
        'GetAccount',
        account_id = 'iroha@test'  
)

# Queryへ署名
IrohaCrypto.sign_query(get_block_query, admin_priv_key)

# Queryの送信
response = net.send_query(get_block_query)

# Responseの出力
print(response)
~~~
アカウント情報の取得方法はトランザクション送信と基本的には流れは同じです。
送信の内容がコマンドではなくクエリになるだけです

### 実行結果
~~~
account_response {
  account {
    account_id: "iroha@test"
    domain_id: "test"
    quorum: 1
    json_data: "{}"
  }
  account_roles: "user"
}
query_hash: "a07e90ca85d9c4f0bd1b12ba8cd9c11886729fcd50ee4c2fc50e6c9a27047a2e"
~~~
実行結果が取得できました

# 参考
・[Iroha API Reference #create-account](https://iroha.readthedocs.io/en/1.1.1/api/commands.html#create-account)

・[Iroha API Reference #get-account](https://iroha.readthedocs.io/en/1.1.1/api/queries.html#get-account)

# 関連記事

[[Hyperledger Iroha]Python SDKの使い方メモ](https://qiita.com/bc_yuuuuuki/items/45b69bd2262c45ac2e83)