Hyperledger-Sawtoothのチュートリアルをやってみる

# 記事の内容
Hyperldger-Sawtoothのチュートリアルに〇×ゲームがあります。
３×３のマス目に２人のプレイヤーがそれぞれ〇、×を交互に埋めて、縦横斜めのどれかが揃ったら勝ちというやつです。

チュートリアル用のスマートコントラクトで〇×ゲームが用意されているので、この〇×ゲームをやってみます。
※Fabricと違ってChainCodeとは呼ばないっぽい

# 環境構築
環境構築はこちらのサイトを参考にしました。
https://akiyoko.hatenablog.jp/entry/2017/12/17/053426

# Hyperldger-Sawtoothのチュートリアルをやってみる

操作は「sawtooth-shell-default」コンテナ内で行います。

~~~
docker exec -it sawtooth-shell-default /bin/bash
~~~

##プレイヤーの作成
プレイヤーを２名分作成します。
ここでは「alex」と「leo」を作成します。

~~~
root@69ab89491d15:/# sawtooth keygen alex
writing file: /root/.sawtooth/keys/alex.priv
writing file: /root/.sawtooth/keys/alex.pub
root@69ab89491d15:/# sawtooth keygen leo
writing file: /root/.sawtooth/keys/leo.priv
writing file: /root/.sawtooth/keys/leo.pub
~~~

##〇×ゲーム開始
まずは、alexが先行でゲームを開始します。

~~~
root@69ab89491d15:/# xo create game --url http://rest-api:8008 --username alex
Response: {
  "link": "http://rest-api:8008/batch_statuses?id=c7fc5758c3340f7643a391db27f1069460e7fe2727018de2ad0140829876b5f81ae58f9f3afcd2047bd319c99858039ea04bc750cdb84f79d77a39f209479e6b"
}
root@69ab89491d15:/# xo list --url http://rest-api:8008 --username alex
GAME            PLAYER 1        PLAYER 2        BOARD     STATE
game                                            --------- P1-NEXT
~~~
ゲームの作成が完了したので、最初の１手目です。
〇×を置いていく場所は数字で指定します。

|1  |2  |3  |
|4  |5  |6  |
|7  |8  |9  |

~~~
root@69ab89491d15:/# xo take game 5 --url http://rest-api:8008 --username alex
Response: {
  "link": "http://rest-api:8008/batch_statuses?id=9ad0fff9c0429982a1cc42cd13095e649d0888307bf38afff648a2b3cc14d41b264f147174d0348293f5272114a000a64e1495ef114d0d26ce066be158610c44"
}
root@69ab89491d15:/# xo show game --url http://rest-api:8008 --username alex
GAME:     : game
PLAYER 1  : 02934c
PLAYER 2  :
STATE     : P2-NEXT

    |   |
 ---|---|---
    | X |
 ---|---|---
    |   |
~~~
ど真ん中は初手の定石ですね。

次は後攻のleoの番です。

~~~
root@69ab89491d15:/# xo take game 9 --url http://rest-api:8008 --username leo
Response: {
  "link": "http://rest-api:8008/batch_statuses?id=440203337627a125cb1e6825fad3dedcfe14d02bc192950a2c17c8dbaf465d5c34c05d7aced151d63b0d45cd1b1a50aa366bb48d009c10b3031590b9f1031cef"
}
root@69ab89491d15:/# xo show game --url http://rest-api:8008 --username leo
GAME:     : game
PLAYER 1  : 02934c
PLAYER 2  : 02d2f2
STATE     : P1-NEXT

    |   |
 ---|---|---
    | X |
 ---|---|---
    |   | O
~~~
はい。置きました。
ここから先はこんな感じです。

~~~
root@69ab89491d15:/# xo take game 3 --url http://rest-api:8008 --username alex
Response: {
  "link": "http://rest-api:8008/batch_statuses?id=32da11e1846e77391bbfa4f7c66705754393c460df1a5bd6e58d76f894b4d77a1a8d9103d456fb90318171830ce6bd33da023662fcbee83819802cb5a618dd5e"
}
root@69ab89491d15:/# xo show game --url http://rest-api:8008 --username alex
GAME:     : game
PLAYER 1  : 02934c
PLAYER 2  : 02d2f2
STATE     : P2-NEXT

    |   | X
 ---|---|---
    | X |
 ---|---|---
    |   | O

