1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Solidity Hot Reloading Using ZepKit

Last updated at Posted at 2019-05-18

Solidityホットリロード

ある日の朝、社内掲示板にて。

 社長「キター!」
 俺「?」

…という事で何がキタのか調べるべく「Solidity Hot Reloading Using ZepKit」の記事内容を試してみました。

Hot Reloading って何?

どうやらようやくsolidity界隈にも Hot Reloading 機能が実装されたようです。

ホットリロードとは「ファイルの変更をトリガにリアルタイムで変更を反映してくれる」機能の事です。
こちらからの引用)

この記事のGIF画像が分かり易いです ↓
hoge
  ※右のソースコードを書き換える → 左のブラウザ画面が自動的に更新される → 便利!

Solidityのホットリロードって何?

では、Solidityのホットリロードとは何なのでしょうか。

"引用"
Hot Reloading watches the .sol files you’re using. Once there’s a change, it compiles them, updates the local blockchain using ZeppelinOS, and refreshes your app in the browser while preserving your blockchain state.
(ホットリロードは、使用している.solファイルを監視します。 変更があると、それらをコンパイルし、ZeppelinOSを使用してローカルブロックチェーンを更新し、ブロックチェーンの状態を維持しながらブラウザでアプリケーションを更新します。)

じゃあ、ホットリロードを使って何が嬉しいのでしょうか?

"引用"
Avoiding endless cycles of building and reloading your project whenever you make a change saves time and focus.
(変更を加えるたびにプロジェクトを構築して再ロードするという無限のサイクルを回避することで、時間と集中力を節約できます。)

これって大切ですね。
チームで開発していると、意外とこういったルーチンワークが、生産性向上を阻害するボトルネックになっていたりするものだと思います。

″引用”
Yet in the world of blockchain development, we’re 10 years behind.
ブロックチェーン開発の世界では、10年遅れています。

Solidity Hot Reloading を使えば、10年の遅れを巻き返す事が出来るのか。
さっそく見て行きましょう。

​​How to start?

「Solidity Hot Reloading Using ZepKit」の真ん中あたりからチュートリアルは始まります。
ここでは、分かり辛い部分に補足を加えて解説していきたいと思います。

なお今回は、Windows10 node.js 環境、Windows Power Shell + Chrome + MetaMask で動作を確認しました。

Install requirements

まず、必要なnpmパッケージをインストールします。

コマンド
npm install --g zos@2.2.0 ganache-cli@6.3.0 truffle@5.0.2

 zos … ZeppelinOS Command-Line Interface. Hot Reloadingで必要です。
 ganache-cli … このチュートリアルは、ganache-cli をテストネットとして使います。
 truffle … unboxに必要なだけ(おそらく)。

Unbox Zepkit

truffleのunboxコマンドを使い、zepkitをクローンします。
なお、unbox するといきなりファイル・フォルダが展開されるので、作業用フォルダを作成してから行いましょう。

コマンド
mkdir zepkittest
cd zepkittest

truffle unbox zeppelinos/zepkit

Run the local blockchain

ganache-cliを起動します。
コンソールをもう一つ開いて、コマンドを実行します。

コマンド
ganache-cli --secure -u 0 -u 1 -u 2 -d
実行結果
PS C:\Users\tobisako> ganache-cli --secure -u 0 -u 1 -u 2 -d
Ganache CLI v6.3.0 (ganache-core: 2.4.0)

Available Accounts
==================
(0) 0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1 (~100 ETH)
(1) 0xffcf8fdee72ac11b5c542428b35eef5769c409f0 (~100 ETH)
(2) 0x22d491bde2303f2f43325b2108d26f1eaba1e32b (~100 ETH)
(3) 0xe11ba2b4d45eaed5996cd0823791e0c93114882d (~100 ETH) 🔒
(4) 0xd03ea8624c8c5987235048901fb614fdca89b117 (~100 ETH) 🔒
(5) 0x95ced938f7991cd0dfcb48f0a06a40fa1af46ebc (~100 ETH) 🔒
(6) 0x3e5e9111ae8eb78fe1cc3bb8915d5d461f3ef9a9 (~100 ETH) 🔒
(7) 0x28a8746e75304c0780e011bed21c72cd78cd535e (~100 ETH) 🔒
(8) 0xaca94ef8bd5ffee41947b4585a84bda5a3d3da6e (~100 ETH) 🔒
(9) 0x1df62f291b2e969fb0849d99d9ce41e2f137006e (~100 ETH) 🔒
  :

「--secure」オプションは、
ganache-cliが用意するテストアカウント(全て)をロック状態にします。
(※このチュートリアルでは不要かもです。)

「-u」オプションは、
逆に指定アカウントをアンロック状態にします。
「-u 0 -u 1 -u 2」と書く事で、アカウント「(0)」「(1)」「(2)」がアンロックされます。
(実行結果では、(0)・(1)・(2)に鍵アイコンが無くアンロックされている事が分かります。)
このチュートリアルでは、後述の「zos session」で、アカウント「(2)」がアンロックされている必要があります(※このチュートリアルでは3つもアンロックしなくても…です)。

