「SolidityとEthereumによる実践スマートコントラクト開発」をDocker環境で試したい。

「SolidityとEthereumによる実践スマートコントラクト開発」という本を読んで、Ethereumをちょっと始めようかなと思った。
ただ、自分のPCに環境を準備するのが大変そうだったので、Dockerを使って試したい。
ということで、

Dockerで構築するEthereum PET-SHOP TRUFFLE BOXES(その1)(Qiita)
ganache-cliを利用して、docker内にローカルネットを立ち上げてみる(BEFOOL Blog)

を参考に、Docker上でganache+truffleの環境を、まずは作ってみる。
ただそれだけなのに、エラーがガンガン出てくる。「非推奨」の警告も大量に出てくるし。
たった1年半前の記事ですらこれって、足早すぎる。

なお、最終的なソースファイルは一番最後(というか「次ページ」)。途中に出てくるのは後からどんどん修正入ります。

ということで、2つのサイトからDockerfileとdocker-compose.ymlを真似て作る。
フォルダ構造は以下の通り。

【ROOT_FOLDER】(フォルダ)
+--docker-compose.yml(ファイル)
+--trufflebox(フォルダ)
   +--Dockerfile(ファイル)
+--ganache-cli(フォルダ)
   +--ganache-data(空のフォルダ)
   +--Dockerfile(ファイル)
  • 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"
        depends_on: 
          - ganache
      ganache:
        build:
          context: ./ganache-cli
          dockerfile: Dockerfile
        volumes:
          - ./ganache-cli/ganache-data:/var/ganache
    
  • trufflebox/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
    
  • ganache-cli/Dockerfile
    FROM node:8-alpine
     
    RUN npm install -g ganache-cli
    RUN mkdir -p /var/ganache
     
    ENV DOCKER true
    ENV DATADIR /var/ganache
    # データを永続化する場合、次回以降も同じmnemonicとnetworkIdで立ち上げる必要性があります
    # https://github.com/trufflesuite/ganache-cli/issues/407
    ENV MNEMONIC pillows andymori al tomoyuki spitz abc quruli whoops fukurouz air bluehearts highlows
    ENV NETWORKID 5777
     
    EXPOSE 8545
     
    ENTRYPOINT ["sh", "-c", "ganache-cli --host=0.0.0.0 --db=${DATADIR} --mnemonic=\"${MNEMONIC}\" --networkId=${NETWORKID}"]
    

そして、ビルド。

> docker-compose build
Building ganache
Sending build context to Docker daemon  3.072kB
Step 1/9 : FROM node:8-alpine
 ---> 2b8fcdc6230a
Step 2/9 : RUN npm install -g ganache-cli
 ---> Running in 925e6ed2a330
・・・
Successfully tagged 【フォルダ名】:latest
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

よし、ganacheは上手くビルド出来た模様。
引き続きtruffle。

Building truffle
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM node:8-alpine
 ---> 2b8fcdc6230a
Step 2/4 : RUN apk add --update alpine-sdk
・・・
Removing intermediate container bf360adf1b5b
 ---> 9da50d09ba03
Step 3/4 : RUN apk add --no-cache git python g++ make     && npm i -g --unsafe-perm=true --allow-root truffle
・・・
(8/8) Installing python2 (2.7.18-r0)
Executing busybox-1.31.1-r8.trigger
OK: 238 MiB in 61 packages
npm WARN deprecated graphql-tools@6.2.6: This package has been deprecated and now it only exports makeExecutableSchema.\nAnd it will no longer receive updates.\nWe recommend you to migrate to scoped packages such as @graphql-tools/schema, @graphql-tools/utils and etc.\nCheck out https://www.graphql-tools.com to learn what package you should use instead

何かnpmが警告を大量に出してきている。古いバージョンを指定してるのかな?
続く。

・・・
make: Entering directory '/usr/local/lib/node_modules/truffle/node_modules/tiny-secp256k1/build'
・・・
/root/.cache/node-gyp/8.17.0/include/node/v8.h: In static member function 'static void v8::V8::SetAllowCodeGenerationFromStringsCallback(v8::DeprecatedAllowCodeGenerationFromStringsCallback)':
/root/.cache/node-gyp/8.17.0/include/node/v8.h:10304:19: warning: cast between incompatible function types from 'v8::DeprecatedAllowCodeGenerationFromStringsCallback' {aka 'bool (*)(v8::Local)'} to 'v8::FreshNewAllowCodeGenerationFromStringsCallback' {aka 'bool (*)(v8::Local, v8::Local)'} [-Wcast-function-type]
10304 |           callback));
      |                   ^
・・・

何か、makeでも警告が出ている。続く。