root@69ab89491d15:/# xo take game 7 --url http://rest-api:8008 --username leo
Response: {
  "link": "http://rest-api:8008/batch_statuses?id=e69d1afedd106090f0f890f0f93ed10833f35e32a49c501332ce63eb3ff81a8563109af7b9daec992c0628ef8b8a52fb18503c42929729f3d69d493ba26cf2db"
}
root@69ab89491d15:/# xo show game --url http://rest-api:8008 --username leo
GAME:     : game
PLAYER 1  : 02934c
PLAYER 2  : 02d2f2
STATE     : P1-NEXT

    |   | X
 ---|---|---
    | X |
 ---|---|---
  O |   | O

root@69ab89491d15:/# xo take game 8 --url http://rest-api:8008 --username alex
Response: {
  "link": "http://rest-api:8008/batch_statuses?id=d8a3d58c95c85f83f20ee3501c1eab79a2a1ac36e216e88508a183afcfde61aa43af3c9478bd058ff26154652efbf6c26c87297ee543dd97629d8d7bc330a0c6"
}
root@69ab89491d15:/# xo show game --url http://rest-api:8008 --username alex
GAME:     : game
PLAYER 1  : 02934c
PLAYER 2  : 02d2f2
STATE     : P2-NEXT

    |   | X
 ---|---|---
    | X |
 ---|---|---
  O | X | O

root@69ab89491d15:/# xo take game 2 --url http://rest-api:8008 --username leo
Response: {
  "link": "http://rest-api:8008/batch_statuses?id=c2770a9997e1387521029d561b77fc14f3ef0a9a33bebeab96a9bd40f0171d0e177f24291e43f120c817e44aaf5a89df26dd4e63fb00f994ad49579c9ef8dc9b"
}
root@69ab89491d15:/# xo show game --url http://rest-api:8008 --username leo
GAME:     : game
PLAYER 1  : 02934c
PLAYER 2  : 02d2f2
STATE     : P1-NEXT

    | O | X
 ---|---|---
    | X |
 ---|---|---
  O | X | O

root@69ab89491d15:/# xo take game 1 --url http://rest-api:8008 --username alex
Response: {
  "link": "http://rest-api:8008/batch_statuses?id=498e565e6486d9c8456e3354136ace1f462f938b0d515821562f5de8031b2aeb3fb79c09fd020c538b22e672dae7a0f683ad3cc2bc8668c707f286726034f4a1"
}
root@69ab89491d15:/# xo show game --url http://rest-api:8008 --username alex
GAME:     : game
PLAYER 1  : 02934c
PLAYER 2  : 02d2f2
STATE     : P2-NEXT

  X | O | X
 ---|---|---
    | X |
 ---|---|---
  O | X | O

root@69ab89491d15:/# xo take game 4 --url http://rest-api:8008 --username leo
Response: {
  "link": "http://rest-api:8008/batch_statuses?id=abf1b31e43d1560bb1b3fed434ade838927584699f00ec33cfa5cc5c578b736909aa57fead1c20d6159df47f17d70e26a6f46a5e87e4d46655f3f860b1048fdd"
}
root@69ab89491d15:/# xo show game --url http://rest-api:8008 --username leo
GAME:     : game
PLAYER 1  : 02934c
PLAYER 2  : 02d2f2
STATE     : P1-NEXT

  X | O | X
 ---|---|---
  O | X |
 ---|---|---
  O | X | O

root@69ab89491d15:/# xo take game 6 --url http://rest-api:8008 --username alex
Response: {
  "link": "http://rest-api:8008/batch_statuses?id=92113ce5d1ce4b3ef20f4204f475e2f758c616f172e4bd1c5469a2fe97bc19600d8815f2b5e501722cf91553aca67be8c2386dbe18e1a7e8a0960fdb77bea9c6"
}
root@69ab89491d15:/# xo show game --url http://rest-api:8008 --username alex
GAME:     : game
PLAYER 1  : 02934c
PLAYER 2  : 02d2f2
STATE     : TIE

  X | O | X
 ---|---|---
  O | X | X
 ---|---|---
  O | X | O
~~~

結果は引き分け（TIE）になりました。
勝敗が着いた場合は、「P1-WIN」と表示されるようです。

## ブロック情報を確認する
スマートコントラクトで実行しているのであれば、ブロックに情報が書き込まれるはずなので、ブロック情報を確認してみます。

