こんにちは、Gunosyで新規事業担当兼CTOの松本(@y_matsuwitter)です。 先日、弊社にてblockchain.tokyo#2を開催しましたが、まとめ記事はAnypayさんの方で書いていただいたようですので、本イベントでトークさせていただいたSolidity with Test&CIについて簡易にこちらにも共有させていただこうかとおもいます。
本トークでは、Ethereumの詳細面よりも、実際にEthereumに興味をもったデベロッパーの皆さんが簡単に開発環境を構築してコードを書き始めてもらうことを主眼に用意したものなので、Truffleによるテストをすでに進めているという方には物足りないかもしれません。
スライドはこちら。
Ethereum、EVM、そしてSolidity
今回の勉強会では個人的に調査・開発しているEthereum、およびその上でのアプリケーション実行環境であるEVM、そこでの実行コードを記述できるSolidityとその基本的な開発フローについて解説させていただきました。
Ethereumについては、その開発規模や流通している時価総額もあってか多くの解説も出ており、またご存じの方も多いかと思います。 簡単にいえばEthereumとは「中央のいない分散型のアプリケーション(Dapps)の実行環境」ということが出来、World Computerを志向したブロックチェーンと言えます。
自分はEC2とS3に始まるクラウドコンピューティングやマネージド・サービスの登場から昨今のServerlessという流れを踏まえた上で、こうした分散実行環境は将来的に次のアーキテクチャの一部として認識しても良いものかと思い注目しています。
さて、どなたでもEthereumの上でアプリケーションを開発できるわけですが、そのアプリケーションはどういった構造で動作しているのでしょうか。スライドでも説明させていただきましたが、Ethereumのアプリケーションは、コントラクトと呼ばれる実行コードが登録されたアドレスに対して所定のパラメタを付与したトランザクションを発行することで、登録された機能を実行する形式になっております。 この実行環境のことをEVM (Ethereum Virtual Machine)といい、その実行コードをEVM Codeと呼びます。EVM Codeはスタック言語と呼ばれるBitcoinのScriptと同種の低級言語をbytecodeで記録したもので、Bitcoinとの違いはチューリング完全である点です。 実行に際しては、EVM Codeに定義されているOpcodesと呼ばれる各種命令のスタックをEVMが解釈し実行するのですが、この際にEthereum上のトークンとして設計されているEther(ETH)を利用料として徴収します。これをGasと呼び、ETHが通貨ではなく燃料であると呼ばれる所以です。 コントラクトに対してトランザクションを発行すると自身で設定したGas Fee(普段送金手数料として見ている事が多いかもしれません)と呼ばれる手数料に対して、スタック上のOpCodesを一つ実行するごとに命令それぞれで設定されたコスト分をマイナスしていき、0になる、ないしは停止するまで実行していきます。燃料を設定することでブロックチェーン上で悪意のあるコストの高いコードの実行に対して、金銭的な壁を設けているわけですね。
この仕組を踏まえると、コントラクトを実際に自分で作成する際にはEVM Codeを開発する必要があるわけですが、非常に低級な言語であるため現実的でありません。これらに対して現状ではいくつかの高級言語が公開されており、その一つがSolidityというわけです。 SolidityはJavascriptライクな文法で書くことができ、solcコンパイラを通じてEVM Codeを生成することが出来ます。言語の仕様等に興味のある方は公式ドキュメントから入ると良いでしょう。
公式ドキュメント
https://solidity.readthedocs.io/en/develop/
Solidityの言語詳細は今回のブログでは割愛しますが、我々がEthereum上で実行可能なコントラクトを実装し分散アプリケーションを作成するためには、Solidityでコントラクトを記述し、それらをEVM Codeとしてコンパイルし、Ethereum上にデプロイする、という流れを踏まえておけばよいでしょう。
SolidityでtestとCIをするということ
実際にアプリケーションを開発するとなると、皆さん当然TestやCIの情報を調べ始めると思います。 EthereumでのDappを書く際には、普段のコード以上にTestとCIについて考える必要があります。 なぜなら、Ethereumのコントラクトは不変であり一度デプロイすると更新することが出来ません。 それはEthereumがこれまで直面してきたThe DAO事件やParity Multisig Walletの凍結事件のような騒動に発展しています。いずれもコントラクトの実装ミスから数十〜数百億の資金が盗難ないしは凍結されるという被害につながっております。
こうしたミスを未然に防ぐため、コードのベストプラクティスを都度収集・共有する姿勢も重要ですがそれ以上に徹底してテストによる検証を行うことが重要であると考えています。
Truffle 4.0を使おう
こうしたコントラクトのテストコードの記述とCIをサポートするツールはいくつか有りますが、現状ではTruffle 4.0を利用するのが最も取りやすい手段だと考えています。 Truffle
実際のEthereumのコントラクト実行については、先に述べた通りコントラクトアドレスに対するトランザクションを完了させることで行われるものです。これはつまりテスト的な実行をするにもEthereumのブロックチェーンと接続し、都度トランザクションの送信とそれを実行するマイナー相当のプロセスが必要ということになります。 テスト実行に都度そうしたブロックチェーンの構築とマイニングは、その実行時間的にも非現実的です。 こうした状況に対して、TruffleはEthereumをエミュレートするテストネットワーク機能(TestRPC)を備えており、こちらを利用することで実際にブロックチェーンを用意することなく低コストでテストコードの記述が可能となっています。
実際のテストコードについては、Solidityのコントラクトのデプロイ・実行、そしてその値に対するアサーションをJavascriptにてMochaライクなスタイルで記述していきます。 例を挙げると下記のようなものになります。
var MetaCoin = artifacts.require("MetaCoin"); contract('MetaCoin', function(accounts) { it("should put 10000 MetaCoin in the first account", // asyncを利用 async function() { // deployされたコントラクトを取得 var d = await MetaCoin.deployed() // 残高の取得 var balance = await instance.getBalance.call(accounts[0]) assert.equal(balance.valueOf(), 10000, "10000 wasn't in the first account"); }) })
基本的には①Contractの実体をネットワークに作成・ないしはデプロイ済みのものを取得②トランザクションの送信③値の検証と言った流れをPromiseを利用して記述します。 上記ではTruffleをnode 7.6以降で実行しており、async/awaitを用いた記述に書き換えています。
Truffle 4.0以上のバージョンでは、TestRPC機能を内包し、truffleコマンド単体で上記のテストを実行、また実際のネットワークに対するデプロイが可能なためCircleCI等のCIツール上でも1コマンドで検証を実行することが可能です。
実際のテストにおいては、過去リリースされてきた大規模なDappsプロジェクトや広く使われているSolidityフレームワークのテストを読むことが一番勘所をつかみやすいのかなと思いますので、自分が参考にしているリポジトリを最後に紹介しておきます。
OpenZeppelin/zeppelin-solidity github.com
ALISプロジェクト github.com
最後に
Dappsは自分が今後の発展を楽しみにしている技術の一つです。 様々な仲介のあるアプリケーションをより効率的に実装し、公開する手段を新しいアーキテクチャで実現できるものだと思います。 個人開発者でもDappsの開発は比較的容易であり、安全な運用に関してもtruffleといった周辺ツールの充実化とベストプラクティスの集積から可能になってきていると思います。 ぜひ、皆さんもEthereum上でなんらかのDappsを作って公開してみましょう。
Blockchain.tokyoは今後も継続的に開催していく予定です。 特に国内においてBlockchainを技術的トピックとして取り扱うエンジニア向けコミュニティとして大きなものにしていきたいと思っております。興味ある方ぜひぜひ今後もご参加ください。 blockchain-tokyo.connpass.com
また、弊社の新規事業開発室ではブロックチェーンやスマートスピーカー、VR/ARと言った新規領域での研究・開発を進めており、メンバーを募集しております。 www.wantedly.com