・・・
> truffle@5.4.6 postinstall /usr/local/lib/node_modules/truffle
> node ./scripts/postinstall.js

/usr/local/lib/node_modules/truffle/build/724.bundled.js:11740
  } catch {
          ^

SyntaxError: Unexpected token {
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:617:28)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at Object.__webpack_require__.f.require (/usr/local/lib/node_modules/truffle/build/cli.bundled.js:625:28)
Error: Error while attempting to download and cache solc 0.5.16: Command failed: node ./build/cli.bundled.js obtain --solc=0.5.16
/usr/local/lib/node_modules/truffle/build/724.bundled.js:11740
  } catch {
・・・

エラー出た。

Successfully tagged 【フォルダ名】:latest
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

見た目は成功っぽいけど、途中でエラーが出ている。実際動かそうとしても動かない。
エラー文「SyntaxError: Unexpected token at createScript (vm.js:80:10)」で検索してみると、どうも、nodeのV8が古くてサポートされていないらしい。Dockerfileの「FROM noge:8-alpine」の「8-」の部分でバージョンが指定されているので、外してbuildし直す。

> docker-compose build
・・・
(ganache側は成功)
・・・
Building truffle
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM node:alpine
 ---> dd7ce8038c96
Step 2/4 : RUN apk add --update alpine-sdk
・・・
Step 3/4 : RUN apk add --no-cache git python g++ make     && npm i -g --unsafe-perm=true --allow-root truffle
 ---> Running in 18e506e0b519
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/community/x86_64/APKINDEX.tar.gz
ERROR: unable to select packages:
  python (no such package):
    required by: world
The command '/bin/sh -c apk add --no-cache git python g++ make     && npm i -g --unsafe-perm=true --allow-root truffle' returned a non-zero code: 1
ERROR: Service 'truffle' failed to build : Build failed

エラーで止まった。「unable to select packages: python (no such package):」で検索して、「python」を「python3 py3-pip」にしてみる。

> docker-compose build
・・・
(ganache側は成功)
・・・
Building truffle
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM node:alpine
 ---> dd7ce8038c96
Step 2/4 : RUN apk add --update alpine-sdk
 ---> Using cache
 ---> e582b467c4d0
Step 3/4 : RUN apk add --no-cache git python3 py3-pip g++ make     && npm i -g --unsafe-perm=true --allow-root truffle
 ---> Running in c18c97b36d80
・・・
Step 4/4 : WORKDIR /usr/src/app
 ---> Running in 883a78855d01
・・・
Successfully tagged 【フォルダ名】:latest
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

お、出来た。
ということで、出来たファイルは以下。

【ROOT_FOLDER】(フォルダ)
+--docker-compose.yml(ファイル)
+--trufflebox(フォルダ)
   +--Dockerfile(ファイル)
+--ganache-cli(フォルダ)
   +--ganache-data(空のフォルダ)
   +--Dockerfile(ファイル)
  • 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"
        depends_on: 
          - ganache
      ganache:
        build:
          context: ./ganache-cli
          dockerfile: Dockerfile
        volumes:
          - ./ganache-cli/ganache-data:/var/ganache
    
  • trufflebox/Dockerfile
    FROM node:alpine  
    
    RUN apk add --update alpine-sdk
    RUN apk add --no-cache git python3 py3-pip g++ make \
        && npm i -g --unsafe-perm=true --allow-root truffle 
    
    WORKDIR /usr/src/app
    
  • ganache-cli/Dockerfile
    FROM node:alpine
     
    RUN npm install -g ganache-cli
    RUN mkdir -p /var/ganache
     
    ENV DOCKER true
    ENV DATADIR /var/ganache
    # データを永続化する場合、次回以降も同じmnemonicとnetworkIdで立ち上げる必要性があります
    # https://github.com/trufflesuite/ganache-cli/issues/407
    ENV MNEMONIC pillows andymori al tomoyuki spitz abc quruli whoops fukurouz air bluehearts highlows
    ENV NETWORKID 5777
     
    EXPOSE 8545
     
    ENTRYPOINT ["sh", "-c", "ganache-cli --host=0.0.0.0 --db=${DATADIR} --mnemonic=\"${MNEMONIC}\" --networkId=${NETWORKID}"]
    

では引き続き、
Dockerで構築するEthereum PET-SHOP TRUFFLE BOXES(その1)(Qiita)
に沿って進める。

> docker-compose run truffle truffle unbox pet-shop
Creating network "【フォルダ名】" with the default driver
Creating petshop_truffle_boxes_ganache_1 ... done
Creating petshop_truffle_boxes_truffle_run ... done
This directory is non-empty...
? Proceed anyway? (Y/n) 
Starting unbox...
=================

ここで、実は入力待ちになっている。「y」を入力してEnter。

? Proceed anyway? Yes
? Preparing to download box
? Downloading
npm WARN old lockfile 
npm WARN old lockfile The package-lock.json file was created with an old version of npm,
npm WARN old lockfile so supplemental metadata must be fetched from the registry.
npm WARN old lockfile
npm WARN old lockfile This is a one-time fix-up, please be patient...
npm WARN old lockfile
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated mixin-deep@1.3.1: Critical bug fixed in v2.0.1, please upgrade to the latest version.
npm WARN deprecated set-value@0.4.3: Critical bug fixed in v3.0.1, please upgrade to the latest version.
npm WARN deprecated set-value@2.0.0: Critical bug fixed in v3.0.1, please upgrade to the latest version.
npm WARN deprecated chokidar@2.0.4: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.
npm WARN deprecated axios@0.17.1: Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410
? 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

成功したっぽい。次はmigrate。でもその前に、設定の修正とganacheの起動。
truffleboxフォルダの下に、petshopアプリ用のファイルが入っている。

【ROOT_FOLDER】(フォルダ)
+--docker-compose.yml(ファイル)
+--trufflebox(フォルダ)
   +--Dockerfile(ファイル)
   +--truffle-config.js(ファイル)←これを修正する。
   +--(その他ファイル・フォルダ)
+--ganache-cli(フォルダ)
   +--ganache-data(空のフォルダ)
   +--Dockerfile(ファイル)
  • trufflebox/truffle-config.js
    module.exports = {
      // See 
      // for more about customizing your Truffle configuration!
      networks: {
        development: {
          host: "ganache",//ここを127.0.0.1から変更。
          port: 8545, // ポート番号を7545から8545に変更。
          network_id: "*" // Match any network id
        } //この下にあったdevelopの部分を削除。
      }
    };
    

で、ganacheを起動。

> docker-compose up -d
Creating network "【フォルダ名】_default" with the default driver
Creating 【フォルダ名】_ganache_1 ... done
Creating 【フォルダ名】_truffle_1 ... done
> docker-compose ps
             Name                            Command               State     Ports
------------------------------------------------------------------------------------
【フォルダ名】_ganache_1   sh -c ganache-cli --host=0 ...   Up       8545/tcp
【フォルダ名】_truffle_1   docker-entrypoint.sh sh -c ...   Exit 2

truffleの方が起動しない。途中だからか?
次にmigrateを実行してみる。

> docker-compose run truffle truffle migrate
Creating 【フォルダ名】_truffle_run ... done

Compiling your contracts...
===========================
> Compiling ./contracts/Migrations.sol
> Artifacts written to /usr/src/app/build/contracts
> Compiled successfully using:
   - solc: 0.5.16+commit.9c3226ce.Emscripten.clang



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


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

   Deploying 'Migrations'
   ----------------------
   > transaction hash:    0x6df0a5a11e36f3e0c7c9ee43fb00aa174cb215e4d72c3d3922ccc48137809df6
   > Blocks: 0            Seconds: 0
   > contract address:    0x808253c9562A2919a2d4cd362F11a1ffA7998531
   > block number:        1
   > block timestamp:     1629030731
   > account:             0xF69Fc8A0AA6b2d0f3baFA7d40ee501a788B0d65E
   > balance:             99.99616114
   > gas used:            191943 (0x2edc7)
   > gas price:           20 gwei
   > value sent:          0 ETH
   > total cost:          0.00383886 ETH


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


Summary
=======
> Total deployments:   1
> Final cost:          0.00383886 ETH



上手くいった?良く分からん。次は起動。
と思ったら、元記事の方でdocker-compose.ymlの修正が必要と判明。
ということで、元記事に書いてあった修正を実施。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"

では起動。

> docker-compose up -d
【フォルダ名】_ganache_1 is up-to-date
Recreating 【フォルダ名】_truffle_1 ... done
PS D:\src\ethereum_dev\PETSHOP_TRUFFLE_BOXES> docker-compose ps
             Name                            Command               State                    Ports
-------------------------------------------------------------------------------------------------------------------
【フォルダ名】_ganache_1   sh -c ganache-cli --host=0 ...   Up      8545/tcp
【フォルダ名】_truffle_1   docker-entrypoint.sh sh -c ...   Up      0.0.0.0:8003->3000/tcp,:::8003->3000/tcp

これで、http://localhost:8003にアクセス。
→ 上手くいった。Pete’s Pet Shopにアクセスできた。

※ちなみに【フォルダ名】は、docker-composeした時にデフォルトで付くtag。

タイトルとURLをコピーしました