~~~
sawtooth block list --url http://rest-api:8008
NUM  BLOCK_ID                                                                                                                          BATS  TXNS  SIGNER
10   29421922a4d056b1048c34a5d34b5f174f8f00c767c6cf0ffed928229a862c47390c2fa635150b9a30230f7ef0dedfd01e31eea4d2f6cb8ee40362861659620e  1     1     0227be2f097d11b1a8e11146f2df73042c5a8671d2338d4ffa623884669c01d4b4
9    020fcd82b13697e5d566bf7b68461b6e6085d5dfc2afb635e54e99cf97987fae0e5f216d6f72ad9007a60449f9ca00c3e89cb6ecc66aa81107dfc0c7be8d1f8a  1     1     0227be2f097d11b1a8e11146f2df73042c5a8671d2338d4ffa623884669c01d4b4
8    409438e028b10a8c1c52fa25d53b0ddee6e7be4d2cc4ecd93ada06d417dd370b485234a2a57fc623237666218ad2c4707112e8424469951474d184e18a580711  1     1     0227be2f097d11b1a8e11146f2df73042c5a8671d2338d4ffa623884669c01d4b4
7    61374280f7094e0fe075209eb4cb539cd090582399be6897f0e2ddd639cbdafa4281bcd9219cb0c8519aadb8bdc56279b61d1942d708c58dfec051fedced1a77  1     1     0227be2f097d11b1a8e11146f2df73042c5a8671d2338d4ffa623884669c01d4b4
6    b7bbb8bfba334c3e2d7df53c646492d6f8dff62b13e8a59a96794c79701d66c26d8ec335a16da5122d1b2740c494768484eb56d1f504dc669f21db0c82018170  1     1     0227be2f097d11b1a8e11146f2df73042c5a8671d2338d4ffa623884669c01d4b4
5    018253b967fdd55cfa69268ffb03e7095f516b412f3bcb2f061a6b1dd9b8c5756e53b91bbc1973f1b023dfbca325022332317061074e3c1e77b30aabb2e8c184  1     1     0227be2f097d11b1a8e11146f2df73042c5a8671d2338d4ffa623884669c01d4b4
4    6e6df4e6cbcd043f664d556fae14db7934f9a2dbcc9805983f6413b287f22ae614248a422337b371a0831948398e343fc2e5621a5e6bf9575de4c0d082cb4523  1     1     0227be2f097d11b1a8e11146f2df73042c5a8671d2338d4ffa623884669c01d4b4
3    a4dbf36fa935862fc27218fcd67ebb171dce62fae29887b9ee1efec960dd84ca0cc1ed5a3e3f810be383b4290afd8113223d80e869b616ed8d2f5f3ce797ad52  1     1     0227be2f097d11b1a8e11146f2df73042c5a8671d2338d4ffa623884669c01d4b4
2    3936f6b6c2c4ff962063f2bd7f4b4d82cabcc4dc07ef4b2e92c7df3c1bbfe95d3fedc8b0fa3b9011341ad39a23c303e9d87d662fa1f48e4ddfb1b3de296fb3cc  1     1     0227be2f097d11b1a8e11146f2df73042c5a8671d2338d4ffa623884669c01d4b4
1    f5d570835f898ffc5f319aab48641a34ca68f0aea3d24fa0c8923091f6f447574083d95ff01713dde6ba8171612ff5e2a600e83e31875a22a6ad5a8eac2ea92f  1     1     0227be2f097d11b1a8e11146f2df73042c5a8671d2338d4ffa623884669c01d4b4
0    2cdeda16589fa10937ee4ad9ede1e9970440a99e5387aa2c028b5d1e2da74d176680cc35d694846d2fe42074686c7ee7ac28d14a87e488f4bd5c1635b57647df  2     3     0227be2f097d11b1a8e11146f2df73042c5a8671d2338d4ffa623884669c01d4b4
~~~

NUM 0がジェネシスブロック
NUM 1がゲームの作成
NUM 2-10が〇×ゲームですね。

ブロックの中身を見てみます。（NUM 10を見てみます。）

