truffle console から色々コントラクトを操作したかったんだけど、ネットに転がってる情報とちょっと違っていたのでメモ。Turffle 4.xとちょっと変わったみたいです。
目標
コントラクトアカウントをローカル環境にデプロイし、truffleコンソール上でEOA(外部アカウント)に独自トークンを送金するのを目的とします!
Webフロントエンドの実装やテストネット、メインネットへのデプロイは今回は行いません!またそのうち‥
コントラクトの準備
まずはコントラクトを用意しましょう!
$ npm install -g truffle # まだインストールしていなければ
$ mkdir test-contract
$ cd test-contract
$ truffle init
これでプロジェクトができますね!
今回は送金するので transfer
メソッドが実装されているコントラクトであれば十分です。ただ自分で実装するのは面倒なので、OpenZeppelinを使いERC20に準拠させます。ここの素晴らしい記事を参考にサクっとやりましょう。
OpenZeppelinを導入した上でContractファイルを作っていきます。
$ npm init -y
$ npm install -E openzeppelin-solidity
$ touch contracts/TestContract.sol
TestContract.sol
の中身を編集していきます。ほとんどここのコピペです‥
pragma solidity ^0.5.0;
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol";
contract TestContract is ERC20, ERC20Detailed {
string private _name = "TestContract";
string private _symbol = "TC";
uint8 private _decimals = 18;
address account = msg.sender;
uint value = 100000000000000000000;
constructor() ERC20Detailed( _name, _symbol, _decimals) public {
_mint(account, value);
}
}
OpenZeppelin も 2.0
からは上記のようにimportする内容が細かくなったようです。古い記事のコピペではコンパイルが通らないので注意!
ローカル環境の準備
ローカル環境を整えていきましょう。今回はお手軽にganacheで環境構築していきます。
公式ホームページ からビルド済みのものを取得するか、自前でビルドします。ビルド済みのもので事足りるのですが、今回は自分でビルドしてみます。
# 作業用ディレクトリとは異なる場所で作業すること
$ git clone https://github.com/trufflesuite/ganache.git
$ cd ganache
$ npm install
$ npm start
npm start
でElectronが立ち上がります。
QUICKSTART
を選ぶといくかのEOAのウォレットが生成され、ノードが立ち上がります。ここに先程のContractをデプロイしていきます。
デプロイの準備
truffleの作業環境で今度はデプロイ用のコードを書いていきます。 ./migrations/
にはすでに 1_initial_migration.js
というファイルがあると思いますが、 2_deploy_contract.js
というファイルを新規作成し、以下のように書いてきましょう。
var TestContract = artifacts.require("./TestContract.sol");
module.exports = function(deployer) {
deployer.deploy(TestContract);
};
そして環境設定を行います。 プロジェクトルートのtruffle-config.js
ganacheの情報をもとに編集します。私の手元だと下記のように表示されていました。
したがってtruffle-config.jsの host
, port
, network_id
は以下のようになります。gas
は大きすぎず小さすぎない適当な値を入力します。小さすぎるとコントラクトを実行できず、大きすぎると手持ちのEtherで足りなくなってしまうからです。
module.exports = {
/* 中略 */
networks: {
+ local: {
+ host:"127.0.0.1",
+ port: 7545,
+ network_id: "5777",
+ gas: 2000000
+ }
}
};
デプロイ
そしてコンパイルとマイグレーションを行い、Contractをローカルにデプロイします。
$ truffle compile
$ truffle migrate --network local
デプロイが終わるといくらgasがかかったかが表示されます。
Summary
=======
> Total deployments: 2
> Final cost: 0.0333941 ETH
truffle console での送金
さてここでContractを送金してみましょう。以下のように入力してコンソールに入ります。
$ truffle console --network local
truffle(local)> # 入った
コンソールから出るには .exit
と入力します。
さて、先程のContractのアドレスを調べてみましょう。
truffle(local)> TestContract.address
'0x88E2a079DaCABaB64f6901aF543f052AAf1dB66f'
と出力されますね。では、今回のトークンの総供給量を出してみましょう。
truffle(local)> const tc = await TestContract.at(TestContract.address).then(_ => _)
undefined
truffle(local)> tc.totalSupply().then(ts => ts.toString())
'100000000000000000000'
このあたりが古い記事(Truffle 4.x以前)だと同期処理になっているのを見かけます。 Contract#at()
などはPromiseを返すようになったため、上記のように対応しましょう。
ではいよいよ送金をしてみましょう。Ganacheに表示されている適当なアドレスに送金してみます。 dest
にGanacheに表示されているEOAのアドレスを格納します。
truffle(local)> const dest = "0x163c07CB14603bcBb867f2e95AE2ae965d824ebd"
undefined
truffle(local)> tc.transfer(dest, 10)
{ tx:
'0x282c11cfbeb31df6483e65cfeda8d9d40309af54627ac2cd427ab4c438ebd2c8',
(中略)
from: '0xfdb1c9353c4b325bb3c609bbb70a60fc26eb9c76',
to: '0x88e2a079dacabab64f6901af543f052aaf1db66f',
gasUsed: 51368,
(後略)
トランザクションや送金先アドレス、使用したGasなどが表示されました。ここでは transfer
関数で10トークンを送っています。残高を表示してみましょう。
truffle(local)> const balance = await TestContract.at(TestContract.address).then((address) => address.balanceOf(dest))
truffle(local)> balance.toNumber()
10
これで指定のEOAにトークンが送金されたことがわかります。これで送金は完了です!