その1、その2からの続きでで、ETHEREUM PET SHOP チュートリアルをやっていきます。
Creating a user interface to interact with the smart contract
今度は、UIの作成です。
最初に見たように、基本的な画面は表示されるようになっています。
チュートリアルのUI変更の最初としては、/src/js/app.js の、データを読み込んでいるinit() が、initWeb3() を呼び出しているので、これに手を入れていくとのこと。
まずは、web3のインスタンス作成。web3とは、web3 JavaScript library。これを使って、Ethereum ブロックチェーンとやりとりをします。
次は、スマートコントラクトのインスタンス作成です。
これは、truffle-contract ライブラリが行います。
まずやりたいのは、Adoption に接続して、getAdopters() を呼び出すことで、これをmarkAdopted Functionで行います。
養育引受済みのペットは、adoptボタン(引受ボタン)を使用不可にして、文字を「Success」にします。
console.log(err.message);
で、コンソールログ出力が可能です。
最後に、adopt() で引受ける処理を作成します。
これらを記載した、app.js は下記のようになります。
App = {
web3Provider: null,
contracts: {},
init: async function() {
// Load pets.
$.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() {
// Modern dapp browsers...
if (window.ethereum) {
App.web3Provider = window.ethereum;
try {
// Request account access
await window.ethereum.enable();
} catch (error) {
// User denied account access...
console.error("User denied account access")
}
}
// Legacy dapp browsers...
else if (window.web3) {
App.web3Provider = window.web3.currentProvider;
}
// If no injected web3 instance is detected, fall back to Ganache
else {
App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
}
web3 = new Web3(App.web3Provider);
return App.initContract();
},
initContract: function() {
$.getJSON('Adoption.json', function(data) {
// Get the necessary contract artifact file and instantiate it with truffle-contract
var AdoptionArtifact = data;
App.contracts.Adoption = TruffleContract(AdoptionArtifact);
// Set the provider for our contract
App.contracts.Adoption.setProvider(App.web3Provider);
// Use our contract to retrieve and mark the adopted pets
return App.markAdopted();
});
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;
// Execute adopt as a transaction by sending account
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();
});
});
Interacting with the dapp in a browser
では、ブラウザでdappを使用します。
最初は、MetaMask のインストールから説明が始まりますが、ここではインストールされているものとして、スキップします。チュートリアルでいうと、6.まで終わっている状態です。
その状態で、MetaMaskをganacheのネットワークに接続するわけですが、http://127.0.0.1:7545 ではなく、HTTP://10.200.10.1:7545 に接続します。e
ここまで来ると、ローカルサーバを起動して、dapp を使うことができるということで、その仕組みとして、lite-server が使用されているとのことです。
では、改めて、ブラウザでアプリを開いてみます。
チュートリアルでは、npm run dev を叩くとなっていますが、docker-compose で起動時にこれを実行することになっています。
いったん、Docker 環境を抜けます。
/usr/src/app # exit
そして、起動しなおします。
$ docker-compose down
$ docker-compose up -d
http://localhost:8003/
あれ、全部Successになってる・・・

最後がイマイチですが、とりあえず、ここまでがチュートリアルでした。
Docker を使用して、開発する流れはできたかなと思います。
次は何をすれば良いのだろう・・・