🌟

「SolidityとEthereumによる実践スマートコントラクト開発」を読む-その1-

2022/06/08に公開

web3エンジニアになりたいSIerおじさんのHIRIPONGです。

話題になっているweb3のアプリケーションとしてDAppと呼ばれる分散型アプリケーションがあります。その開発する方法を学んでみたいと思い、オライリーの「SolidityとEthereumによる実践スマートコントラクト開発」を読み進めることにしました。
https://www.oreilly.co.jp/books/9784873119342/

とてもいい本だと思うのですが、ところどころ情報が古くなってきていて、なかなか前に進むことが難しい部分があります。本記事では、この本を読み進めるにあたり、前に進めなくなったときにどうやって回避/解決したかを備忘録的に記述します。

なお、筆者はどちらかというとWindowsの開発畑を歩んできたこともあり、実行環境としてWindowsのWSL(Windows Subsystem for Linux)上でUbuntuと呼ばれるLinuxのディストリビューションを使っています。Macで開発されている方には、あまり参考にならないかもしれません。あらかじめご了承ください。

1回目の今回は、p81にある、Ganacheというソフトでローカル環境でブロックチェーンを立ち上げ、そこに最初のコントラクトと呼ばれるソフトウェアをデプロイ(展開)するところまでをやっていこうと思います。

1章、2章についてはそれぞれ、ブロックチェーンの概念だったり、非中央集権アプリケーションの解説なので、読み進めていくうえで問題になるところはないと思います。ブロックチェーンとは、dAppsとは何ぞやというところが全く分からない方は、これらの章をよんでイメージをつかんでおくと良いと思います。

1.最初の難関

3.1で最初の難関が訪れます。

3.1.1 Parityのインストール で本に記載されているコマンドがさっそく通らない。という事態に遭遇します。色々な方が記事でそのことに触れられていますが、どうやら本書にある以下のコマンドは使えないようです。

