Boilerplateを使ったDapps(分散型アプリケーション)の作成(2)
前回の続きです。 前回 -> sendeetech.hatenablog.com
ブロックチェーンをコントロールする
前回の作業ですでにEthereumのAPIであるgethにコマンドを送ることで、Ethereumが起動した状態になっています。
その状態でマイニングをスタートしてみます。
> miner.start() true
マイニングが行われているかどうかは下記コマンドで確認できます。
> miner.hashrate 500450 //ゼロじゃなかったらマイニングされている状態
ストップは下記です。
> miner.stop() true
今回はマイニングをしたまま開発を進めていきます。
アプリケーションの全体像
フォルダ構成は(抜粋すると)下記のようになっているかと思います。
├── client │ ├── collections.js │ ├── index.js │ ├── lib │ │ ├── compatibility │ │ │ └── bootstrap.js │ │ ├── contracts │ │ │ └── MultiplyContract.sol │ │ ├── helpers │ │ │ ├── helperFunctions.js │ │ │ └── templateHelpers.js │ │ └── thirdparty │ │ ├── chance.min.js │ │ └── web3 │ │ └── web3.js │ ├── meta.js │ ├── routes.js │ ├── stylesheets │ └── templates │ ├── components │ │ ├── accounts.html │ │ ├── accounts.js │ │ ├── balance.html │ │ ├── balance.js │ │ ├── multiplyContract.html │ │ ├── multiplyContract.js │ │ ├── networkHealth.html │ │ └── networkHealth.js │ ├── index.html │ ├── layout │ │ ├── _footer.html │ │ ├── _header.html │ │ ├── main.html │ │ └── notFound.html │ └── views │ ├── view1.html │ ├── view1.js │ ├── view2.html │ └── view2.js ├── i18n ├── project-tap.i18n ├── public │ ├── fonts │ └── images ├── settings.json ├── test-genesis.json └── tests └── mocha └── client └── MultiplyContract.js
Meteorでよく見かけるのは、ServerとClientにディレクトリを分けて、それぞれのサイドにおける開発を進めていく形でしょうか。
今回は、serverフォルダは存在せずに、Client側からだけで(実質的には)開発が可能なのMeteorの特徴が現れてています。
その他、簡単にピックアップして説明すると、
- Meteorのデファクトスタンダードなルーティング用ライブラリ「iron-router」でルーティングが行われている
- Viewは、
layout/main.html
からviews/view1 or views/view2
を呼び出し views/view1 or views/view2
からcomponents/
以下の各テンプレートファイルを呼び出し- Componentsフォルダの各htmlファイル名に対応してJSファイルが作成される
- (基本的には)JSファイル内に、各Viewで呼び出すためのhelperやイベントを記載していく
上記は主にMeteorの知識ですが、今回の特徴は、 Smart Contract を記載しているアプリであることです。
SmartContractは、デフォルトでは、 client/lib/contracts
以下に記載されています。
Meteorは独特の読み込みルールがあるため、それを意識した書き方が必要になります。
(参考:Meteor 開発者がおさえておきたい「ファイルの読み込み順番(File Load Order)」
)
SmartContractの中身
.sol
という拡張子で保存されています。- Congractは「Solidity」という専用の言語で記載されています。
client/lib/contracts/multiplyContract.sol
の中身は下記の通りです。
contract MultiplyContract { function multiply(uint a) returns(uint d) { return a * 7; } }
上記のコードは、見たままではありますが、
- MultiplyContract という契約を宣言
- 変数aと戻り値bを宣言して、引数を7倍したuint(符号なし整数)を戻す
ということを記述しています。
JSベースの言語で、チューリング完全を謳っており、どんな複雑な契約でもプログラミングにおとしこめるものであれば理論上は実現できます(ということになっています)。
SmartContractの動作確認
Cloneしたままの状態で、Meteorを起動すると、View2へのリンクがあるはずです。
View2を開くとこのような画面が出るはずです。
この画面に対応するhtmlとjsファイルは、 multiplyContract.html
と multiplyContact.js
です。
下記は、multiplyContract.jsの抜粋です。
Template['components_multiplyContract'].events({ /** On "Create New Contract" click @event (click .btn-default) */ "click .btn-default": function(event, template){ // Create Contract TemplateVar.set('state', {isMining: true}); // Set coinbase as the default account web3.eth.defaultAccount = web3.eth.coinbase; // assemble the tx object w/ default gas value var transactionObject = { data: MultiplyContract.bytecode, gasPrice: web3.eth.gasPrice, gas: 500000, from: web3.eth.accounts[0] }; // estimate gas cost then transact new MultiplyContract web3.eth.estimateGas(transactionObject, function(err, estimateGas){ // multiply by 10 hack for testing if(!err) transactionObject.gas = estimateGas * 10; MultiplyContract.new(transactionObject, function(err, contract){ if(err) return TemplateVar.set(template, 'state', {isError: true, error: String(err)}); if(contract.address) { TemplateVar.set(template, 'state', {isMined: true, address: contract.address, source: source}); contractInstance = contract; } }); }); }, /** On Multiply Number Input keyup @event (keyup #multiplyValue) */ "keyup #multiplyValue": function(event, template){ // the input value var value = template.find("#multiplyValue").value; // call MultiplyContract method `multiply` which should multiply the `value` by 7 contractInstance.multiply.call(value, function(err, result){ TemplateVar.set(template, 'multiplyResult' , result.toNumber(10)); if(err) TemplateVar.set(template, 'multplyResult' , String(err)); }); }, });
こちらも簡単にですが説明すると、
.btn-default
がクリックされた際にイベントを発生させる- Web3というJavaScript APIを用いて、ブロックチェーンにアクセスしたり色んなアクションを発生させたりする
- Web3についてはこちら(JavaScript API)
.sol
で記載したコントラクトをMultiplyContract
クラスのように扱うことができる- コントラクトが実行されるには、(testnetで)マイニングがされていることと、適切に取引時のgasを設定することが必要
あとは通常のJSが扱えれば理解は出来るかと思います
動作後の画面
実際にボタンを押してみると下記のように取引実行後の画面が表示されます
Contractがブロックチェーン上に流された結果、Contractのaddressが生成され、実行できるようになりました。
「Type a value here to multiply」に数字を入力すると、(実際にはクライアント側での動作ですが)記載した契約通りに7倍された数字が戻ってくるのが分かるかと思います。
今回もデフォルトのBoilerplateの説明に終始してしましましたが、次回は最後に、ContractやViewをカスタマイズして独自のDappを作成してみたいと思います。