Truffleでコントラクトのコンパイルとローカルへのデプロイ
# 目次
Truffleを使ってSolidityで書かれたコントラクトをコンパイル、そしてローカルテストネットへデプロイする方法を紹介します.
# この記事で得られるもの
- Truffleを使ったコンパイル方法
- ローカルテストネットへデプロイする方法
# Truffleを使ったコンパイル方法
イーサリアム上のアプリ(スマートコントラクト)は現在Solidityという言語で書きます.
ソースコードをバイトコードにコンパイルします.
ここではコンパイル方法を学ぶためにSolidityで"Hello, world!!"
と返すだけの簡単なスマートコントラクトを書いてみましょう.
truffleプロジェクトのcontractsディレクトリの中に、
以下の内容でHelloWorld.solというファイルを作成して下さい.
pragma solidity ^0.4.23;
contract HelloWorld
{
function say () pure external returns (string)
{
return "Hello, world!!";
}
}
コンパイルしてみましょう.
../node_modules/.bin/truffle compile
contracts以下のファイルが自動ですべてコンパイルされます.
build/contracts/HelloWorld.jsonというファイルが出力されていれば成功です.
# デプロイスクリプトの作成
TruffleでデプロイするためにはJavascriptで書かれたデプロイ用のスクリプトが必要になります.
migrationsディレクトリ以下に連番で作成します.
予めmigrations/1_initial_migration.jsというファイルがあります.
以下の内容を2_deploy_helloworld.jsというファイル名で保存して下さい.
var HelloWorld = artifacts.require("HelloWorld");
module.exports = function(deployer) {
deployer.deploy(HelloWorld);
};
先ほど作成したコントラクトを取得し、公開するという内容です.
# ローカルテストネットにデプロイする
Truffleが提供するローカルテスト用ネットワークとコンソールを立ち上げましょう.
../node_modules/.bin/truffle develop
開発の便利のために予め作成された10個のアカウントが表示されます.
それぞれEtherの残高も持っています.
Ethereumネットワークではコントラクトの公開や呼び出し、送金の度にEtherを支払う必要があります.
1番目のアカウントの残高を確認してみましょう.
コントラクトの公開やマイニングなどではデフォルトで1番目([0]
)のアカウントの残高が使用されます.
値はETHの1/1000000000000000000のWeiという単位で返されます.
分かりやすさのために、1000000000000000000で割ってETHに変換しています.
web3.eth.getBalance(web3.eth.accounts[0]).toNumber() / 10**18
100
100ETHが初期設定されています.
デプロイしましょう.
migrate --reset
migrateがTruffleでデプロイするコマンドです.
migrationsディレクトリ以下が1番から順番に実行されます.
デフォルトでは一度実行されたものは実行がスキップされます.
--reset
パラメータを渡すことで必ず1から実行させることが出来ます.
以下のようなメッセージが出力されたら成功です.
HelloWorld: 0x345ca3e014aaf5dca488057592ee47305d9b3e10
Saving successful migration to network...
... 0xf36163615f41ef7ed8f4a8f192149a0bf633fe1a2398ce001bf44c43dc7bdda0
HelloWorld:
の右側のハッシュ値がこのコントラクトのアドレスです.
コントラクトを呼び出す時にはこのアドレスが必要になります.
Truffleの場合はデプロイ後、HelloWorld.address
という変数に格納してくれています.
呼び出してみましょう.
var hw = HelloWorld.at(HelloWorld.address)
hw.say()
"Hello, world!!"
表示されました.
ここでもう一度1番目のアカウント残高を確認しましょう.
web3.eth.getBalance(web3.eth.accounts[0]).toNumber() / 10**18
99.95170309999999
コントラクトのデプロイに消費した分が減っていますね.
# ABIとコントラクトアドレス
var hw = HelloWorld.at(HelloWorld.address)
この行でHelloWorldコントラクトへの接続情報を設定しています.
他のオブジェクト指向言語と異なるので、少し分かりにくいので説明します.
イーサリアムネットワークに公開されたコントラクトにアクセスするためには2つの情報が必要です.
ABI(Application Binary Interface)とアドレスです.
ABIはメソッドやプロパティなどのインターフェイス情報です.
アドレスはそのコントラクトをネットワーク全体から一意に特定するものです.
同じABIに対して複数の異なるアドレスがありえます.
コントラクトはデプロイ時の1度のみインスタンス化され、そしてデプロイする度に異なるアドレスのインスタンスが生成されるからです.
ABIはオブジェクト指向言語におけるクラス、アドレスはメモリアドレスと考えると分かりやすいです.
以下はC#の例です.
同じクラスに対して異なるメモリアドレス上にある複数のインスタンスがありえます.
var hwA = new HelloWorld();
var hwB = new HelloWorld();
var hwC = new HelloWorld();
Truffleを使ったコンパイルとローカルネットワークへのデプロイの紹介は以上です.