Truffleとnode.jsでwebブラウザにHelloEthereum!

スマートコントラクトを用いてwebブラウザ上にHelloEthereum!を表示させたいと思います．
Truffle,node.js,Ganacheを使うので下記のサイトを参考にインストールしてください．

>[Dapps作成手順をイチから学べる！Truffleの「イーサリアム・ペットショップ」](http://kojiryo.com/811/)

#コントラクトをデプロイする

ではまず任意のディレクトリにHelloEthereumというディレクトリを作成してください．

```
mkdir HelloEthereum
```

次に環境の構築をしていきます．
今回はtruffleというフレームワークを使用します．
truffleはEthereumの開発言語であるsolidityでの開発をサポートするフレームワークです．
まず以下のコマンドで初期化します．

```
truffle init
```

次に下記のコマンドでsolidityのファイルを作成します．

```
truffle create contract HelloEthereum
```

contract内にHelloEthereum.solというファイルが作成されるので編集します．

```solidity:HelloEthereum.sol

pragma solidity ^0.4.22;

contract HelloEthereum {
  
  string private _word;
  constructor() public {
    _word = "HelloEthereum!";
  }
  function get() public view returns(string){
    return _word;
  }
}
```

getという関数を呼び出すとHelloEthereum!を返すというものです．

次にこのファイルをコンパイルします．

```
truffle compile
```
コンパイルが成功すると`build`ディレクトリが生成されます．

次に`migration`ファイルを作成します．

`migrations`の中に`2_deploy_contracts.js`というファイルを作成してください．

```javascript:2_deploy_contracts.js
var HelloEthereum = artifacts.require("HelloEthereum");

module.exports = function(deploy){
    deploy.deploy(HelloEthereum);
}
```
次に`truffle.js`ファイルを編集します．

```javascript:truffle.js

module.exports = {
    networks:{
        development:{
            host: "127.0.0.1",
            port: 7545,
            network_id: "5777"
        }
    }
}
```

`host`,`port`,`network_id`は自身の設定に変更してください．
起動したらページの上部に記載されています．
<img width="1198" alt="スクリーンショット 2018-09-17 17.44.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/146752/a7b88b80-f42e-fc70-2cc9-0cdd0495d9a6.png">



最後に`ganache`を起動してから下記のコマンドでデプロイします．

```
truffle migrate
```

これでひとまずはテスト環境のブロックチェーンにデプロイが完了しました．

#サーバの設定

node.jsを用いてサーバ環境を構築します．

```
npm init -y
```

今回はlite-serverを使用します．

```
npm install lite-server --save
```

そしてbs-config.jsonというファイルを作成します．
今回使用するlite-serverの設定ファイルです．

```json:bs-config.json
{
  "server": {
    "baseDir": ["./src", "./build/contracts"]
  }
}
```

次にsrcフォルダを作成してください．
そしてtruffle-contractをインストールします.

```
npm install truffle-contract --save
```
`node-modules/truffle-contract/dist`内の`truffle-contract.js`というファイルをsrc内にコピーします．

最後に`package.json`を次のように編集します．
`scripts`に`"dev": "lite-server"`を追加します．

```json:package.json
{
  "name": "HelloEthereum",
  "version": "1.0.0",
  "description": "",
  "main": "truffle-config.js",
  "directories": {
    "test": "test"
  },
  "dependencies": {
    "lite-server": "^2.4.0",
    "truffle-contract": "^3.0.6"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "lite-server"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```

これでサーバの設定は終了です．

#フロントエンド部分の作成

最後にフロントエンドの部分を作成します.
`index.html`と`index.js`というファイルを作成し以下のように編集します．

```html:index.html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello Ethereum</title>
        <script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    </head>

    <body>
        <script type="text/javascript" src="./truffle-contract.js"></script>
        <script type="text/javascript" src="./index.js"></script>
    </body>
</html>
```

```javascript:index.js
App = {
    web3Provider:null,
    contracts: {},

    initWeb3: function(){
        App.web3Provider = new web3.providers.HttpProvider("http://localhost:7545");
        return App.initContract();
    },

    initContract: function(){
        $.getJSON('HelloEthereum.json', function(data){
            var Artifact = data;
            App.contracts.HelloEthereum = TruffleContract(Artifact);

            App.contracts.HelloEthereum.setProvider(App.web3Provider);

            App.contracts.HelloEthereum.deployed().then(function(instance) {
                return instance.get.call();
            }).then(function(adopters){
                document.write(adopters);
            }).catch(function(err){
                console.log(err.message);
            });
        });
    }
}

window.onload = function(){
    App.initWeb3();
}
```

以下のコマンドを叩くとサーバが立ち上がりブラウザが立ち上がります．

```
npm run dev
```

HelloEtereumと表示されていたら成功です．お疲れ様でした．