Boilerplateを使ったDapps(分散型アプリケーション)の作成(2)


前回の続きです。
前回 -> [Boilerplateを使ったDapps(分散型アプリケーション)の作成(1)](http://qiita.com/Y-Mukoyama/items/5d751dc01ea4a45dc850)

## ブロックチェーンをコントロールする
前回の作業ですでに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)」
](http://qiita.com/n-oshiro/items/be9be5639e09e2b80902))

## 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を開くとこのような画面が出るはずです。

![Screen Shot 2016-05-16 at 17.55.18.png](https://qiita-image-store.s3.amazonaws.com/0/87650/3144eea7-131a-d8f7-50d6-9848dfd60641.png "Screen Shot 2016-05-16 at 17.55.18.png")


この画面に対応する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](https://github.com/ethereum/wiki/wiki/JavaScript-API))
- `.sol` で記載したコントラクトを `MultiplyContract` クラスのように扱うことができる
- コントラクトが実行されるには、(testnetで)マイニングがされていることと、適切に取引時のgasを設定することが必要


あとは通常のJSが扱えれば理解は出来るかと思います

## 動作後の画面
実際にボタンを押してみると下記のように取引実行後の画面が表示されます

![Screen Shot 2016-05-16 at 18.31.55.png](https://qiita-image-store.s3.amazonaws.com/0/87650/7c1b9cbf-279c-c02b-e033-ca24d6147930.png "Screen Shot 2016-05-16 at 18.31.55.png")

Contractがブロックチェーン上に流された結果、Contractのaddressが生成され、実行できるようになりました。

「Type a value here to multiply」に数字を入力すると、(実際にはクライアント側での動作ですが)記載した契約通りに7倍された数字が戻ってくるのが分かるかと思います。

<br>
今回もデフォルトのBoilerplateの説明に終始してしましましたが、次回は最後に、ContractやViewをカスタマイズして独自のDappを作成してみたいと思います。

[Boilerplateを使ったDapps(分散型アプリケーション)の作成(3)](http://qiita.com/Y-Mukoyama/items/36586d4b2a7e550bf2e1)