【後編】Ethereum Pet Shop DAppの作成とテスト~UI 作成編~
IT技術
後編~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 ファイルを、以下のコードに修正します。
1App = {
2 web3Provider: null,
3 contracts: {},
4
5 init: async function() {
6 // ペットの情報をロードします。
7 $.getJSON('../pets.json', function(data) {
8 var petsRow = $('#petsRow');
9 var petTemplate = $('#petTemplate');
10
11 for (i = 0; i < data.length; i ++) {
12 petTemplate.find('.panel-title').text(data[i].name);
13 petTemplate.find('img').attr('src', data[i].picture);
14 petTemplate.find('.pet-breed').text(data[i].breed);
15 petTemplate.find('.pet-age').text(data[i].age);
16 petTemplate.find('.pet-location').text(data[i].location);
17 petTemplate.find('.btn-adopt').attr('data-id', data[i].id);
18
19 petsRow.append(petTemplate.html());
20 }
21 });
22
23 return await App.initWeb3();
24 },
25
26 initWeb3: async function() {
27 // DAppを使用できるブラウザーか確認する
28if (window.ethereum) {
29 App.web3Provider = window.ethereum;
30 try {
31 // アカウントへのアクセス要求
32 await window.ethereum.enable();
33 } catch (error) {
34 // ユーザーがアカウントのアクセスを拒否しました
35 console.error("User denied account access")
36 }
37}
38// Web3プロバイダーのウィンドウを開く
39else if (window.web3) {
40 App.web3Provider = window.web3.currentProvider;
41}
42// もし挿入されたWeb3インスタンスが検出されない場合は、Ganacheに戻します
43else {
44 App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
45}
46web3 = new Web3(App.web3Provider);
47
48 return App.initContract();
49 },
50
51<span style="color: rgb(255, 0, 0);" data-mce-style="color: #ff0000;"> initContract: function() {
52 $.getJSON('Adoption.json', function(data) {
53 //必要なContract Artifactファイルを取得し、@truffle/contractでインスタンス化します
54 var AdoptionArtifact = data;
55 App.contracts.Adoption = TruffleContract(AdoptionArtifact);
56
57 // コントラクトの為にプロバーダーを設定します
58 App.contracts.Adoption.setProvider(App.web3Provider);
59
60 // データ取得と受け取ったペットをマーキングする為にコントラクトを使用します
61 return App.markAdopted();
62});
63</span>
64
65 return App.bindEvents();
66 },
67
68 bindEvents: function() {
69 $(document).on('click', '.btn-adopt', App.handleAdopt);
70 },
71
72 markAdopted: function(adopters, account) {
73 var adoptionInstance;
74
75App.contracts.Adoption.deployed().then(function(instance) {
76 adoptionInstance = instance;
77
78 return adoptionInstance.getAdopters.call();
79}).then(function(adopters) {
80 for (i = 0; i < adopters.length; i++) {
81 if (adopters[i] !== '0x0000000000000000000000000000000000000000') {
82 $('.panel-pet').eq(i).find('button').text('Success').attr('disabled', true);
83 }
84 }
85}).catch(function(err) {
86 console.log(err.message);
87});
88
89 },
90
91 handleAdopt: function(event) {
92 event.preventDefault();
93
94 var petId = parseInt($(event.target).data('id'));
95
96 var adoptionInstance;
97
98web3.eth.getAccounts(function(error, accounts) {
99 if (error) {
100 console.log(error);
101 }
102
103 var account = accounts[0];
104
105 App.contracts.Adoption.deployed().then(function(instance) {
106 adoptionInstance = instance;
107
108 // アカウントを送信してデータ取得としてのトランザクションを実行します
109 return adoptionInstance.adopt(petId, {from: account});
110 }).then(function(result) {
111 return App.markAdopted();
112 }).catch(function(err) {
113 console.log(err.message);
114 });
115});
116
117 }
118
119};
120
121$(function() {
122 $(window).load(function() {
123 App.init();
124 });
125});
コントラクトのインスタンス化
上記コードの 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 //lite-serverの起動
2 $ npm install -g lite-server
3 //*****プロジェクトルート
4 $ pet-shop-tutorial pet-shop > lite-server
5 //******プロジェクトルート
ベースディレクトリーの設定
「bs-config.json」をテキストエディタで開きます。
以下のコマンドの場合、 Webサイトファイル用の「./srcディレクトリー」と、contract artifacts用の「./build/contractsディレクトリー」を追加します。
1{ "server": { "baseDir": ["./src", "./build/contracts"] } }
dev コマンドを追加
プロジェクトのルートディレクトリーに、「package.json」ファイルがあります。
このファイルに、「dev コマンド」を追加します。
スクリプトオブジェクトを使用すると、コンソールコマンドを単一の npm コマンドに変換できます。
1"scripts": {
2 "dev": "lite-server",
3 "test": "echo \"Error: no test specified\" && exit 1"
4},
実行
Lite-Server を実行しましょう。
以下のコマンドで、MetaMask が起動します。
1npm run dev
必ず、Web3 で設定したコンパイル設定のポート上「http://127.0.0.1:7545」でログインしてください。
app.js ファイルで設定したアカウントで開くと、認証後に「Adopt」ボタンが「Success」に変更されます。
さいごに
「Ethereum Pet Shop」は、Ethereum ブロックチェーンのトレーニング用プロジェクトです。
「コントラクトの作成」から「デプロイの仕方」「MetaMask への連携」「Ganache でのテスト」まで制作手順が分かります。
このプロジェクトを通して、プライベートブロックチェーン「Ethereum」の可能性を感じました。
「Ethereum」は、決済手段だけではなく、認証手段として使用することで DApp の活用方法も広がります。
新たな Web3 の世界がインターネットに変革を起こしそうですね!
おすすめの本
こちらの記事もオススメ!
2020.08.14ブロックチェーン特集知識編ブロックチェーンとコンセンサスアルゴリズム実装編【Blockchain Data Managerを使ってみたEt...
2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...
関連記事
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
「好きを仕事にするエンジニア集団」の(株)ライトコードです! ライトコードは、福岡、東京、大阪、名古屋の4拠点で事業展開するIT企業です。 現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。 いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。 システム開発依頼・お見積もり大歓迎! また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」を積極採用中です! インターンや新卒採用も行っております。 以下よりご応募をお待ちしております! https://rightcode.co.jp/recruit
おすすめ記事
immichを知ってほしい
2024.10.31