Truffle+Vue で DApp 開発入門

以前 geth を使って開発環境作りみたいなことしましたが、Truffle と Ganache を使ってより簡単に DApp を作っていきたいと思います。

スポンサーリンク

今回作ったもの

初めての DApp 開発なのでアイディアを書き込んで参照するだけの簡単な ものを作ってみます。

デモアプリは Heroku で公開しています。Free Dyno なので、最初の接続に時間がかかります。試す際は必ず Ropsten ネットワークに切り替えてください。

GitHub にも上げています。

開発環境

  • macOS High Sierra
  • Truffle: v4.1.14
  • Solidity: v0.4.24
  • Vue: v2.9.6
  • Ganache: v1.2.1

あらかじめ Vue (vue-cli) を入れておきます。macOS に Vue を入れる方法は過去の記事でご確認ください。

Truffle インストール

Truffle を入れるとプロジェクトの管理が楽になります。

Ganache インストール

geth は色々設定することがありますが、Ganache (GUI 版) は起動するとアカウントが最初から用意されていて楽に開発できます。

Ganache ダウンロード

プロジェクトの初期化

Truffle での開発に必要なディレクトリが作られます。

コントラクト

コーディング

Solidity で Ethereum ブロックチェーン上に置くコントラクトのコードを書きます。コーディングに使う言語は他にも Vyper とかあります。

一応コーディング規約もあります。誰でも使えるようなコントラクトならやはり見やすいほうが望ましいと思われるので、命名規則などは統一すべきです。JS ライクなのでだいたい CapsWords か mixedCase です。

コントラクトのコードは contracts ディレクトリに保存します。

Solidity のコーディングで注意すべき点

  • Struct は返せないので、複数の戻り値を使うなどして対応する
  • string の配列も返せない
  • Struct 外で uint32 など変数の使用領域を指定するのは意味がない

Struct の配列を返したかったら基本型の配列を作って返すことで対応できますが、string が含まれる場合は詰みます。その場合は JS 側で片付けましょう。

コンパイル

コンパイルすると build/contracts に JSON ファイルが作られます。

ローカルネットワークへのデプロイ

予め起動した Ganache にデプロイします。

設定

truffle init した状態では白紙になっている truffle.js に設定を書き込みます。

development というネットワークの環境を設定します。ホストとポートは Ganache のものを書き込みます。network_id はワイルドカードになっています。

127.0.0.1 の代わりに localhost で設定すると何らかの問題が起きる的なことをどこかで見た気がするので、前者で書いています。

マイグレーションファイルの作成

migrations ディレクトリに保存します。Truffle はファイル名の最初の数字の昇順にマイグレーションを実行します。

デプロイ

ネットワークを選択する場合は --network development のようにオプションで指定できます。truffle.js の設定を参照しています。

マイグレーションをし直したい場合は --reset オプションを付けます。

テスト

test ディレクトリにテストコードを保存し、想定通りの動きをしているか確認してみます。

testGetIdea() では変数を memory にしています。明示的に宣言しなかったら Type error: memory is not implicity convertible to expected type 的な感じで怒られました。

ちなみに変数は格納領域が三つあり、それぞれコストのかかり方が異なります。

  • storage: 参照型の変数 (Struct, 配列, mapping)
  • memory: 関数の引数
  • stack: 基本型の変数 (uint, string etc)

(参考) Solidity の変数の格納領域 (storage, memory, stack) | Qiita

ファイル名を指定しなければ、ディレクトリ内のすべてのファイルに対してテストします。

Vue

デプロイが成功したら、フロントエンドも用意します。今回は Vue を使います。

Vue プロジェクトの初期化

vue-cli を使って Vue のプロジェクトを作ります。全て初期設定です。

Truffle のルートディレクトリで実行します。ディレクトリが空でないため、注意が表示されますがそのまま実行できます。

ちなみに、truffle init は空のディレクトリじゃないと実行できないので、vue init からの truffle init はできません。

必要なパッケージをインストール

フロントエンドでブロックチェーンを扱うためのパッケージを入れます。

Vue Component を書く

vue-cli を使うと基本形が用意されるので、それを少しいじって作ることにします。コントラクトを使って動いていることが最低限分かればいいので、ここは適当に書きます。

コンポーネント名を変更したので src/router/index.js も書き換えます。