bash <(curl https://getparity.io -L)

本書で出てくる最初の作業で躓いてしまうことで、挫折してしまう人も出てしまいそうなのが心配です。実際に私も「あ~、このパターンか…」「この本も使えないのかな…」などとネガティブに考えてしまって、なかなか次に進もうと思えませんでした。メルカリでの出品に回そうかなという考えが頭をよぎりました。

少し救いがあったのは、3.1.1の最後のところに「Parityについては、6章でスマートコントラクトをデプロイするときに改めて取り上げる。」とあったので、少なくとも3章の時点ではインストールできなくても問題がなさそうだと判断ができました。もう少し、このまま進めてみようという気持ちになりました。

Parity はイーサリアムクライアントと呼ばれるアプリケーションの一つで、ブロックチェーンとのやり取りができるようです。イーサリアムクライアントにあたるソフトウェアはParity以外にもいくつか公開されているようなので、必ずしもParityでなくとも良さそうです。このあたりは、6章以降で実際にイーサリアムクライアントが必要になったタイミングで考える、という方向で気楽に考えておいて良さそうです。

インストールが出来なかったことを必要以上に気にすることはありません。

2.MetaMaskのインストール

3.WindowsにUbuntuをインストール

パート3はWindowsで開発を行う人向けになります。UbuntuなどのLinuxディストリビューションを使うためには、従来であればVirtualBoxやVMWareなどの仮想環境をインストールして、その上でLinuxを動かす必要がありました。

Windows 10からはWSL(Windows Subsystems for Linux)という機能を使ってLinuxを使うことができるようです。

かつて、中古パソコンやPCのパーツショップで部品を集めたりして、UbuntuのデータをダウンロードしてCDやDVDなどのメディアを使ってインストールしていた頃からすると隔世の感があります。今回はこのWSLを使ってUbuntuを使いたいと思います。

以下のサイトなどを参考にして、WSLを使ってLinuxを使えるようにします。
https://www.kkaneko.jp/tools/wsl/wsl2.html

Windows 10がいいのか、Windows 11がいいのかですが、私はこの一連の作業を実施している途中でWindows 10をWindows 11にアップグレードしてみましたが、特に問題は発生しませんでした。このあたりは、どちらを使いたいか個人の好みもあると思いますので、好きなほうを使えばよいと思います。

Ubuntuのバージョンですが、私はなれているほうのUbuntu-18.04LTSを使用しましたが、Ubuntu-20.04LTSで上手く動作させておられるかたもネット上には散見されますので、これもどちらでも良さそうです。

3.1 Windows 10 を使う場合は,Windows 10 の更新

Windows 10 を使う場合には,Windows 10 May 2021 Update 以上に更新する必要があるそうです。自動で更新されない場合は、 次のサイトを利用できます。

https://www.microsoft.com/en-us/software-download/windows10

更新による不具合の可能性がありますので、 大事なデータのバックアップを取っておくことや、リカバリメディアを更新するなど、個々人で取れる対策をお願いします。

3.2 WindowsにおいてLinux用のサブシステムを有効にして使えるようにする。

「Windows の機能の有効化または無効化」で,
「Hyper-V」にチェックする.(すでにチェックされている場合には,何も行わなくて良い)⇒私の環境にはこの「Hyper-V」のチェック項目がなかったので、これはパスしました。

「Linux 用 Windows サブシステム」と 「仮想マシンプラットフォーム」にもチェックし, 「OK」をクリック.

※ なお,「Linux 用 Windows サブシステム」がないというときは, 「Windows Subsystem for Linux」と 「仮想マシンプラットフォーム」にもチェックし, 「OK」をクリックするとのこと。私の環境では、「Linux用Windows サブシステム」くらいしかチェックする項目がなかったので、これをチェックしました。最後に画面の指示により、Windows を再起動します。

★Windows 10 での 「Windows の機能の有効化または無効化」の表示法
Windows のメニューで「設定」を選ぶ
「アプリ」

下の方へスクロールし,「プログラムと機能」

「Windows の機能の有効化または無効化」を選ぶ.

コントールパネルに慣れている場合は,コントールパネルで,「プログラム」,「プログラムと機能」,「Windows の機能の有効化と無効化」という操作でもよいと思います。
Windows の検索機能で「Windows の機能の有効化または無効化」と検索をかけるのも良いでしょう。

3.3 WSLの有効化

①Windows Terminal あるいはPowerShellを、管理者として実行します。
②Windows Subsubsystem for Linux を有効化する
https://docs.microsoft.com/en-us/windows/wsl/install-win10
に記載の手順による

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

③仮想マシンプラットフォームのオプションコンポーネントを有効化する
https://docs.microsoft.com/en-us/windows/wsl/install-win10
に記載の手順による

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

④WSL の既定(デフォルト)のバージョンを 2 に設定する
https://docs.microsoft.com/en-us/windows/wsl/install-win10
に記載の手順による

wsl --set-default-version 2

※ このとき「 WSL2 requires an update to its kernel component. For information please visit https://aka.ms/wsl2kernel」 のようなメッセージが表示されることがあります。その場合は、表示の指示に従い、
https://aka.ms/wsl2kernel
から、Linux カーネル更新プログラムパッケージをダウンロードし、インストールします。

上記の例では、「https://aka.ms/ws2-install」を参照するようにとなっているので、「Windows の機能の有効化と無効化」の項目で「仮想マシン プラットフォーム」が有効になっているかチェックします。

3.4 Windows 11の場合の操作

Windows Terminal あるいはコマンドプロンプトを管理者として実行。次のコマンドで一覧を得る.
wsl --list --online
[image]
次のコマンドで Ubuntu-18.04 をインストールできる.
Windows Terminal やコマンドプロンプトを管理者として実行していたときは、WSLg, WSL update が自動でインストールされる.

wsl --install -d Ubuntu-18.04
アンインストールは次のような操作になります。
wsl --shutdown
wsl --unregister Ubuntu-18.04

3.5 Windows 10の場合の操作

私の環境では、最初Windows 10で操作をしていたので、こちらの流れに従うことにしました。マイクロソフト・ストアからインストールができるようです。

Ubuntu, OpenSUSE, SUSE Linux Enterprse Server, Lali Linux, Debian GNU/Linux から選ぶことができますが、今回はUbuntu-18.04を選択することにしました。

Windows で,コマンドプロンプトを実行.
マイクロソフト・ストアを開く.
start ms-windows-store:
検索窓で「Ubuntu」と入れる

Linux ディストリビューションを選ぶ.
Ubuntu 20.04 を使いたいとき:「Ubuntu 20.04 LTS」を選ぶ.
Ubuntu 18.04 を使いたいとき:「Ubuntu 18.04 LTS」を選ぶ.
最新版の Ubuntu を使いたいとき:「Ubuntu」を選ぶ.
※ 「Ubunt 20.04 LTS」を選んだとして説明を続ける.

「入手」をクリック
「入手」が表示されていなくて, 「インストール」が表示されているというときは, 「インストール」をクリック.インストールが始まる.

「この製品はインストール済みです」と表示されたら, インストールが終了している. 確認のため,この画面の「起動」をクリック.

新しい画面が現れる. Linux ディストリビューションの初期化が始まる. しばらく待つ.
以下のようにエラーが出てうまく立ち上がらないときがあります。

どうやら、WSL2で起動するためには足りないパッケージなどがあるようです。以下のサイトを参考にしてUbuntuの足りないパッケージをダウンロードします。
https://docs.microsoft.com/ja-jp/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package
ダウンロードしたインストーラーを起動すると、以下のような画面が出てくる。

「Next」をクリック。インストールは一瞬で終わる。「Finish」で終了する。
この状態で、Ubuntuを起動しようとすると、エラーなどは特に出力されずインストールが始まります。

ユーザー名、パスワードなどを入れるとUbuntuが起動します。

3.6 WSLのバージョンを2にするところは余裕を持とう

Ubuntuのインストールにおいて、不具合が出て前に進めなくなった箇所としては、WSLのバージョンを1から2に変更するところである。バージョン2にするコマンド「wsl --set-default-version 2」を実行していたつもりではあったが、以下のコマンドを打ったところ、WSLがバージョン1で実行されていました。

wsl -l -v

Ubuntuのインストール時点ではWSLのバージョンは1のままでも問題はないようなのですが、あとあとの作業でバージョン2に変更しておかないとうまくいかないところが出てくるようです。なので、早めにバージョン2に変更しておくことをおススメします。

ただし、WSL上で動作するUbuntuの容量が大きいことが影響しているためか、Ubuntuをインストールしている状態だと、バージョン1からバージョン2に移行するタイミングでハードディスク(WindowsのC:ドライブ)に30GB程度の余裕が必要みたいです。ハードディスクに余裕がない状態でバージョン2への移行を始めてしまうと、途中で処理が止まってしまううえに、C:ドライブの空き容量がほぼ0になってしまうという事態が発生します。

私はこれが発生してしまったので、「Windows の機能の有効化または無効化」の項目で「Linux 用 Windows サブシステム」を一旦無効にし、再起動を行うことでWSLが動いていない状態にしておくことでDiskの空き容量を確保し、使っていないアプリやデータを消去することで対応しました。

また、たとえ容量に余裕があったとしても、コマンド

wsl --set-default-version 2

の完了までは、相当な時間がかかる場合があるため、昼寝をするとか、コーヒーを飲むなどして気持ちに余裕を持つことをおススメします。

4.Node.jsのインストール、Truffleをインストール、Ganacheのインストール

ここからはテキストに従って、Node.js、Truffle、Ganacheのインストールを行っていただければと思います。少し混乱するかもしれませんが、Node.jsやTruffleのインストールはUbuntu上で行い、GanacheのインストールはWindows上で行う作業となります。

Truffleのバージョンですが、テキスト通り5.1.31をインストールしてしまうと、後のテストでうまく行かないことがあるみたいなので、ここはうまくいっている人のバージョンを利用するとして、5.4.16あたりを使うことにします。私は以下のページを参考にしました。
https://zenn.dev/mizuneko4345/scraps/b3d34f0505a63a

npm install -g truffle@5.4.16

上記のコマンドに変換するなどしてインストールしてみてください。

5.始めてのスマートコントラクトの開発

第4章については、基本的にテキスト通りにやっていけばおおよそその通りにできるのはないかと思います。ここでは、コントラクトを編集する上で、必要になってくるであろうviの簡単な使い方についてと、Windows側のサンプルコードをUbuntu側にもっていく方法について記述します。

5.1 viの世界一簡単な(すぼらな?)基礎

「vi」とは、Linux環境にてはファイルを編集するときに使うエディタです。WSLではGUIとは違って、基本的にコマンドラインをキーボードで操作することによってOSの設定を変更したり、プログラムを書いたりするCUIとなっています。Windowsのようにマウスを使ってクリックして編集したりはできないので、キーボードでの操作にある程度慣れる必要があります。

Ubuntuのコマンドライン上で、

vi test.txt

のように「vi」のあとに編集したいファイル名を入れて「Enter」キーを押すとvi上でtest.txtなどのテキストファイルが展開されます。例えば、p53にて「続いて、リスト4-1に示すコードを追加する。」とさらっとテキストファイルを編集するように書かれていますが、この例だと

vi test/greeter-test.js

というコマンドにて、viで「greeter-test.js」というファイルを開くことができます。viは起動時にはコマンドモードになっているため、メモ帳のようにそのままでは編集できません。「i」ボタンを押すと下のところが-INSERT-という表示になり、文字の追加や削除が可能になります(編集モード)。この状態で文字の追加や削除を行って編集してください。
 保存して抜けるときには、一旦「Esc」キーでコマンドモードに戻る必要があります。コマンドモードに戻ったら「:」⇒「w」⇒「q」の順に押下して「enter」でviを終了してください。「w」はWirte、「q」はQuitの頭文字を表しているので、「書き込んで終了する」という意味になります。保存せずに終了するときは「:」⇒「q」⇒「!」の順に入力して決定してください。これでファイルは更新されないまま、viを終了することができます。

基本的にこれさえ覚えておけば、あとはメモ帳と同じようにキーボード操作ができると思います。私は覚えるのが苦手なので、必要になったタイミングでコマンドを覚えて(例えばコピー&ペースト)、その都度使いこなせるようにして徐々にレベルアップを図っています。皆様も自分に合った方法で、「vi」の操作をマスターしていただければ幸いです。

5.2 WindowsのテキストをUbuntu側にコピー(コマンドライン、viなど)

テキストを進めていくうえで、先に実施した人のコードを使わせてもらいたいこともあるかど思います。そのとき、WindowsでコピーしたテキストファイルをUbuntu側で使うケースがあるかと思います。私の環境ではWindowsでコピーしたテキストファイルがUbuntu上で「Ctrl」 + 「V」としてペーストできないので、代わりに右クリックをしてペーストしています。

6.コントラクトのデプロイと操作

5章のコントラクトのデプロイと操作のところについては、Parityがインストールできなったため、Ganacheにデプロイする方法だけやってみます。その他の方法については未検証です。p75のところで以下を実行しています。コード自体はGitHubに公開されているので、ダウントードします。

command
# you are in root dir of greeter project
cd ..
git clone https://github.com/RedSquirrelTech/hoscdev
cp -r hoscdev/chapter-5/greeter/client/ greeter/client

truffle-config.jsファイルを以下のように編集します。solc(Solidityのコンパイラ)のバージョンについては、個別で設定すべきところかと思います。

truffle-config.js
module.exports = {
  contracts_build_directory: "./client/src/contracts",
  networks: {},
  mocha: {},
  compilers: {
    solc: {
      version: "0.5.16", // Fetch exact version from solc-bin (default: truffle's version)
    },
  },
};

下記コマンドにて、UIを起動します。

command
# you are in root dir of greeter project
truffle compile
cd client
npm i
npm run start

テキストにも書かれていますが、ここはエラーが出ても良いようです。

Ganacheを起動

ここで、WSLをバージョン1のままで運用しているとWSL用に割り当てられたネットワークが見つからない可能性があります。その場合は、WSLをバージョン2に変更してください。

ここで、(WSL)の表記があるネットワークを選択して、このときのIPアドレスを控えておいてください。metamaskを接続するときに、リカバリーフレーズを使います。

入力するリカバリフレーズは、Ganacheに表示されているリカバリフレーズです。

カスタムのネットワークとして以下を参考にしてネットワークに接続してください。

ここで苦労したのですが、Chain IDに「1337」を入れようとすると、「Localhost 8545によって使用されている」というようなエラーが出てしまい、ネットワークに接続できませんでした。metamaskのテストネットの中に「Localhost 8545」というものがあり、それによってChain ID:1337が使われてしまっているようです。metamaskから「Localhost8545」をいったん削除することにしました。

接続が完了したら、CPAYというトークンのバランスが表示されます。

hostのIPアドレスはGanacheの設定画面に表示されていたものを使います。

truffle-config.js
module.exports = {
  contracts_build_directory: "./client/src/contracts",
  networks: {
    development: {
      host: "192.168.80.1",
      port: 7545,
      network_id: "*",
    },
  },
  mocha: {},
  compilers: {
    solc: {
      version: "0.5.16", // Fetch exact version from solc-bin (default: truffle's version)
    },
  },
};

Deploy to Dev Network

# in project root folder
truffle migrate --network development
# Compiling your contracts...
# ===========================
# ...
# Summary
# =======
# > Total deployments:   2
# > Final cost:          0.01683276 ETH

Launch web server.

# in project root folder
cd client
npm run start

metamaskが起動されるのでアカウントを選ぶ。

「接続」をクリックする。

DAppの画面が表示される。

・metamaskにおけるテストネットの表示と削除
・Localhost 8545エラーの出現

・参考になったページ
https://www.kkaneko.jp/tools/wsl/wsl2.html
https://zenn.dev/mizuneko4345/scraps/b3d34f0505a63a
https://qiita.com/daei/items/84c55dbe03ebb81da162

Discussion