前回はMeteorを利用してDAppsを開発してみました。
今回はTruffle(トリュフ)というフレームワークで同じように試してみます。
デプロイ部分やテストなども説明しているので長文です。
Truffleとは
Consensysが提供しているDApps開発用フレームワーク。
デプロイやテスト実行なども含めてフレームワーク化されており、ドキュメント(英語)も提供している。
参考URL:
http://truffleframework.com/
http://truffleframework.com/tutorials/
合わせてGanacheやDrizzleも提供されておりDAppsを作る上での環境が現状最も充実している。
準備
NodeJSのインストール
https://nodejs.org/en/ から最新版をダウンロードしてインストーラでインストールします。
truffleのインストール
truffleはnpmコマンドでインストールします。
$ npm install -g truffle
/usr/local/bin/truffle -> /usr/local/lib/node_modules/truffle/build/cli.bundled.js
+ truffle@4.0.6
added 91 packages in 6.651s
$ truffle version
Truffle v4.0.6 (core: 4.0.6)
Solidity v0.4.19 (solc-js)
Ganacheのインストール
ついでにGanacheというツールもダウンロードします。
http://truffleframework.com/ganache/ からインストーラーをダウンロードします。
プロジェクトの作成
プロジェクトを作成するには適当な場所にフォルダを作成し、その中にテンプレートのコードをダウンロードします。
今回はコンセンシスが公開しているPet Shopというテンプレートでプロジェクトを作成してみます。
Pet Shopの詳しい手順は http://truffleframework.com/tutorials/pet-shop を参照ください。
フォルダの作成
$ mkdir pet-shop-tutorial
$ cd pet-shop-tutorial/
テンプレートのダウンロード
$ truffle unbox pet-shop
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!
Commands:
Compile: truffle compile
Migrate: truffle migrate
Test contracts: truffle test
Run dev server: npm run dev
テンプレートではなく空のプロジェクトを作りたい場合は以下のようにinitオプションを使用します。
$ truffle init
プロジェクトの構造
こちらはDAppsに特化しているだけあって構造はわかりやすいです。
- contractsにsolidityのコードを追加します。
- migrationsはデプロイ用のコードです。
- srcの下は通常のWebアプリのソースコードです。
- testの下にテストコードを書いていきます。
DAppsの作成
ここから先はPetshopのチュートリアルに従います。
Adoption.sol の作成
以下のコードを記載します。
pragma solidity ^0.4.17;
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]) {
return adopters;
}
}
コンパイル
以下のコマンドでsolidityのコードをコンパイルします。
現在はWarningが出ますが特に問題ないのでそのまま進みます。
$ truffle compile
Compiling ./contracts/Adoption.sol...
Compiling ./contracts/Migrations.sol...
Compilation warnings encountered:
/Users/tomonariokubo/truffleProjects/pet-shop-tutorial/contracts/Migrations.sol:11:3: Warning: No visibility specified. Defaulting to "public".
function Migrations() {
^
Spanning multiple lines.
,/Users/tomonariokubo/truffleProjects/pet-shop-tutorial/contracts/Migrations.sol:15:3: Warning: No visibility specified. Defaulting to "public".
function setCompleted(uint completed) restricted {
^
Spanning multiple lines.
,/Users/tomonariokubo/truffleProjects/pet-shop-tutorial/contracts/Migrations.sol:19:3: Warning: No visibility specified. Defaulting to "public".
function upgrade(address new_address) restricted {
^
Spanning multiple lines.
Writing artifacts to ./build/contracts
移行スクリプトを作成
truffleではデプロイ用のスクリプトを作成する仕組みになっています。
これを一度作るとコマンドライン一行で毎回デプロイできるので便利です。
以下のように2_deploy_contracs.jsを作ります。
var Adoption = artifacts.require("Adoption");
module.exports = function(deployer) {
deployer.deploy(Adoption);
};
デプロイ
ブロックチェーンネットワークの開始
プライベートネットを開始するにはGanacheアイコンをクリックするだけです。
これでプライベートネットがローカル環境に開始され、マイニングも自動的に開始されます。
さらにアカウントがランダムに10個出来上がります。
プライベートネットにSolidityのコードをデプロイします。
$ truffle migrate
Using network 'development'.
Running migration: 1_initial_migration.js
Deploying Migrations...
... 0xa62e50bcc466353b229a9d9c4f1d61ff0c27eb3f7423174532eb9e875c318485
Migrations: 0x8cdaf0cd259887258bc13a92c0a6da92698644c0
Saving successful migration to network...
... 0xd7bc86d31bee32fa3988f1c1eabce403a1b5d570340a3a9cdba53a472ee8c956
Saving artifacts...
Running migration: 2_deploy_contracts.js
Deploying Adoption...
... 0x4f39b4b30e8d5283a79691f34367345f5d20ed5d1aeef99c6b44d1364ca72c22
Adoption: 0x345ca3e014aaf5dca488057592ee47305d9b3e10
Saving successful migration to network...
... 0xf36163615f41ef7ed8f4a8f192149a0bf633fe1a2398ce001bf44c43dc7bdda0
Saving artifacts...
テストスクリプトの作成
以下のようにテストスクリプトを作成し、テストを自動化することができます。
pragma solidity ^0.4.17;
import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/Adoption.sol";
contract TestAdoption {
Adoption adoption = Adoption(DeployedAddresses.Adoption());
// Testing the adopt() function
function testUserCanAdoptPet() public {
uint returnedId = adoption.adopt(8);
uint expected = 8;
Assert.equal(returnedId, expected, "Adoption of pet ID 8 should be recorded.");
}
// Testing retrieval of a single pet's owner
function testGetAdopterAddressByPetId() public {
// Expected owner is this contract
address expected = this;
address adopter = adoption.adopters(8);
Assert.equal(adopter, expected, "Owner of pet ID 8 should be recorded.");
}
// Testing retrieval of all pet owners
function testGetAdopterAddressByPetIdInArray() public {
// Expected owner is this contract
address expected = this;
// Store adopters in memory rather than contract's storage
address[16] memory adopters = adoption.getAdopters();
Assert.equal(adopters[8], expected, "Owner of pet ID 8 should be recorded.");
}
}
$ truffle test
Using network 'development'.
Compiling ./contracts/Adoption.sol...
Compiling ./test/TestAdoption.sol...
Compiling truffle/Assert.sol...
Compiling truffle/DeployedAddresses.sol...
TestAdoption
✓ testUserCanAdoptPet (120ms)
✓ testGetAdopterAddressByPetId (202ms)
✓ testGetAdopterAddressByPetIdInArray (205ms)
3 passing (1s)
ブラウザで実行
Metamaskの準備
Metamaskを新規で導入する場合は http://truffleframework.com/tutorials/pet-shop の手順に従ってもいいが、すでに使っている場合は以下の手順。
Ganacheでプライベートキーを確認
Account4という名前で出来ました。(Account4は私の環境の場合です。また名前は自由に変更できます。)
$ npm run dev
以下のように画面が表示されれば成功です。
Adoptボタンを押すと以下のようにMetamaskのポップアップが出てきますのでSubmitをクリックします。
ブラウザをリロードしてSuccessに変わっていれば成功です。
最後に
実はこの記事を書いている最中にLoom Networkという会社が運営している以下のサイトを見つけました。
最初に見つけた際は目から鱗でした。
内容としてはSolidityの基本を学びながら最終的にはDAppsでのゲーム開発の流れが日本語で理解できます。