JS 側で注意すべき点

  • 非同期なので Promise で返ってくる
  • JSON RPC エラーで泣くことがある
  • BigNumber で返ってくる
  • Metamask のエラーが出て混乱することがある (これは無視)

JSON RPC エラーはパッケージの使い方が正しくなかったりプロバイダ指定が間違っていたりすると起きるようですが、詳細不明です。前者に関しては正しくなくても一見動いているように見えるので、要確認です。

returns (uint) だから int で返ってくるのかと思いきや、BigNumber という型で返ってくることがあります。obj.toString(10) でいいよって Q&A サイトには書かれていましたが、望ましい書き方かどうかはわかりません。obj.toNumber() かもしれませんし、int 型にパースしたほうがいいのかもしれません。

利用環境の準備

Chrome ブラウザで Metamask が使える環境を作っておきます。Chrome ウェブストアから拡張機能としてインストールできます。

Metamask を開き、Ganache 上のアカウントをインポートして使います。Main Ethereum Network になっているので Custom RPC に切り替え、Ganache の動いているポートを指定します。初期設定では http://localhost:7545 です。

ネットワークを切り替えたら Import existing DEN で進みます。12 単語を入力する画面が出るので、Ganache の MNEMONIC をコピペするとインポートできます。

開発環境で実行

webpack-dev-server を使ってローカルサーバで起動します。ポートは 8080 です。(http://localhost:8080)

Ropsten ネットワークへのデプロイ

現時点では Ganache を使ってローカルで動いています。本番環境ではメインネットを使いますが、デプロイ後はコントラクトを書き換えられないのでテストネットを使ってテストします。

Infura の登録

はじめに Infura に登録します。[CREATE NEW PROJECT] でエンドポイントが生成されます。

設定の更新

設定に使うパッケージを入れます。

truffle.js に Ropsten の設定を加えます。

HDWalletProvider() の第二引数には Infura で発行されたエンドポイントを入れます。エンドポイントはユーザーの固有値となるため、誤って Git の管理下にしないように .gitignore で設定して下さい。

network_id は 3 を指定すると Ropsten ネットワークが選択されます。その他の ID にも対応するネットワークがあり、1 がメインネットです。

テスト用 ETH の受け取り

ETH がないと何もできないので、テスト用に配布されているものを受け取ります。

アカウント画面で [BUY] > [ROPSTEN TEST FAUCET] > [request 1 ether from faucet] で Ropsten ネットワークで使える 1ETH が送られてきます。テストネットでブロックが承認されたら受け取れるので、数十秒かかります。

デプロイ

デプロイした後は Metamask を Ropsten ネットワークに切り替えても DApp が動くようになります。

デプロイ時のエラー

Error encountered, bailing. Network state unknown. Review successful transactions manually. insufficient funds for gas * price + value

このエラーはデプロイに使うアカウントに必要な分のガスがなかったときに出ます。恐らく初期設定では一つ目のアカウントが coinbase になっているので、一つ目のアカウントに ETH を入れておくとデプロイできます。

(参考) Ropsten デプロイ時に躓いたことメモ | Qiita

Node.js サーバへのデプロイ

ローカルサーバで動かしているものを公開するためには Node.js に対応する Web サーバに上げる必要があります。GCP や Heroku を使うと楽です。

Express の導入

今回は Express で動く環境を作ります。

Express の設定

設定ファイルを書きます。

npm でビルドしたファイルは dist ディレクトリ下に生成されるので、Express がそこを参照するように設定します。

ビルド

ビルドすると Vue で書いた内容をコンパイルしてくれます。

起動

起動コマンドの設定

上記のコマンドでも動きますが、package.json に設定を加えておくと良いと思います。

初期設定では "dev" と "start" の内容が同じなので、後者を書き換えます。

これ以降は次のコマンドで起動できます。

Heroku へのデプロイ

書くのに疲れてきてしまったので、ざっくりとした説明になります…。

Git の初期化

Heroku で Node.js を始める方法 の「1.開発環境の構築」が終わってるものとして、プロジェクトのルートディレクトリで以下のコマンドを実行します。

.gitignore の編集

初期設定では動かなくなるので、必要に応じてデプロイするディレクトリ、ファイルを変更します。

デプロイ

Heroku 上にアプリを作成し、Git をデプロイします。

(参考) Easily deploy a Vue + Webpack App to Heroku in 5 Steps [tutorial] | Medium

スポンサーリンク

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください