はじめに
Ganacheを使用してプライベートネットワークを構築し、Truffleを使用して「Hello World!」を出力するコントラクトをプライベートネットワーク上にデプロイする。
Truffle & Ganacheのインストール
Truffle
npmからインストールする。
npm install -g truffle
Ganache
公式サイトからダウンロード、インストールする。
https://trufflesuite.com/ganache/
初期設定
作業ディレクトリを作成する。
% mkdir greeting
% cd greeting
truffleプロジェクトの初期化を行う。
% truffle init
Starting init...
================
> Copying project files to /Users/xxx/xxx/greeting
Init successful, sweet!
Try our scaffold commands to get started:
$ truffle create contract YourContractName # scaffold a contract
$ truffle create test YourTestName # scaffold a test
http://trufflesuite.com/docs
初期化実行後のディレクトリは以下になる。
% tree
.
├── contracts
│ └── Migrations.sol
├── migrations
│ └── 1_initial_migration.js
├── test
└── truffle-config.js
3 directories, 3 files
生成されたファイル
- contracts
Solidityプログラムを配置するディレクトリ - migrations
マイグレーションファイルを配置するディレクトリ。
「truffle create migration」コマンドでマイグレーションファイル(.js)が配置され、コントラクトをネットワークにデプロイするために使用される。 - test
テストファイルを配置するディレクトリ - truffle-config.js
Truffleの設定ファイル
Truffleの設定
「truffle-config.js」の内容を以下にする。
module.exports = {
compilers: {
solc: {
version: "0.8.15". // コンパイラのバージョン指定
}
},
networks: {
development: {
host: "127.0.0.1", // Localhost
port: 7545, // Ganacheのデフォルトポート
network_id: "*", // Any network
}
}
}
Ganacheの設定
TruffleとGanacheを連携させる。
Ganacheを開き「NEW WORKSPACE」を選択する。
「ADD PROJECT」を選択し、「truffle-config.js」を読み込ませ「SAVE WORKSPACE」をクリックする。
※WORKSPACE NAMEは任意で変更する
保存ができたら残高100ETHのアドレスが10個生成され、Ethereumのプライベートネットワークが起動する。
TruffleからGanacheに接続
「truffle-config.js」のあるディレクトリで以下コマンドを打ち、エラーが出なければ成功。
※終了するときは「ctrl+d」または「ctrl+c」を2回押す。
% truffle console
truffle(development)>
Hello Worldコントラクトの作成
以下のコマンドを実行することで、「contracts」ディレクトリ配下に「HelloWorld.sol」が作成される。
% truffle create contract HelloWorld
% ls contracts
HelloWorld.sol Migrations.sol
% cat contracts/HelloWorld.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
contract HelloWorld {
constructor() public {
}
}
「Hello World!」を返す「getMessage」関数を作成する。
pragma solidity >=0.4.22 <0.9.0;
contract HelloWorld {
constructor() public {}
function getMessage() public pure returns (string memory) {
return "Hello World!";
}
}
コード説明
- 一行目
コンパイラのバージョンを指定している。 - constructor関数
コントラクト作成時(デプロイ時)に一度だけ実行される関数(上記では空なので何もしない) - getMessage関数
「Hello World!」を返すだけの関数。
コンパイル
以下コマンドでコンパイルをすると「build/contracts」配下にファイルが生成される。
% truffle compile
Compiling your contracts...
===========================
> Compiling ./contracts/HelloWorld.sol
> Artifacts written to /Users/xxx/xxx/greeting/build/contracts
> Compiled successfully using:
- solc: 0.8.15+commit.e14f2714.Emscripten.clang
% ls build/contracts
HelloWorld.json Migrations.json
マイグレーションファイル作成
以下コマンドでコントラクトをデプロイするためのマイグレーションファイルを作成する。
※コマンドを実行すると「migration」ディレクトリ配下に新たにファイルが生成される。
% truffle create migration HelloWorld
% ls migrations
1658805189_hello_world.js 1_initial_migration.js
% cat migrations/1658805189_hello_world.js
module.exports = function(_deployer) {
// Use deployer to state migration tasks.
};
生成された「1658805189_hello_world.js」にデプロイするコントラクトを追記する。
const HelloWorld = artifacts.require("HelloWorld");
module.exports = function(_deployer) {
// Use deployer to state migration tasks.
_deployer.deploy(HelloWorld);
};
デプロイ
以下コマンドでGanacheの開発環境にデプロイする。
% truffle migrate
Compiling your contracts...
===========================
> Everything is up to date, there is nothing to compile.
Starting migrations...
======================
> Network name: 'development'
> Network id: 5777
> Block gas limit: 6721975 (0x6691b7)
1_initial_migration.js
======================
Replacing 'Migrations'
----------------------
> transaction hash: 0x45cb4fd19e69b9b0003b0886dde0b8a49d461e7281a1cc02cb00d649d1df5c58
> Blocks: 0 Seconds: 0
> contract address: 0x87Ad3f841C85f7080b6052aCfE178A6EC21455Ba
> block number: 1
> block timestamp: 1658812104
> account: 0x4AF756f52665e05c1ac4C078c0Fc19b5FBdd5D7e
> balance: 99.99502292
> gas used: 248854 (0x3cc16)
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.00497708 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.00497708 ETH
1658805189_hello_world.js
=========================
Replacing 'HelloWorld'
----------------------
> transaction hash: 0x7d7c5252db6ebf3019fc9c8f27665d67f5a9330007c484e737b494450dc195b3
> Blocks: 0 Seconds: 0
> contract address: 0x03C71AE9A3F94Ca0643ABD223E9E3bF8cd428aB8
> block number: 3
> block timestamp: 1658812105
> account: 0x4AF756f52665e05c1ac4C078c0Fc19b5FBdd5D7e
> balance: 99.99147132
> gas used: 135067 (0x20f9b)
> gas price: 20 gwei
> value sent: 0 ETH
> total cost: 0.00270134 ETH
> Saving migration to chain.
> Saving artifacts
-------------------------------------
> Total cost: 0.00270134 ETH
Summary
=======
> Total deployments: 2
> Final cost: 0.00767842 ETH
トランザクションの確認
Ganacheの画面を確認してみると、INDEX 0のアカウントの残高が少し減っており、トランザクションカウントも4になっているのがわかる。
続いて、トランザクション一覧を確認してみると4つのトランザクションが確認できる。
トランザクションは下から時系列順になっており、最初に作成された一番下のトランザクションは「Migrations.sol」コントラクトを作成するトランザクションになっている。
以下記載事項の説明
- TX HASH
トランザクションのハッシュ値 - FROM ADDRESS
「ACCOUNTS」タブにてトランザクションに使用したINDEX 0のアドレス - CREATED CONTRACT ADDRESS
コントラクトデプロイ時に割り当てられるアドレス、このアドレスを呼び出すことでコントラクトを実行できる。
「CONTRACTS」タブにて作成されたコントラクトを確認でき、名前が「Migrations」のアドレスと一致していることがわかる。 - GAS USED
使用したGAS - VALUE
転送したETHの量、今回はETHを送金していないので0 - CONTRACT CREATION
このトランザクションでコントラクトを作成したことを表す。
続いて下から2番目は「CONTRACT CALL」となっており、コントラクトを呼び出したことがわかる。
クリックして詳細を見てみる。
「TO CONTRACT ADDRESS」は作成された「Migrations」コントラクトのアドレスである。
「CONTRACT」の箇所をみると、実行した関数が「setCompleted(completed: uint256)」で引数に「1」を与えていることがわかる。
これは、「Migrations.sol」の以下に該当し、どのマイグレーションファイルを実行したかを記録する関数になっている。
※ 1というのは、「migrations」ディレクトリ配下にある「1_initial_migration.js」ファイルの先頭アンダーバーまでの数字
また、一度実行されたマイグレーションファイルは次回以降マイグレーションがスキップされるが、「truffle migrate —reset」とすることで全てのファイルをマイグレーションしてくれる。
function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
続いて、トランザクション一覧に戻り、下から3番目は「HelloWorld」コントラクトを作成したものとなっている。
最後に一番上のトランザクションは、先ほどと同じく「Migrations」コントラクトを呼び出しており、今度は引数に「1658805189」を与えており、マイグレーションを行ったことを記録している。
※ 上記同様に「1658805189_hello_world.js」の先頭アンダーバーまでの数字
HelloWorldコントラクトの呼び出し
truffle console から「getMessage」関数を実行し、「Hello World!」を表示させることができる。
% truffle console
truffle(development)> let helloWorld = await HelloWorld.deployed()
undefined
truffle(development)> helloWorld.getMessage()
'Hello World!'
コントラクトのアドレスを指定して実行することも可能。
truffle(development)> HelloWorld.address
'0x03C71AE9A3F94Ca0643ABD223E9E3bF8cd428aB8'
truffle(development)> let helloWorld = await HelloWorld.at(HelloWorld.address)
undefined
truffle(development)> helloWorld.getMessage()
'Hello World!'
0件のコメント