Dockerで構築するEthereum PET-SHOP TRUFFLE BOXES（その1）

[TruffleBoxs 入門](https://www.programmers-office.ml/truffleboxs-%e5%85%a5%e9%96%80/)（以下「入門記事」）
では、下記サイト（以下「React&Truffle記事」）をなぞらせていただきました。
[TruffleBox (React&Truffle)を用いたDockerでのdapps（ブロックチェーンアプリ）の開発環境の構築](https://qiita.com/dl10yr/items/26b106d27a2de87da131)


本記事では、より実践的なチュートリアルに挑戦ということで、ペットショップをやってみたいと思います。

[ETHEREUM PET SHOP -- YOUR FIRST DAPP](https://www.trufflesuite.com/tutorials/pet-shop)

ちなみに、このチュートリアルとはどのようなものなのか、今話題のDeepLで翻訳すると、このようになりました。

>このチュートリアルでは、ペットショップのための養子縁組追跡システムを作成するプロセスを説明します。
>
>このチュートリアルは、Ethereumとスマートコントラクトの基本的な知識があり、HTMLとJavaScriptの知識はあるが、ダップスには初めての方を対象としています。


## 開発環境構築

### Docker環境

[React&Truffle記事](https://qiita.com/dl10yr/items/26b106d27a2de87da131)を参考に、使用するTruffleBox をペットショップに変更する形でDocker環境を用意します。

```yaml:docker-compose.yml
version: '3'

services:
  truffle:
    build: 
      context: ./trufflebox/
      dockerfile: Dockerfile
    volumes:
      - ./trufflebox:/usr/src/app
    command: sh -c "cd client && yarn start"
    ports:
      - "8003:3000"
```

```Docker:Dockerfile
FROM node:8-alpine  

RUN apk add --update alpine-sdk
RUN apk add --no-cache git python g++ make \
    && npm i -g --unsafe-perm=true --allow-root truffle 

WORKDIR /usr/src/app
```

この2ファイルを下記構成で作成。

```shell:
pet-shop
├── docker-compose.yml
└── trufflebox
    └── Dockerfile
```

pet-shopフォルダで、下記を実行。

```shell:
$ docker-compose build
Building truffle
Step 1/4 : FROM node:8-alpine
 ---> 2b8fcdc6230a
Step 2/4 : RUN apk add --update alpine-sdk
 ---> Using cache
 ---> 761342077e72
Step 3/4 : RUN apk add --no-cache git python g++ make     && npm i -g --unsafe-perm=true --allow-root truffle
 ---> Using cache
 ---> 82200b1b0c8f
Step 4/4 : WORKDIR /usr/src/app
 ---> Using cache
 ---> 4eb121f5853d
Successfully built 4eb121f5853d
Successfully tagged pet-shop_truffle:latest
```


```shell:
$ docker-compose run truffle truffle unbox pet-shop
Creating network "pet-shop_default" with the default driver
You can improve web3's performance when running Node.js versions older than 10.5.0 by installing the (deprecated) scrypt package in your project
This directory is non-empty...
? Proceed anyway? (Y/n) 
Starting unbox...
=================

? Proceed anyway? Yes
✔ Preparing to download box
✔ Downloading
npm WARN pet-shop@1.0.0 No description
npm WARN pet-shop@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

✔ cleaning up temporary files
✔ Setting up box

Unbox successful, sweet!

Commands:

  Compile:        truffle compile
  Migrate:        truffle migrate
  Test contracts: truffle test
  Run dev server: npm run dev
```

React&Truffle記事では、「unbox react」としていたところを、今回は、「unbox pet-shop」とするわけです。
これにより、
https://www.trufflesuite.com/boxes/pet-shop
を使用していることになります。

### Ethereum ネットワーク

React&Truffle記事を参考に、Docke環境からローカルのGanache のテストネットワークに接続します。

まず、ローカル環境に接続可能なIPアドレスを割り振ります。
ローカルIPアドレスない場合は設定します。（React&Truffle記事、及び、入門記事参照）
そして、Ganache の設定画面で、ローカルIPアドレスで起動するように指定します。
<img width="320" alt="スクリーンショット 2020-03-24 20.32.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77307/b2637bca-cce5-bf05-40db-358cfdba9626.png">
PORT NUMBER は7545としておきます。これは後で出てきます。

この状態で、METAMASKで接続できることを確認しておきます。
METAMASKは、このアドレス、ポートで接続するための設定を追加します。
<img width="160" alt="スクリーンショット 2020-03-24 21.22.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77307/f63c0d02-03bd-10ae-8921-dcfe48da68c1.png">

ここに接続するように、truffle-config.jsを構成します。
先ほど実行された、unbox pet-shop により、trufflebox フォルダに、ファイルが作成されています。

自動作成されたtruffle-config.js は下記のようになっていました。

```js:truffle-config.js（自動作成）
module.exports = {
  // See <http://truffleframework.com/docs/advanced/configuration>
  // for more about customizing your Truffle configuration!
  networks: {
    development: {
      host: "127.0.0.1",
      port: 7545,
      network_id: "*" // Match any network id
    },
    develop: {
      port: 8545
    }
  }
};
```

truffleは、ネットワーク名を指定しなければ、development を使用します。
ですので、この中の設定を変更します。

```js:truffle-config.js（変更）
module.exports = {
  // See <http://truffleframework.com/docs/advanced/configuration>
  // for more about customizing your Truffle configuration!
  networks: {
    development: {
      host: "10.200.10.1",
      port: 7545,
      network_id: "*" // Match any network id
    },
    develop: {
      port: 8545
    }
  }
};
```

そして、マイグレート＝Ganache へのデプロイ。

```shell:
$ docker-compose run truffle truffle migrate
You can improve web3's performance when running Node.js versions older than 10.5.0 by installing the (deprecated) scrypt package in your project

Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.



Starting migrations...
======================
> Network name:    'development'
> Network id:      5777
> Block gas limit: 0x6691b7


1_initial_migration.js
======================

   Deploying 'Migrations'
   ----------------------
   > transaction hash:    0xd032d73ed143eeb44062f09d02fa64888d9c133d3addb2ff79ccef63d7a4f1ff
   > Blocks: 0            Seconds: 0
   > contract address:    0xF88b3D9805da39D094178f2ba0dCc38a0610d214
   > block number:        5
   > block timestamp:     1585053865
   > account:             0xc55F3d6C444ca88f529F3413EDEd85a39e38609C
   > balance:             99.98893326
   > gas used:            188483
   > gas price:           20 gwei
   > value sent:          0 ETH
   > total cost:          0.00376966 ETH


   > Saving migration to chain.
   > Saving artifacts
   -------------------------------------
   > Total cost:          0.00376966 ETH


Summary
=======
> Total deployments:   1
> Final cost:          0.00376966 ETH
```

起動。

```shell:
$ docker-compose up
Creating pet-shop_truffle_1 ... done
Attaching to pet-shop_truffle_1
truffle_1  | sh: cd: line 1: can't cd to client: No such file or directory
pet-shop_truffle_1 exited with code 2
```

おっと失敗。フォルダ構成違うんですね。
docker-compose.ymlのcommandを修正します。

```yaml:docker-compose.yml
version: '3'

services:
  truffle:
    build: 
      context: ./trufflebox/
      dockerfile: Dockerfile
    volumes:
      - ./trufflebox:/usr/src/app
    command: sh -c "npm run dev"
    ports:
      - "8003:3000"
```

```shell:
$ docker-compose up
Recreating pet-shop_truffle_1 ... done
Attaching to pet-shop_truffle_1
truffle_1  | 
truffle_1  | > pet-shop@1.0.0 dev /usr/src/app
truffle_1  | > lite-server
truffle_1  | 
truffle_1  | ** browser-sync config **
truffle_1  | { injectChanges: false,
truffle_1  |   files: [ './**/*.{html,htm,css,js}' ],
truffle_1  |   watchOptions: { ignored: 'node_modules' },
truffle_1  |   server: 
truffle_1  |    { baseDir: [ './src', './build/contracts' ],
truffle_1  |      middleware: [ [Function], [Function] ] } }
truffle_1  | [Browsersync] Access URLs:
truffle_1  |  -----------------------------------
truffle_1  |        Local: http://localhost:3000
truffle_1  |     External: http://172.22.0.2:3000
truffle_1  |  -----------------------------------
truffle_1  |           UI: http://localhost:3001
truffle_1  |  UI External: http://localhost:3001
truffle_1  |  -----------------------------------
truffle_1  | [Browsersync] Serving files from: ./src
truffle_1  | [Browsersync] Serving files from: ./build/contracts
truffle_1  | [Browsersync] Watching files...
truffle_1  | [Browsersync] Couldn't open browser (if you are using BrowserSync in a headless environment, you might want to set the open option to false)
```

ブラウザで、
http://localhost:8003/
を開きます。画面が開きます！

<img width="400" alt="スクリーンショット 2020-03-24 23.43.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77307/49e80a72-12e7-9703-7f82-e938d0d590fa.png">

これにより、[PET-SHOPトリュフボックス](https://www.trufflesuite.com/boxes/pet-shop)のInstallationがDocker環境にできたことになりまし、[ETHEREUM PET SHOP -- YOUR FIRST DAPP](https://www.trufflesuite.com/tutorials/pet-shop)のWriting the smart contract を始められる環境になったことになります。

いったんここで終了し、次の記事で、スマートコントラクトを作成していきます。