
【後編】Ethereum Pet Shop DAppの作成とテスト~UI 作成編~
2021.12.20
後編~Ethereum Pet ShopでDApp作成とテスト~
前回に引き続き「Ethereum Pet Shopを使って DAppの作成からテスト」まで行ってみたいと思います!
中編では、実際にコントラクトを作成し、テストまで行っていきました。
今回は、UI の作成を行っていきたいと思います!
制作工程
- 環境設定
- Truffle Box を使って Truffle プロジェクトを作成
- コントラクト作成
- コントラクトをコンパイルしてデプロイ
- コントラクトのテスト
- UI 作成
- ブラウザ上の DApp でログインする
UI の作成
pet shop の Truffle Box には、アプリのフロントエンドファイルが src ディレクトリに内包されています。
仕様は以下の通りです。
- Lite Server を起動
- 購入画面で選んだペットの「Adopt」ボタンをクリック
- MetaMask に登録した Ethereum アドレスで承認
このコントラクトから、MetaMask 経由で対話できる UI が「web3」です。
web3 のインスタンス化
アプリはグローバルオブジェクトで、int( ) 内にペットのデータがロードされ、intWeb3( )関数で読み込みます。
また、Ethereum Blockchainとの対話に必要なデータがパッケージ化されている「Web3JavascriptLibrary」も使えます。
これにより、「ユーザーアカウントの取得」「トランザクションの送金」「コントラクトとの対話」などが出来ます。
【Web3JavascriptLibrary】
https://github.com/ethereum/web3.js/
app.js ファイルを修正
まず、src/js/app.js ファイルをテキストエディタで開きます。
app.js ファイルを、以下のコードに修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | App = { web3Provider: null, contracts: {}, init: async function() { // ペットの情報をロードします。 $.getJSON('../pets.json', function(data) { var petsRow = $('#petsRow'); var petTemplate = $('#petTemplate'); for (i = 0; i < data.length; i ++) { petTemplate.find('.panel-title').text(data[i].name); petTemplate.find('img').attr('src', data[i].picture); petTemplate.find('.pet-breed').text(data[i].breed); petTemplate.find('.pet-age').text(data[i].age); petTemplate.find('.pet-location').text(data[i].location); petTemplate.find('.btn-adopt').attr('data-id', data[i].id); petsRow.append(petTemplate.html()); } }); return await App.initWeb3(); }, initWeb3: async function() { // DAppを使用できるブラウザーか確認する if (window.ethereum) { App.web3Provider = window.ethereum; try { // アカウントへのアクセス要求 await window.ethereum.enable(); } catch (error) { // ユーザーがアカウントのアクセスを拒否しました console.error("User denied account access") } } // Web3プロバイダーのウィンドウを開く else if (window.web3) { App.web3Provider = window.web3.currentProvider; } // もし挿入されたWeb3インスタンスが検出されない場合は、Ganacheに戻します else { App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545'); } web3 = new Web3(App.web3Provider); return App.initContract(); }, <span style="color: rgb(255, 0, 0);" data-mce-style="color: #ff0000;"> initContract: function() { $.getJSON('Adoption.json', function(data) { //必要なContract Artifactファイルを取得し、@truffle/contractでインスタンス化します var AdoptionArtifact = data; App.contracts.Adoption = TruffleContract(AdoptionArtifact); // コントラクトの為にプロバーダーを設定します App.contracts.Adoption.setProvider(App.web3Provider); // データ取得と受け取ったペットをマーキングする為にコントラクトを使用します return App.markAdopted(); }); </span> return App.bindEvents(); }, bindEvents: function() { $(document).on('click', '.btn-adopt', App.handleAdopt); }, markAdopted: function(adopters, account) { var adoptionInstance; App.contracts.Adoption.deployed().then(function(instance) { adoptionInstance = instance; return adoptionInstance.getAdopters.call(); }).then(function(adopters) { for (i = 0; i < adopters.length; i++) { if (adopters[i] !== '0x0000000000000000000000000000000000000000') { $('.panel-pet').eq(i).find('button').text('Success').attr('disabled', true); } } }).catch(function(err) { console.log(err.message); }); }, handleAdopt: function(event) { event.preventDefault(); var petId = parseInt($(event.target).data('id')); var adoptionInstance; web3.eth.getAccounts(function(error, accounts) { if (error) { console.log(error); } var account = accounts[0]; App.contracts.Adoption.deployed().then(function(instance) { adoptionInstance = instance; // アカウントを送信してデータ取得としてのトランザクションを実行します return adoptionInstance.adopt(petId, {from: account}); }).then(function(result) { return App.markAdopted(); }).catch(function(err) { console.log(err.message); }); }); } }; $(function() { $(window).load(function() { App.init(); }); }); |
コントラクトのインスタンス化
上記コードの Artifact は、展開されたアドレスや ABI などのコントラクトに関する情報です。
ABI | 「変数」「関数」「そのパラメーターを含むコントラクトとの対話方法」を定義するJavaScriptオブジェクト |
TruffleContract( )関数 | TruffleContract( )関数を通過すると、対話可能なコントラクトのインスタンスが作成されます |
App.web3Provider変数 | web3 に最初に設定する時に格納した値が入ります |
markAdpted( )関数 | 既に受け入れが決まったペットを読み込みます |
確認

UI のアップデート
Adoption.sol コントラクトをデプロイすると、「getAdopters( )関数」を呼び込みます。
「adoptionInstance 変数」でデータを呼び出し、コントラクト外で宣言した後、インスタンスにアクセスできるようにします。
loop でデータを検索し、Ethereum アドレスが格納されている petId を見つけ出すと「Success」ボタンに変わります。
確認

adopt()関数の処理
「ペットの ID」と「アカウントに格納したアドレスを含むオブジェクト」を使用して、adopt( )関数を実行することにより、トランザクションを送信します。
エラーがない場合は、「markAdopted( )関数」を呼び出して、UI を新しく保存されたデータと同期します。
MetaMask の設定
ブラウザアプリをインストール
まず、MetaMask のブラウザアプリをインストールします。

ログインする
インストール後に、デプロイでターミナル上に表示された Mnemonic を使用し、ログインします。
ネットワークから「カスタムRPC」を選択し、「http://127.0.0.1:7545」を入力しましょう。

すると、各アカウントにテスト用の「100ETH」が表示されます。
ただし、コントラクトのデプロイ時や Ganache でテストに使った場合は、「Gas」 が差し引かれている場合があります。
「コントラクト」「Ganache」「MetaMask」が連携されたことを確認してください。
Lite-Server のインストールと構成
まず、Lite-Server をインストールします。
1 2 3 4 5 | //lite-serverの起動 $ npm install -g lite-server //******プロジェクトルート $ pet-shop-tutorial pet-shop > lite-server //******プロジェクトルート |
ベースディレクトリーの設定
「bs-config.json」をテキストエディタで開きます。
以下のコマンドの場合、 Webサイトファイル用の「./srcディレクトリー」と、contract artifacts用の「./build/contractsディレクトリー」を追加します。
1 | { "server": { "baseDir": ["./src", "./build/contracts"] } } |
dev コマンドを追加
プロジェクトのルートディレクトリーに、「package.json」ファイルがあります。
このファイルに、「dev コマンド」を追加します。
スクリプトオブジェクトを使用すると、コンソールコマンドを単一の npm コマンドに変換できます。
1 2 3 4 | "scripts": { "dev": "lite-server", "test": "echo \"Error: no test specified\" && exit 1" }, |
実行
Lite-Server を実行しましょう。
以下のコマンドで、MetaMask が起動します。
1 | npm run dev |
必ず、Web3 で設定したコンパイル設定のポート上「http://127.0.0.1:7545」でログインしてください。
app.js ファイルで設定したアカウントで開くと、認証後に「Adopt」ボタンが「Success」に変更されます。
さいごに
「Ethereum Pet Shop」は、Ethereum ブロックチェーンのトレーニング用プロジェクトです。
「コントラクトの作成」から「デプロイの仕方」「MetaMask への連携」「Ganache でのテスト」まで制作手順が分かります。
このプロジェクトを通して、プライベートブロックチェーン「Ethereum」の可能性を感じました。
「Ethereum」は、決済手段だけではなく、認証手段として使用することで DApp の活用方法も広がります。
新たな Web3 の世界がインターネットに変革を起こしそうですね!
おすすめの本
こちらの記事もオススメ!
関連記事
書いた人はこんな人

- 「好きなことを仕事にするエンジニア集団」の(株)ライトコードです!
ライトコードは、福岡、東京、大阪の3拠点で事業展開するIT企業です。
現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。
いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。
システム開発依頼・お見積もりは大歓迎!
また、WEBエンジニアとモバイルエンジニアも積極採用中です!
ご応募をお待ちしております!
ITエンタメ2022.05.25COBOL開発者は「コンピューターおばあちゃん」で海軍准将!?グレース・ホッパー
ITエンタメ2022.05.23マイクロソフトの壁は穴だらけ!?デヴィッド・カトラー
ITエンタメ2022.05.13ホーコン・ウィウム・リーが提唱したCSSの過去と未来
ITエンタメ2022.04.28ラスムッセン兄弟が作ったグーグルマップの軌跡