Slide 1

Slide 1 text

Solidity with Test & CI At Blockchain.tokyo #2 @y_matsuwitter

Slide 2

Slide 2 text

2 ©Gunosy Inc. ⾃⼰紹介 n Gunosy Inc. – 新規事業開発室 執⾏役員 CTO n 業務 – 開発全般のマネジメント – 技術に関する横断的な課題対処 – 現在は新規事業⽴ち上げがメイン – 新規技術周りの検証・事業提案 n 経歴 – 現在28歳 – 在学時に⼆社のベンチャーの⽴ち上げ・ 開発に携わり1つ事業売却 – 2013年3⽉ 東京⼤学⼯学部卒業 – 2013年1⽉よりGunosyに⼊社 – 2014年6⽉執⾏役員就任、現在に⾄る 松本 勇気 @y_matsuwitter

Slide 3

Slide 3 text

3 ©Gunosy Inc. 【本⽇話すこと】 SolidityでテストとCIを如何に実装するか (Smart Contractそのものには触れません)

Slide 4

Slide 4 text

4 ©Gunosy Inc. EthereumとSolidity “Ethereum as a World Computer” を実現する⼿段の⼀つ。 n Ethereum上のコントラクトはEVM Codeと して保存されている。 – EVM = Ethereum Virtual Machine – チューリング完全 n SolidityはEVM Codeに対する⾼級⾔語 – CompileしてEVM Codeに変換される。 n Javascriptライクな⾔語だが、変数の考え⽅ 等⼤きく異る点も多い。 – 特にvisibility関連に注意。 Ethereum上のスマートコントラクトを記述する⼿段の⼀つ。 Solidity EVM Code Ethereum Compile Deploy

Slide 5

Slide 5 text

5 ©Gunosy Inc. EVM Codeは如何に動作するのか Etherを燃料としてチェーン上のコードの状態を変更する作業と捉える。 n Opcodesのシーケンスとして表現される。 n 動作⾃体は、Blockchainをコントラクトの状 態を記録したものとして考える。 n 記録されたコードにパラメタ付きのトランザ クションを送って実⾏ – 状態変化を伴わないものは利⽤料不要で callとして呼び出せる。 n 実⾏に対する利⽤料としてのGas – OpcodesごとのGasコストの合計値 基本的にはブロックチェーン上のトランザクションとして表現される。 Ethereum Transaction Call 状態を書き換え 値の読み出し EVM Code

Slide 6

Slide 6 text

6 ©Gunosy Inc. Solidityを学ぶ題材 国内のICO 海外のICO/Dapps フレームワーク n ALIS – メディアプラット フォーム – ICOの実装有 – Zeppelin-solidity ベース n Status – Interface for Ethereum – ERC20 tokenや Multisig wallet有 n Augur – 予測市場 – 殆どのコアロジッ クがSolidity n Zeppelin-solidity – Consensys製 – 数値演算の WrapperやERC20 トークンの標準形 など。 既存の動いているコードがどのように実装されているか知る。 現状のICOをしたプロダクトの多くはソースコードが⾒れる。

Slide 7

Slide 7 text

7 ©Gunosy Inc. Solidityでテストを書く理由 ロールバックが難しい分テストとレビューを徹底する。 n Parity Multisig Walletの事例 – 300億円分のEtherを持つmultisigウォ レットにバグが混⼊ – 全てのEtherが凍結・動かすことが不可 能な状態に。 n Testの重要性 – 不具合発⽣時のロールバックは容易では ない。 – 正しい挙動やエッジケースをカバーでき ているかデプロイ前に常に確認する。 – (当然ですね) Solidityでのミスは、場合によっては簡単に⼤規模な損害へ。 参考: https://paritytech.io/blog/security-alert.html

Slide 8

Slide 8 text

8 ©Gunosy Inc. テストフレームワークの⽐較 truffle Pythereum.testing テスト 記述⾔語 特徴 利⽤事例 n Javascript n Solidity n Solidity周辺のマイグレーション 管理等含む開発ツール n Consensys製 n Status-network-token n OpenZeppelin/zeppelin-solidity – ERC20トークン実装等を集 めたフレームワーク n Python n Ethereumのpython向けコアラ イブラリに含まれるテストツー ル n augur-core – Solidityで記述、 pythereumでテスト 今回は⾃分が利⽤しているtruffleを主に紹介。 いくつかのフレームワークが存在するが、2つ紹介。

Slide 9

Slide 9 text

9 ©Gunosy Inc. Truffleのテストについて Javascript, Solidityの双⽅でテストを記述可能、今回はJSを利⽤。 Solidityの記述・コンパイル・デプロイ・テストを全てtruffleで管理可能。 n テスト対象のnetworkに対するデプロイや、 後述のtestrpcと連携してtear downの処理な どを効率化。 n JSではMochaスタイルで記述。 – 慣れたBDD形式等でテストを書ける。 n ブロックチェーンとのやり取りはPromiseや Async/AwaitでWrapされている。 – 環境をNode.js 7.6で⽤意して async/awaitの利⽤をおすすめします。 例: token残高を取得するテスト

Slide 10

Slide 10 text

10 ©Gunosy Inc. ethereumjs-testrpcについて Testrpcを使ってテストを⾼速に回す。 n Contractの実⾏完了 = ブロックの⽣成 n Local networkの難点 – CPUを⼤きく消費する。 – テスト毎に状態を巻き戻すことのコスト が⾼い。 n testrpc – Ethereumのネットワーク挙動を模した RPCを⽴ち上げ。 – テストごとに状態を⼀定に保てる。 ローカルでマイニングを回しながらのテストはコスト的にも時間的にも⾯倒。 図:Testrpcの起動、オプションに従ってアドレス等を発行

Slide 11

Slide 11 text

11 ©Gunosy Inc. Testrpc + truffleでCI Docker-composeを使ってテスト環境を⽤意する。 n Truffle.jsでtestrpcを指定 n TestrpcはsendTransaction等を受けてブロッ クチェーンの挙動を模してくれる。 n Testrpcは別プロセスで⽴ち上がる。 – CI時はdocker-compose等で実⾏環境を 作ると楽 – truffle実⾏コンテナとtestrpcをdocker でlinkする。 紹介した2つを組み合わせることでCircleCIでもsolidityのCIが回せる。 Solidity testrpc EVM code Test code truffle deploy test

Slide 12

Slide 12 text

12 ©Gunosy Inc. この資料の作成中に truffle 4.0がリリースされました

Slide 13

Slide 13 text

13 ©Gunosy Inc. Truffle 4.0での変更点 truffle test でテストが完結するようになった。 l test実⾏時に⾃動でtest networkが⽴ち上がる。 実⾏時のMnemonicが固定されアドレスが常に固定に。 l テストコードにアドレスを書くことも(⼀応)可能に。 — 個⼈的にはハードコードはおすすめしませんが… デバッグコンソールの追加 l truffle developでlocalで操作可能な対話環境を利⽤できる。 Testrpcが内蔵され、テスト実⾏が簡略化されました。

Slide 14

Slide 14 text

14 ©Gunosy Inc. truffle Truffle 4.0による簡略化 すでにTruffleをお使いの⽅はすぐにupgradeしましょう。 n DockerComposeを利⽤しての連携は不要 – 先述の通り、testrpcは内包された。 n 移⾏の場合はtruffle.jsを修正。 – 設定中のdevelopment, testは不要、削 除することでtruffle内蔵のtestrpcを参 照するようになる。 CI時に必要なのは truffle testのみになった。 Solidity Rpc EVM code Test code deploy test

Slide 15

Slide 15 text

15 ©Gunosy Inc. 実際にCIを⾒てみる。 y-matsuwitter/eventeth-contracts

Slide 16

Slide 16 text

16 ©Gunosy Inc. テストコードの例 Async/awaitを使うと記述が楽です。

Slide 17

Slide 17 text

17 ©Gunosy Inc. テスト時のハマリポイント すべてが「invalid op_code」エラーになる。 l コンパイルされたSolidityコード上の論理エラーはinvalid op_codeとして扱われる。 l Requireに引っかかってもInvalid op code!! l 原因が⾒えず⾟い。 nowの扱い l now関数は、ブロック時刻を返します。 l 現在時刻ではありませんのでテストを書く際も注意。 基本的にtestrpcやgethからの応答は不親切。

Slide 18

Slide 18 text

18 ©Gunosy Inc. テスト時の幾つかのhack evm_increaseTime l ブロックの時刻を強制的 に進める。 l ICO等ある時刻になった ら解放等のテストに役⽴ つ。 evm_mine l Miningをtestrpcに強制。 l 意図的にblock numberを 進めたい時など。

Slide 19

Slide 19 text

19 ©Gunosy Inc. SmartContractは安全第⼀ 1 テストできる、とはいえ… 3 Truffle4.0でテストやCIは簡単に実施可能 2 まとめ n ⼀度登録したコントラクトで⼤きなミスが起きるとケースによってはロールバック 不可能・⼤損失へ。 n セキュリティ等のベストプラクティスを常に追い続ける。 n MochaライクなBDDスタイルのテストコードでSolidityの振る舞いを検証可能。 n TruffleのRPCを利⽤して⾼速にローカルテストを回せる。 – 常にCIを実⾏することで最低限の動作確認を担保する。 n リリースまでには、Testrpc => Localのgeth等のネットワーク => Ropsten等の Testnet => 本番環境でのデプロイ => 最終動作確認のステップは必ず踏むべき。 Ethereumの更新に⽬を向けつつ、安全性を最優先に開発しましょう。 SolidityのテストとCIを含む開発の始め⽅について。