「-d」オプションは、
ganache-cliが用意するテストアカウントを生成する際のニーモニック(MNEMONIC)を指定するものです。
 1・指定無しの場合は、ganache-cli起動毎にテストアカウントのアドレスが変わります(不便かもです)。
 2・「-d」のみ指定すると、常に同じテストアカウントが生成されます。
 3・「-d -db [PATH]」と指定する事で、ニーモニックをファイル指定する事も出来る様です。

上記「2」で生成されるテストアカウントのアドレスは、別環境でも常に同じです。
(Windows10 と Ubuntu(Cloud9) で試したが同じだった)
このチュートリアルでは、後述の「zos session」でアカウント「(2)」のアドレスが直指定されており、
ここで「-d」を指定する事で整合性が取れています。(なんだかアクロバティックですね)

※ganache-cliのコマンドライン引数の解説はgithubで確認して下さい。
※ニーモニックについては、HD Walletでググッって見てください。

Initialize the ZeppelinOS project

「truffle unbox zeppelinos/zepkit」で取得したチュートリアル・サンプルソースを設定していきましょう。

コマンド
zos init zepkit

すると、ファイル zos.json が生成されます。

zos.json
{
  "zosversion": "2.2",
  "name": "zepkit",
  "version": "0.1.0",
  "contracts": {}
}

Add the Counter contract to your project

Hot Reloading で監視するコントラクトを設定します。

コマンド
zos add Counter

 すると、下記の様に soliddity ソースファイルがコンパイルされ、zos.json が更新されます。
 con03.png

ファイル zos.json の "contracts" に、 Counter が書き加えられました。

zos.json
{
  "zosversion": "2.2",
  "name": "zepkit",
  "version": "0.1.0",
  "contracts": {
    "Counter": "Counter"
  }
}

Connect with your local blockchain by opening a session

次に、Hot Reloading で使用するセッション管理情報を保存します。

zos session --network development --from 0x22d491bde2303f2f43325b2108d26f1eaba1e32b --expires 3600

すると、ファイル .zos.session が生成されます。

.zos.session
{
  "network": "development",
  "from": "0x22d491bde2303f2f43325b2108d26f1eaba1e32b",
  "expires": "2019-05-18T15:32:43.175Z"
}

Let’s compile the Counter contract

まだまだ準備は続きます。以下のコマンドを実行し、セッション情報をブロックチェーンにプッシュします。

コマンド
zos push --deploy-dependencies

このコマンドを実行したら、ganache-cli の表示にも注目しましょう。

・zosコマンド画面
con04_zof.png
・ganache-cli画面
con04_ganache-cli.png

We create an instance of our contract and deploy it

次のコマンドで、ようやくコントラクトがデプロイされインスタンスが生成されます。

コマンド
zos create Counter --init initialize --args 2

 ※「--args 2」を指定する事で、Counter.solのコンストラクタに引数 2 を渡しています。

Open another terminal in the client folder and run

このチュートリアルでは、MetaMask を ganache-cli に接続して使用するので、まず先に MetaMask のネットワークを「Localhost 8545」に切り替えます。
meta01.png

次に、クライアントweb画面を起動します。
チュートリアルでは別Windowsを開くと書いていますが、ここではそのままコマンドを実行します。

「truffle unbox zeppelinos/zepkit」で取得したフォルダ「client」にパスを移動して、コマンドを実行します。

コマンド
cd client
npm run start

するとブラウザが起動し、暫くするとweb画面が表示されます。
(コンパイル後に表示されるので、少し時間がかかります)
meta_06.png

このタイミングで MetaMask の確認画面が出てくるので、「Connect]ボタンを押して許可しておきましょう。
meta_07.png

では、web画面を確認したら、そっと閉じて次のURLを開きましょう。
http://localhost:3000/counter

こっちが目的のweb画面です。
web_02.png

さて、ホットリロードを確認する前に、以下をチェックしておきましょう。
web_02_b.png
  「Increase Counter by 1」ボタンはアクティブですが、
  「Decrease Counter by 1」ボタンは非アクティブで押せない状態になっています。

ここで使用されているSolidityファイルの覗いてみましょう。

contracts/Counter.sol(修正前)
    :
contract Counter is Initializable {
    :

  //and it can add to a count
  function increaseCounter(uint256 amount) public {
    count = count + amount;
  }

  //We'll upgrade the contract with this function after deploying it
  //Function to decrease the counter
  // function decreaseCounter(uint256 amount) public returns (bool) {
  //   require(count > amount, "Cannot be lower than 0");
  //   count = count - amount;
  //   return true;
  // }
}

※関数「increaseCounter()」と「decreaseCounter()」がありますが、後者はコメントアウトされています。

次に、webクライアント側のソースファイル index.js を覗いてみましょう。