~~~
root@69ab89491d15:/# sawtooth block show 29421922a4d056b1048c34a5d34b5f174f8f00c767c6cf0ffed928229a862c47390c2fa635150b9a30230f7ef0dedfd01e31eea4d2f6cb8ee40362861659620e --url http://rest-api:8008
batches:
- header:
    signer_public_key: 02934c71d9794041b1f05ceab4fd37c3030e0f322538467bb68dd68fd49459c8a9
    transaction_ids:
    - 241a8fb37313efe305885abf664888f26e0e3522d1f028cf9becbcac9290f22952b0d285923ba8c06f22c65055e1dcf2f12345c3ce2a1fa15184450ce34dab52
  header_signature: 92113ce5d1ce4b3ef20f4204f475e2f758c616f172e4bd1c5469a2fe97bc19600d8815f2b5e501722cf91553aca67be8c2386dbe18e1a7e8a0960fdb77bea9c6
  trace: false
  transactions:
  - header:
      batcher_public_key: 02934c71d9794041b1f05ceab4fd37c3030e0f322538467bb68dd68fd49459c8a9
      dependencies: []
      family_name: xo
      family_version: '1.0'
      inputs:
      - 5b73496ba2b9df31680dcda5a4a083c462109df7e1abf32ff25d82f8b3cbf9734de8ef
      nonce: '0x7337ad0fe9eceed3'
      outputs:
      - 5b73496ba2b9df31680dcda5a4a083c462109df7e1abf32ff25d82f8b3cbf9734de8ef
      payload_sha512: 04c182e786582fae7b3cfd17174c9313ae90e7f1b54342890134553a0e34c2e7d7147d9721f10778bc6bd5bc30d07478d92804c71d0ae7c2c950e156dc8628aa
      signer_public_key: 02934c71d9794041b1f05ceab4fd37c3030e0f322538467bb68dd68fd49459c8a9
    header_signature: 241a8fb37313efe305885abf664888f26e0e3522d1f028cf9becbcac9290f22952b0d285923ba8c06f22c65055e1dcf2f12345c3ce2a1fa15184450ce34dab52
    payload: Z2FtZSx0YWtlLDY=
header:
  batch_ids:
  - 92113ce5d1ce4b3ef20f4204f475e2f758c616f172e4bd1c5469a2fe97bc19600d8815f2b5e501722cf91553aca67be8c2386dbe18e1a7e8a0960fdb77bea9c6
  block_num: '10'
  consensus: RGV2bW9kZZiBt2PR+OkgurztTeBcUriF5Poc3AkcjUL7UPDYxMU6
  previous_block_id: 020fcd82b13697e5d566bf7b68461b6e6085d5dfc2afb635e54e99cf97987fae0e5f216d6f72ad9007a60449f9ca00c3e89cb6ecc66aa81107dfc0c7be8d1f8a
  signer_public_key: 0227be2f097d11b1a8e11146f2df73042c5a8671d2338d4ffa623884669c01d4b4
  state_root_hash: d93bb3d9d0e12f7c8dcc307ceaa6af3eeebc8c26c86d77ecf97166128044a0d6
header_signature: 29421922a4d056b1048c34a5d34b5f174f8f00c767c6cf0ffed928229a862c47390c2fa635150b9a30230f7ef0dedfd01e31eea4d2f6cb8ee40362861659620e
~~~

次に、このブロックの中のトランザクション情報を見てみます。

~~~
root@69ab89491d15:/# sawtooth transaction show 241a8fb37313efe305885abf664888f26e0e3522d1f028cf9becbcac9290f22952b0d285923ba8c06f22c65055e1dcf2f12345c3ce2a1fa15184450ce34dab52 --url http://rest-api:8008
header:
  batcher_public_key: 02934c71d9794041b1f05ceab4fd37c3030e0f322538467bb68dd68fd49459c8a9
  dependencies: []
  family_name: xo
  family_version: '1.0'
  inputs:
  - 5b73496ba2b9df31680dcda5a4a083c462109df7e1abf32ff25d82f8b3cbf9734de8ef
  nonce: '0x7337ad0fe9eceed3'
  outputs:
  - 5b73496ba2b9df31680dcda5a4a083c462109df7e1abf32ff25d82f8b3cbf9734de8ef
  payload_sha512: 04c182e786582fae7b3cfd17174c9313ae90e7f1b54342890134553a0e34c2e7d7147d9721f10778bc6bd5bc30d07478d92804c71d0ae7c2c950e156dc8628aa
  signer_public_key: 02934c71d9794041b1f05ceab4fd37c3030e0f322538467bb68dd68fd49459c8a9
header_signature: 241a8fb37313efe305885abf664888f26e0e3522d1f028cf9becbcac9290f22952b0d285923ba8c06f22c65055e1dcf2f12345c3ce2a1fa15184450ce34dab52
payload: Z2FtZSx0YWtlLDY=
~~~

確認できました。

# 感想
思いの外、簡単に出来ました。
iroha、sawtoothは環境構築からチュートリアルの実施まで特に躓くことなく出来るので、ブロックチェーンをとりあえず動かしてイメージを掴むには良いかもしれませんね。

sawtoothはサプライチェーン用のフレームワーク「Hyperledger-GRID」と連携出来るみたいなので、このあたりの学習も進めようと思います。