Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Tendermint をさわってみる

490b0d3889f99313ef90dcda6dd2f5bd?s=47 Yuka Tsuboi
September 03, 2018

Tendermint をさわってみる

20180903 ビットコインとか勉強会 #21 でお話ししたスライドです

490b0d3889f99313ef90dcda6dd2f5bd?s=128

Yuka Tsuboi

September 03, 2018
Tweet

More Decks by Yuka Tsuboi

Other Decks in Technology

Transcript

  1. Tendermintをさわってみる 2018.09.03 坪井有花 @__kyrieleison__ ビットコインとか勉強会 #21

  2. - Webエンジニア / 株式会社TRUSTDOCK - 本人確認をAPIで提供している会社です - 過去にブロックチェーン x 本人確認の実証実験を


    していました - 趣味で Dapps 開発をして遊んでいます 坪井有花 @__kyrieleison__
  3. 目的 - Tendermintの概要を知る - Tendermintのノードを起動したり、アプリケーションコードを読んだり、実行したりすること を通じて、Tendermintで何ができるのかを理解する - EthermintやCosmosのような、Tendermintをベースとしたブロックチェーンについて知り、 スケーラビリティ問題を解決するための手札を増やす (…ための足がかりにする)

    本発表を通じて、こんな目的が達成できたらよいなと考えております よろしくお願いいたします
  4. スケーラビリティ問題について

  5. スケーラビリティ問題を解決するアプローチ - On-chain / 1st layer - コンセンサスアルゴリズムの改善 - Casper

    (Proof of Stake): 通貨の保有量に応じてマイナーを選出することで、計算を必要とする Proof of Work よりも高速にコンセンサスを得られる - 処理の並列化 - Sharding: トランザクションを分割し、ノードグループ毎に割り当てることで並列処理を可能にする - Off-chain / 2nd layer - ステートチャネルで処理 - Raiden Network: ペイメントチャネルで取引を行い、チェーンには最新の状態だけを記録することで、 取引を早く安く行える - サイドチェーンで処理 - Plasma: 子チェーンでトランザクションを処理し、親チェーンにはブロックのハッシュだけを記録することで、 トランザクションの処理を早く安く行える
  6. - On-chain / 1st layer - コンセンサスアルゴリズムの改善 - Casper (Proof

    of Stake): 通貨の保有量に応じてマイナーを選出することで、計算を必要とする Proof of Work よりも高速にコンセンサスを得られる - 処理の並列化 - Sharding: トランザクションを分割し、ノードグループ毎に割り当てることで並列処理を可能にする - Off-chain / 2nd layer - ステートチャネルで処理 - Raiden Network: ペイメントチャネルで取引を行い、チェーンには最新の状態だけを記録することで、 取引を早く安く行える - サイドチェーンで処理 - Plasma: 子チェーンでトランザクションを処理し、親チェーンにはブロックのハッシュだけを記録することで、 トランザクションの処理を早く安く行える スケーラビリティ問題を解決するアプローチ Tendermint
  7. - On-chain / 1st layer - コンセンサスアルゴリズムの改善 - Casper (Proof

    of Stake): 通貨の保有量に応じてマイナーを選出することで、計算を必要とする Proof of Work よりも高速にコンセンサスを得られる - 処理の並列化 - Sharding: トランザクションを分割し、ノードグループ毎に割り当てることで並列処理を可能にする - Off-chain / 2nd layer - ステートチャネルで処理 - Raiden Network: ペイメントチャネルで取引を行い、チェーンには最新の状態だけを記録することで、 取引を早く安く行える - サイドチェーンで処理 - Plasma: 子チェーンでトランザクションを処理し、親チェーンにはブロックのハッシュだけを記録することで、 トランザクションの処理を早く安く行える スケーラビリティ問題を解決するアプローチ Tendermintをベースとしたブロックチェーン Cosmos, Ethermint Tendermint
  8. Tendermint

  9. Tendermint セキュアかつスケーラブルなブロックチェーンを誰でも容易に構築するための コンセンサスエンジンとアプリケーションインターフェースをパッケージングしたソフトウェア Tendermint コンセンサスエンジン Tendermint Core アプリケーションインターフェース Application BlockChain

    Interface (ABCI)
  10. セキュアかつスケーラブルなブロックチェーンを誰でも容易に構築するための コンセンサスエンジンとアプリケーションインターフェースをパッケージングしたソフトウェア 特徴 - 1秒あたり数千トランザクションを処理できる - ブロック生成後すぐにファイナリティを得られる - 3分の1のノードが停止、または悪意を持った振る舞いをしても安全 -

    任意のプログラミング言語でブロックチェーンプロトコルの実装ができる ブロックチェーンプロトコルの開発者は、Tendermintを用いることで コンセンサスアルゴリズムやP2Pネットワークのセキュリティやスケーラビリティを意識せず また特定のプログラミング言語にも縛られずに 独自のブロックチェーンプロトコルを開発することができる
  11. Tendermintで実装されているブロックチェーン Tendermintで実装されたこれらのブロックチェーンが実用段階になれば Dapps開発者にとっても、これまで開発したDappsをそのままに よりスケーラブルなブロックチェーンに乗り換えることができるかもしれない Ethermint EVMを実装しており web3やsolidityとの互換性がある EthereumのDappsを処理できる Cosmos Tendermintで実装されたチェーン同士は

    相互にメッセージをやりとりできる 異なるチェーン間でのトークン移転を容易にする
  12. Application BlockChain Interface (ABCI)

  13. Application BlockChain Interface (ABCI) 1台のマシン上でのステートマシン(= アプリケーションロジック)と 複数のマシンへステートマシンを複製する仕組み(= コンセンサスエンジン)との間に シンプルなインターフェースを提供することで、それぞれの関心事を分離する コンセンサスエンジン

    ステートに対するトランザクションが すべてのマシンに同じ順序で複製されることを保証する アプリケーションロジック トランザクションを検証し、OKなら トランザクションを実行してステートを更新する ABCI
  14. メッセージプロトコル アプリケーションロジックとコンセンサスエンジンとの間のインターフェースは、 リクエストとレスポンスのペアで構成される”メッセージ”として定義される コンセンサスエンジンがリクエストを行い、アプリケーションロジックがレスポンスを行う レスポンス リクエスト ABCI ABCI サーバ ABCI

    クライアント アプリケーションロジック コンセンサスエンジン
  15. メッセージプロトコル メッセージはGoogleが開発しているデータフォーマット”Protocol Buffer”で定義する 主要なメッセージタイプとしてCheckTx, DeliverTx, Commit等がある - CheckTx - リクエストされたトランザクションの検証を行う

    - DeliverTx - リクエストされたトランザクションの検証と実行を行い、アプリケーションステートを更新する - Commit - 現在のアプリケーションステートのルートハッシュを計算する - レスポンスとして返却されたルートハッシュを次のブロックのヘッダにセットする
  16. Go JavaScript Python C++ Java 任意のプログラミング言語でABCIを使う場合、その言語でのABCIサーバ実装が必要となる クライアントとの通信には、GRPCかソケット通信のいずれかを選択する ABCIサーバ ABCI レスポンス

    リクエスト ABCI サーバ ABCI クライアント アプリケーションロジック コンセンサスエンジン
  17. ABCIクライアントはコンセンサスエンジンであるTendermint Coreが担うため、 通常の場合は実装する必要はない “abci-cli”というテストツールを用いて、コマンドラインからリクエストすることも可能 ABCIクライアント ABCI レスポンス リクエスト ABCI サーバ

    ABCI クライアント アプリケーションロジック コンセンサスエンジン abci-cli or
  18. ブロックチェーンプロトコル ABCIはコネクション指向で、メッセージのやりとりにはコネクションを確立する タイミングと用途に応じて、3つのコネクションを明示的に使い分ける - Mempool Connection - ユーザからトランザクションを受け取ったときに確立するコネクション - Consensus

    Connection - コンセンサスの得られた新しいブロックがコミットされたときに確立するコネクション - Query Connection - アプリケーションステートの状態を問い合わせるときに確立するコネクション
  19. Mempool Connection ユーザからトランザクションを受け取ったときに確立するコネクション CheckTXメッセージを送ってトランザクションを検証し、 受け取ったトランザクションを他のノードにブロードキャストするかどうかを判断する ABCI ABCI サーバ ABCI クライアント

    アプリケーションロジック コンセンサスエンジン 2. CheckTXメッセージを送信 4. OK or NG を返却 3. トランザクションを検証 5. OKならメモリプールに溜 めておき、受け取ったの と同じ順序で他のノード にブロードキャストする。 NGなら破棄する 1. トランザクションを 受け取る
  20. Consensus Connection コンセンサスの得られた新しいブロックがコミットされたときに確立するコネクション BeginBlock, [DeliverTX, ...], EndBlock, Commit の一連のメッセージを送って ブロックのすべてのトランザクションを実行し、次のブロック生成の準備をする

    ABCI ABCI サーバ ABCI クライアント アプリケーションロジック コンセンサスエンジン 4. ステートのルートハッシュを返却 3. DeliverTXで送られた トランザクションを検証・ 実行してステートを更新 する 5. ステートのルートハッシュを 次のブロックのヘッダにセッ トする 1. コンセンサスを得ら れた新しいブロック がチェーンにコミット される 2. BeginBlock, [DeliverTX,…], EndBlock, Commitメッセージ を送信
  21. Query Connection アプリケーションステートの状態を問い合わせるときに確立するコネクション 最後にコミットしたBlockHeightやルートハッシュを問い合わせるInfoメッセージや アプリケーションステートのデータを問い合わせるQueryメッセージ等を処理する ABCI ABCI サーバ ABCI クライアント

    アプリケーションロジック コンセンサスエンジン 1. Queryメッセージ等を送信 2. 結果を返却
  22. Tendermint Core

  23. Tendermint Core 同じトランザクションが同じ順序で、すべてのマシンに複製されることを保証する 低レイヤなプロトコル コンセンサスアルゴリズムとP2Pネットワークプロトコルで構成される Tendermint Core アプリケーションロジック ABCI コンセンサスアルゴリズム

    P2Pネットワーク
  24. コンセンサスアルゴリズム 部分的に非同期で、決定論的な BFT-based PoS - 部分的に非同期 - トランザクションを収集/検証/拡散するのに特定の時間を設定する(Bitcoinは10分、 Ethereumは15秒) =

    同期的 - タイムアウトするまで非同期で続く = 部分的非同期, 弱い同期 - 決定論的 - ランダム性がなく、完全に決定論的にプロポーザーを選出する - 通貨の保有量に応じた加重ラウンドロビン方式でローテーションする Chain-based PoS (Casper) と BFT-based PoS との違いについては Consensus Compare: Casper vs. Tendermint を参照してください
  25. コンセンサスを得るまでのステップ

  26. コンセンサスを得るまでのステップ 2. Pre-Vote 1. Propose 4. Commit 3. Pre-Commit

  27. コンセンサスを得るまでのステップ 1. Transaction Submittion - ユーザからトランザクションが送られるとローカルのMempoolキャッシュに保持される - ABCIのMempool Connectionでトランザクションがアプリケーションで検証され、ローカ ルのMempoolに保持された後、他ノードのMempoolにブロードキャストされる

    2. Propose - P2Pネットワークに参加するノード(バリデータ)の中から、通貨保有量に応じた加重ラウン ドロビン方式で”プロポーザー”が選ばれる - メモリプールに溜まっているトランザクションを近隣のバリデータにブロードキャストする
  28. コンセンサスを得るまでのステップ 3. Pre-Vote - 提案されたブロックに1回目の投票(署名)を行う - 2/3以上のバリデータが投票し終わるか、タイムアウトに達するまで待つ - 投票が集まればすぐに次のステップに進むことができる =

    部分的非同期 4. Pre-Commit - Pre-Voteで2/3以上のバリデータが投票したブロックに、2回目の投票(署名)を行う - 2/3以上のバリデータが投票し終わるか、タイムアウトに達するまで待つ - 1ラウンドでPre-Commitできるのは1度だけ。そのため、同時に別のブロックがPre- Commitされることはなく、フォークが発生しない = すぐにファイナリティが得られる
  29. コンセンサスを得るまでのステップ 5. Commit - 2/3以上のバリデータからの投票が集まったブロックが、ブロックチェーンにコミットされる - ABCIのConsensus Connectionでアプリケーションステートが更新される - 投票が集まらなかったブロックは、次のラウンドに回される

  30. Tendermintをさわってみる

  31. https://tendermint.com/docs/ introduction/install.html Tendermintのインストール GCPでUbuntu 18.04のVMインスタンスを作成し、セットアップしました

  32. ルートディレクトリの初期化: $HOME/.tendermint 下に秘密鍵やチェーンの初期定義ファイルが生成される $ tendermint init I[09-04|14:50:24.402] Generated private validator

    module=main path=/root/.tendermint/config/ priv_validator.json I[09-04|14:50:24.403] Generated node key module=main path=/root/.tendermint/config/ node_key.json I[09-04|14:50:24.403] Generated genesis file module=main path=/root/.tendermint/config/ genesis.json $ tendermint node --proxy_app=kvstore I[09-04|14:50:33.146] Starting multiAppConn module=proxy impl=multiAppConn I[09-04|14:50:33.146] Starting localClient module=abci-client connection=query impl=localClient I[09-04|14:50:33.146] Starting localClient module=abci-client connection=mempool impl=localClient I[09-04|14:50:33.146] Starting localClient module=abci-client connection=consensus impl=localClient I[09-04|14:50:33.146] ABCI Handshake module=consensus appHeight=0 appHash= I[09-04|14:50:33.146] ABCI Replay Blocks module=consensus appHeight=0 storeHeight=0 stateHeight=0 I[09-04|14:50:33.148] Completed ABCI Handshake - Tendermint and App are synced module=consensus appHeight=0 appHash= ノードの起動(1): kvstoreというサンプルアプリケーションをインプロセスで起動し、ABCIハンドシェイクをして接続する
  33. ノードの起動(2): ノードがバリデータとして起動し、周辺のピアと接続しにいこうとする (が、見つからないため1ノードで続行する) ノードの起動(3): コンセンサスが開始され、プロポーザーとして選出される。プロポーザルブロックを生成する I[09-04|14:50:33.148] This node is a

    validator module=consensus addr=11C18BAB5694F38F8A2AC7A8FEDC90C62D320700 pubKey=PubKeyEd25519{9E12F91773DCCE385FC02778AB7BB94D9C0D2249C70F44AEA7179758FBF03F86} I[09-04|14:50:33.361] Starting Node module=main impl=Nodeactor … 中略 … I[09-04|14:50:33.368] Started node module=main nodeInfo="NodeInfo{id: d662eb55503a3934ec72a6636db84a539f9ce5fe, moniker: instance-2, network: test-chain-HVlSTN [listen 10.142.0.2:26656], version: 0.23.0-013b9cef ([amino_version=0.10.1 p2p_version=0.5.0 consensus_version=v1/0.2.2 rpc_version=0.7.0/3 tx_index=on rpc_addr=tcp://0.0.0.0:26657])}" I[09-04|14:50:33.368] Ensure peers module=p2p numOutPeers=0 numInPeers=0 numDialing=0 numToDial=10 I[09-04|14:50:33.368] No addresses to dial nor connected peers. Falling back to seeds module=p2p E[09-04|14:50:33.368] Couldn't connect to any seeds module=p2p I[09-04|14:50:34.357] enterNewRound(1/0). Current: 1/0/RoundStepNewHeight module=consensus height=1 round=0 I[09-04|14:50:34.357] enterPropose(1/0). Current: 1/0/RoundStepNewRound module=consensus height=1 round=0 I[09-04|14:50:34.357] enterPropose: Our turn to propose module=consensus height=1 round=0 proposer=11C18BAB5694F38F8A2AC7A8FEDC90C62D320700 privValidator="PrivValidator{11C18BAB5694F38F8A2AC7A8FEDC90C62D320700 LH:0, LR:0, LS:0}" I[09-04|14:50:34.360] Signed proposal module=consensus height=1 round=0 proposal="Proposal{1/0 1:08E44C262B06 (-1,:0:000000000000) 05A0C21B1A54 @ 2018-09-04T14:50:34.358047426Z}" I[09-04|14:50:34.363] Received proposal module=consensus proposal="Proposal{1/0 1:08E44C262B06 (-1,:0:000000000000) 05A0C21B1A54 @ 2018-09-04T14:50:34.358047426Z}" I[09-04|14:50:34.369] Received complete proposal block module=consensus height=1 hash=048C7EC62CF3BB8C145F96517AAB93262F762B7962B79
  34. ノードの起動(4): Pre-Vote ノードの起動(5): Pre-Commit I[09-04|14:50:34.369] enterPrevote(1/0). Current: 1/0/RoundStepPropose module=consensus I[09-04|14:50:34.369]

    enterPrevote: ProposalBlock is valid module=consensus height=1 round=0 I[09-04|14:50:34.372] Signed and pushed vote module=consensus height=1 round=0 vote="Vote{0:11C18BAB5694 1/00/1(Prevote) 048C7EC62CF3 FB3D599C0A0D @ 2018-09-04T14:50:34.369900185Z}" err=null I[09-04|14:50:34.374] Added to prevote module=consensus vote="Vote{0:11C18BAB5694 1/00/1(Prevote) 048C7EC62CF3 FB3D599C0A0D @ 2018-09-04T14:50:34.369900185Z}" prevotes="VoteSet{H:1 R:0 T:1 +2/3:048C7EC62CF3BB8C145F96517AAB93262F762B79:1:08E44C262B06(1) BA{1:x} map[]}” I[09-04|14:50:34.375] enterPrecommit(1/0). Current: 1/0/RoundStepPrevote module=consensus height=1 round=0 I[09-04|14:50:34.375] enterPrecommit: +2/3 prevoted proposal block. Locking module=consensus height=1 round=0 hash=048C7EC62CF3BB8C145F96517AAB93262F762B79 I[09-04|14:50:34.377] Signed and pushed vote module=consensus height=1 round=0 vote="Vote{0:11C18BAB5694 1/00/2(Precommit) 048C7EC62CF3 E6A1CD8E697A @ 2018-09-04T14:50:34.375424414Z}" err=null I[09-04|14:50:34.380] Added to precommit module=consensus vote="Vote{0:11C18BAB5694 1/00/2(Precommit) 048C7EC62CF3 E6A1CD8E697A @ 2018-09-04T14:50:34.375424414Z}" precommits="VoteSet{H:1 R:0 T:2 +2/3:048C7EC62CF3BB8C145F96517AAB93262F762B79:1:08E44C262B06(1) BA{1:x} map[]}” ノードの起動(6): Commit I[09-04|14:50:34.380] enterCommit(1/0). Current: 1/0/RoundStepPrecommit module=consensus height=1 commitRound=0 I[09-04|14:50:34.380] Commit is for locked block. Set ProposalBlock=LockedBlock module=consensus height=1 commitRound=0 blockHash=048C7EC62CF3BB8C145F96517AAB93262F762B79 I[09-04|14:50:34.381] Finalizing commit of block with 0 txs module=consensus height=1 hash=048C7EC62CF3BB8C145F96517AAB93262F762B79 root=
  35. I[09-04|14:50:34.381] Block{ Header{ ChainID: test-chain-HVlSTN Height: 1 Time: 2018-09-04 14:50:34.357894057

    +0000 UTC NumTxs: 0 TotalTxs: 0 LastBlockID: :0:000000000000 LastCommit: Data: Validators: A84F985E84234524C58721C7BF452D4E73A48B88 App: Consensus: D6B74BB35BDFFD8392340F2A379173548AE188FE Results: Evidence: }#048C7EC62CF3BB8C145F96517AAB93262F762B79 Data{ }# EvidenceData{ }# Commit{ BlockID: :0:000000000000 Precommits: }# }#048C7EC62CF3BB8C145F96517AAB93262F762B79 module=consensus I[09-04|14:50:34.388] Executed block module=state height=1 validTxs=0 invalidTxs=0 I[09-04|14:50:34.391] Committed state module=state height=1 txs=0 appHash=0000000000000000 module=txindex height=1 ノードの起動(7): 新しいブロックが生成され、アプリケーションステートもコミットされる
  36. https://tendermint.com/docs/ tendermint-core/using- tendermint.html より詳しくはこちら Tendermintノードの実行、トランザクションの発行、バリデータの追加 etc…

  37. https://github.com/ tendermint/js-abci ABCIサーバのJS実装 js-abci とサンプルコード

  38. let createABCIServer = require(‘abci') let state = { count: 0

    } let handlers = { // …中略… deliverTx (request) { let tx = padTx(request.tx) // padTxはトランザクションデータが4bytesかチェックする関数 let number = tx.readUInt32BE(0) if (number !== state.count) { return { code: 1, log: 'tx does not match count' } } state.count += 1 // 検証がOKならステートを更新 return { code: 0, log: 'tx succeeded' } } } let port = 26658 createABCIServer(handlers).listen(port, () => { console.log(`listening on port ${port}`) }) js-abciを用いたアプリケーションロジックのサンプル: トランザクション毎にカウントアップしてステートに保持する
  39. Tendermintは、ステートの複製に関することを気にせず、プログラミング言語に縛られず セキュアでスケーラブルなブロックチェーンを容易に構築可能 今よりパワフルなブロックチェーンが続々と登場する可能性 ブロックチェーンプロコトル開発の敷居が下がり、Dapps開発の選択肢も広がる 今ある基盤がひっくり返るかもしれない まとめ Tendermint Core セキュアでスケーラブルなコンセンサスアルゴリズムと P2Pネットワークを提供

    ABCI コンセンサスエンジンとアプリケーションロジックを 分離するインターフェースを提供