client/src/index.js
    :
        <div className={styles.buttons}>
          <Button
            onClick={() => this.props.increase(1)}
            size="small">Increase Counter by 1</Button>
          <Button
            onClick={() => this.props.decrease(1)}
            disabled={!contract.methods.decreaseCounter} size="small">Decrease Counter by 1</Button>
        </div>
    :

※「disabled={!contract.methods.decreaseCounter}」で、コンパイルされたSolidityソースにメソッド「decreaseCounter()」が含まれているかを確認し、ボタンのアクティブ・非アクティブを切り替えている事がわかります。

今回のお題は「ホット・リローディング」ですので、
Counter.sol の関数「decreaseCounter()」コメントを外し有効にして、ファイルを保存する事で自動的にホット・リロードすれば成功、という事になります。

それでは、やってみましょう。

下記の様に、「Counter.sol」の関数「decreaseCounter()」のコメントを外します。

contracts/Counter.sol(修正後)
    :
contract Counter is Initializable {
    :

  //and it can add to a count
  function increaseCounter(uint256 amount) public {
    count = count + amount;
  }

  //We'll upgrade the contract with this function after deploying it
  //Function to decrease the counter
  function decreaseCounter(uint256 amount) public returns (bool) {
    require(count > amount, "Cannot be lower than 0");
    count = count - amount;
    return true;
  }
}

ファイルを保存すると、自動的にコンパイルが始まります。
auto_compile.png

そして、内容に変更があった場合のみ、自動的にデプロイが行われます。
(今回は関数「decreaseCounter()」が新たに加わった)
auto_compile_2.png

さらに、web画面も自動的に更新され、
OK.png
  ソースファイルを保存しただけで、
  上記の様に「Decrease Counter by 1」ボタンがアクティブとなり、押せる様になりました。

これで、Solidity の Hot Reloading がうまく動作した事が確認できました。

失敗するケース

サクサクやらないと失敗するかもしれません。以下の点に注意しましょう。
 ・1時間(3600秒)以内に終わらせる。
 ・失敗したら、ganache-cli を一度再起動して、「zos init zepkit」からやり直す。
 ・たまに「zos.json」(およびzos-dev-xxxx.json)を手動で消さないとやり直し出来ない事がある。

せっかくなのでボタンを押してみよう

ここからはチュートリアルには無いオマケです。

ボタンを押すと、コントラクト関数を呼び出して、カウンターを増やしたり減らしたり出来る筈ですが、
関数呼び出しには gas が必要です。

もし ether 残高が足りないと、MetaMask で「残高不足」となってしまいます。
gas_not_enough.png

ganache-cli を使ったテストネットなので、MetaMask で TEST-ether を使う必要があります。
 1・使用している MetaMask に ether を送ってやる
 2・MetaMask にテストアカウントをインポートしてやる

MetaMask にテストアカウントを追加するのはちょっとアレな感じなので、
ここでは「1」の方法で、geth コンソールを起動して、ganache-cliテストネットに接続し、MetaMask のアカウントに ether を送金しましょう。

コマンド
geth attach http://127.0.0.1:8545

ganache-cli に geth コンソールで接続出来たら、下記の送金コマンドを実行します。
(「to:」のアドレスは、自分の MetaMask アカウントに置き換えてください。)

gethコンソール・コマンド
eth.sendTransaction({from:eth.accounts[0],
    to:"0xd7436A5d7AabaDE2cdBA5FA9489Afd15af2E86EA",
    value:1000000000000000000})

  ※ganache-cli は最初から10個のテストアカウントが作成され、それぞれ 100 ether ずつ入っています。
  ※上記コマンドでは、アカウント0番→自分の MetaMask アカウントへ 1 ether を送金しています。

これで準備OKです。

さっそく「Increase Counter by 1」ボタンを押してみましょう。
OK.png

ボタンを押すと、MetaMask のポップアップが表示され、今度はちゃんと押す事が出来ます。「確認」ボタンを押しましょう。
gas_ok.png

 ※初期値「2」から、「3」に更新される事が確認できました。
 count_up.png

感想

コントラクトの自動デプロイは便利でした。ただ、色々触っているとMetaMaskとの連携でエラーが出たり、ganache-cliを停止させると整合性が保てなくなる等、まだまだ使い勝手としては向上の余地があるのかなと思いました。zosの今後の進歩に期待です。

FLOCブロックチェーン大学校

FLOCブロックチェーン大学校・スマートコントラクト開発課は、solidity・truffleを学ぶ事が出来るカリキュラムです。web受講の他に教室受講オプションがあり、講師に直接質問出来て身に付きやすいです。短期集中で ethereum 開発ノウハウを獲得するならおススメです。

ちょっと嬉しいと思った事

5月下旬からの回では、講師・講師補助メンバーとして関わって下さる方々が増えるのですが、
エンジニア同士でカリキュラムの進め方についてあーだこーだ議論出来るのが嬉しいです(*´Д`)
きっと違った目線からより面白いワークショップが生まれるんじゃないかと思うと今から楽しみです。
乞うご期待!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?