その1からの続きでで、ETHEREUM PET SHOP チュートリアルをやっていきます。
Writing the smart contract
バックエンドとして動作するスマートコントラクト、Adoption.sol を作成していきます。
記述結果はこのようになります。
pragma solidity ^0.5.0;
contract Adoption {
address[16] public adopters;
// Adopting a pet
function adopt(uint petId) public returns (uint) {
require(petId >= 0 && petId <= 15);
adopters[petId] = msg.sender;
return petId;
}
// Retrieving the adopters
function getAdopters() public view returns (address[16] memory) {
return adopters;
}
Compiling and migrating the smart contract
コンパイルは、
$ truffle compile
を叩きます。Docker環境の中で。これがポイント。
普通にやるのであれば、docker-compose up で起動中の環境を、Ctrl+Cで終了。
改めて、
$ docker-compose up -d
でバックグラウンド起動。
この状態で、Docker内のshellに入ります。
下記の、「truffle」は、docker-compose.yml で、services:の下で指定している名前。
$ docker-compose run truffle sh
/usr/src/app #
こんな感じで表示されますので、truffle compile を実行します。
/usr/src/app # truffle compile
You can improve web3's performance when running Node.js versions older than 10.5.0 by installing the (deprecated) scrypt package in your project
Compiling your contracts...
===========================
> Compiling ./contracts/Adoption.sol
> Artifacts written to /usr/src/app/build/contracts
> Compiled successfully using:
- solc: 0.5.16+commit.9c3226ce.Emscripten.clang
成功です。
続いてマイグレーション。マイグレーションファイルを使って、ネットワークにデプロイします。
元々準備されている、migrations/1_initial_migration.js は、trrfle プロジェクトを作成した際に作られるもので、Migrations.sol をデプロイするということだけを書いているのですね。
そこで、Adoption.sol をデプロイするための、2_deploy_contracts.js を作ります。
やっている内容は、対象が違うだけで、1_initial_migration.js と同じです。
var Adoption = artifacts.require("Adoption");
module.exports = function(deployer) {
deployer.deploy(Adoption);
};
マイグレートする前には、ganache が起動していることを確認しておきます。
RPC SERVER
HTTP://10.200.10.1:7545
です。
そして、コンパイル時に、Docker環境に入っていると思いますので、実行します。
/usr/src/app # truffle migrate
You can improve web3's performance when running Node.js versions older than 10.5.0 by installing the (deprecated) scrypt package in your project
Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.
Starting migrations...
======================
> Network name: 'development'
> Network id: 5777
> Block gas limit: 0x6691b7
2_deploy_contracts.js
=====================
Deploying 'Adoption'
--------------------
> transaction hash: 0x60f8967bc9aff355dac281fe96576362ea57bcc8b461466ee6eb19e7df645b76
> Blocks: 0 Seconds: 0
> contract address: 0xb25D78Fc89CE462816Aa4596e93b9a31CAfC176E
> block number: 7
> block timestamp: 1585479243
> account: 0xc55F3d6C444ca88f529F3413EDEd85a39e38609C
> balance: 99.98329494
> gas used: 239915
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.0047983 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.0047983 ETH
Summary
=======
> Total deployments: 1
> Final cost: 0.0047983 ETH
成功です。ganacheの画面でも、current block が増加し、最初のアカウントのetherが減少しています。
Testing the smart contract
次は、テストを書いていきます。テストは、JavaScript でも、Solidity でも書けるそうです。チュートリアルでは、Solidity で書いていきます。
Adoption.sol は、
- address[16] public adopters
- function adopt(uint petId) public returns (uint)
- function getAdopters() public view returns (address[16] memory)
のPublic 変数、Functionがありますので、それらをテストします。
チュートリアルに従って記述していくと、下記のようになります。
pragma solidity ^0.5.0;
import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/Adoption.sol";
contract TestAdoption {
// The address of the adoption contract to be tested
Adoption adoption = Adoption(DeployedAddresses.Adoption());
// Testing the adopt() function
function testUserCanAdoptPet() public {
uint returnedId = adoption.adopt(expectedPetId);
Assert.equal(returnedId, expectedPetId, "Adoption of the expected pet should match what is returned.");
}
// Testing retrieval of a single pet's owner
function testGetAdopterAddressByPetId() public {
address adopter = adoption.adopters(expectedPetId);
Assert.equal(adopter, expectedAdopter, "Owner of the expected pet should be this contract");
}
// Testing retrieval of all pet owners
function testGetAdopterAddressByPetIdInArray() public {
// Store adopters in memory rather than contract's storage
address[16] memory adopters = adoption.getAdopters();
Assert.equal(adopters[expectedPetId], expectedAdopter, "Owner of the expected pet should be this contract");
}
// The id of the pet that will be used for testing
uint expectedPetId = 8;
//The expected owner of adopted pet is this contract
address expectedAdopter = address(this);
}
コンソールはDocker環境に入っていると思いますので、そこでテストを実行します。
/usr/src/app # truffle test
You can improve web3's performance when running Node.js versions older than 10.5.0 by installing the (deprecated) scrypt package in your project
Using network 'development'.
Compiling your contracts...
===========================
> Compiling ./test/TestAdoption.sol
> Artifacts written to /tmp/test-2020229-61-u4mbmv.pjgpm
> Compiled successfully using:
- solc: 0.5.16+commit.9c3226ce.Emscripten.clang
TestAdoption
✓ testUserCanAdoptPet (140ms)
✓ testGetAdopterAddressByPetId (147ms)
✓ testGetAdopterAddressByPetIdInArray (164ms)
3 passing (10s)
成功しました。
Creating a user interface to interact with the smart contract
では、UIの作成に入っていきます。
(いったん公開して、その3に続けていきます。)