ERC20準拠のトークン

ERC20準拠のトーク

プロジェクト作成

$ mkdir dapps-token
$ cd dapps-token
$ truffle init

OpenZeppelinのインストール

$ npm init -f
$ npm install zeppelin-solidity

トークコントラクトの作成

デプロイスクリプト

  • migrations/2_deploy_dapps_token.jsファイルを作成

テストコードの作成

  • tests/DappsToken.jsファイルを作成
  • テストを実行
$ truffle develop
truffle(develop)> test
  • migrateコマンドでdevelopネットワークにデプロイし、設定した名前などを確認する
truffle(develop)> migrate
truffle(develop)> dappsToken = DappsToken.at(DappsToken.address)
truffle(develop)> dappsToken.name()
'DappsToken'
truffle(develop)> dappsToken.symbol()
'DTKN'
truffle(develop)> dappsToken.totalSupply()
{ [String: '1000'] s: 1, e: 3, c: [ 1000 ] }

発行量の確認

  • balanceOfコマンドでアカウント別の発行量を確認できる
  • アカウントの1番目は発行者なので、トークンを全額保持している
  • アカウントの2番目は保持量が0になっている
truffle(develop)> dappsToken.balanceOf(web3.eth.accounts[0])
{ [String: '1000'] s: 1, e: 3, c: [ 1000 ] }
truffle(develop)> dappsToken.balanceOf(web3.eth.accounts[1])
{ [String: '0'] s: 1, e: 0, c: [ 0 ] }

送金

  • transferコマンドで送金する
  • 送金完了後に各アカウントが所持するトークン数を確認すると、トークンが正常に動作していることがわかる
truffle(develop)> dappsToken.transfer(web3.eth.accounts[1], 100)
{ tx: '0xf001aa4460728b5b75b96e7afdc72e739d5a53cf71dffc4cb6323b83d1d5b2d0',
  receipt:
   { transactionHash: '0xf001aa4460728b5b75b96e7afdc72e739d5a53cf71dffc4cb6323b83d1d5b2d0',
     transactionIndex: 0,
     blockHash: '0x933600dadc8888729d6d538a27944088e37859b2d931af5f5e1a19a9f15e780f',
     blockNumber: 13,
     gasUsed: 51519,
     cumulativeGasUsed: 51519,
     contractAddress: null,
     logs: [ [Object] ],
     status: '0x01',
     logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000010000008000000000000000000010000000080000000000000000000000000000000000000000000000000000000000000000010000000000000000000010000000000000000000000000000000000000000010000000002000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000010000000000000' },
  logs:
   [ { logIndex: 0,
       transactionIndex: 0,
       transactionHash: '0xf001aa4460728b5b75b96e7afdc72e739d5a53cf71dffc4cb6323b83d1d5b2d0',
       blockHash: '0x933600dadc8888729d6d538a27944088e37859b2d931af5f5e1a19a9f15e780f',
       blockNumber: 13,
       address: '0x345ca3e014aaf5dca488057592ee47305d9b3e10',
       type: 'mined',
       event: 'Transfer',
       args: [Object] } ] }
truffle(develop)> dappsToken.balanceOf(web3.eth.accounts[0])
{ [String: '900'] s: 1, e: 2, c: [ 900 ] }
truffle(develop)> dappsToken.balanceOf(web3.eth.accounts[1])
{ [String: '100'] s: 1, e: 2, c: [ 100 ] }

最後に

こちらにサンプルを置いておきます。

GitHub - akifumi/dapps-token

公式サンプルMetaCoin

MetaCoin

サンプルプロジェクトのダウンロード

  • truffle unboxコマンドを実行することでサンプルを取得できる
$ mkdir metacoin
$ cd metacoin
$ truffle unbox metacoin

コンパイルマイグレーションの実行

$ truffle develop
truffle(develop)> migrate
Using network 'develop'.
Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0xe993a882da8ba0d176a7feffe95e0f5fb2b417d0a8f07320bdfa722004360851
  Migrations: 0x8cdaf0cd259887258bc13a92c0a6da92698644c0
Saving successful migration to network...
  ... 0xd7bc86d31bee32fa3988f1c1eabce403a1b5d570340a3a9cdba53a472ee8c956
Saving artifacts...
Running migration: 2_deploy_contracts.js
  Deploying ConvertLib...
  ... 0xb097805eae8952a028f633d8eb76256fb00782cac3a4989c59615f571f83add8
  ConvertLib: 0x345ca3e014aaf5dca488057592ee47305d9b3e10
  Linking ConvertLib to MetaCoin
  Deploying MetaCoin...
  ... 0x678ce1cfd0903e0fb7ec5d293858c32f428184c18ccaea408e64f20ef1194e82
  MetaCoin: 0xf25186b5081ff5ce73482ad761db0eb0d25abfbf
Saving successful migration to network...
  ... 0x059cf1bbc372b9348ce487de910358801bbbd1c89182853439bec0afaee6c7db
Saving artifacts...
truffle(develop)> m = MetaCoin.at("0xf25186b5081ff5ce73482ad761db0eb0d25abfbf")

MetaCoinコントラクトの参照

  • マイグレーション時に出力されたログのMetaCoin: 0xf25186b5081ff5ce73482ad761db0eb0d25abfbfというところから、MetaCoinのアドレスを取得する
  • at()にMetaCoinのアドレスを渡すことで、MetaCoinのコントラクトを変数として定義できる
truffle(develop)> m = MetaCoin.at("0xf25186b5081ff5ce73482ad761db0eb0d25abfbf")

getBalanceの呼び出し

truffle(develop)> m.getBalance(web3.eth.accounts[0])
{ [String: '10000'] s: 1, e: 4, c: [ 10000 ] }
truffle(develop)> m.getBalance(web3.eth.accounts[1])
{ [String: '0'] s: 1, e: 0, c: [ 0 ] }

sendCoinでコインを送る

truffle(develop)> m.sendCoin(web3.eth.accounts[1], 1000)
{ tx: '0x6b650d826e20aba52c82636f3f2947a263a66714f0684975253527e6f810d1ea',
  receipt:
   { transactionHash: '0x6b650d826e20aba52c82636f3f2947a263a66714f0684975253527e6f810d1ea',
     transactionIndex: 0,
     blockHash: '0xd27c08f5cf5efd1c47ba15b451ac78643dba5af026812de3b77e51eddf038e5a',
     blockNumber: 6,
     gasUsed: 51024,
     cumulativeGasUsed: 51024,
     contractAddress: null,
     logs: [ [Object] ],
     status: '0x01',
     logsBloom: '0x00000000000000000000000000000000010000000000000000000010000000000000000000000020000000000000000000000000000000000000000000000000000000000000000010000008000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000010000000000000000000010000000000000000000000000000000000000000010000000002000000000000000000000000000000000000002000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' },
  logs:
   [ { logIndex: 0,
       transactionIndex: 0,
       transactionHash: '0x6b650d826e20aba52c82636f3f2947a263a66714f0684975253527e6f810d1ea',
       blockHash: '0xd27c08f5cf5efd1c47ba15b451ac78643dba5af026812de3b77e51eddf038e5a',
       blockNumber: 6,
       address: '0xf25186b5081ff5ce73482ad761db0eb0d25abfbf',
       type: 'mined',
       event: 'Transfer',
       args: [Object] } ] }
truffle(develop)> m.getBalance(web3.eth.accounts[0])
{ [String: '9000'] s: 1, e: 3, c: [ 9000 ] }
truffle(develop)> m.getBalance(web3.eth.accounts[1])
{ [String: '1000'] s: 1, e: 3, c: [ 1000 ] }

残高を確認する

truffle(develop)> m.getBalance(web3.eth.accounts[0])
{ [String: '9000'] s: 1, e: 3, c: [ 9000 ] }
truffle(develop)> m.getBalance(web3.eth.accounts[1])
{ [String: '1000'] s: 1, e: 3, c: [ 1000 ] }

失敗するケース

truffle(develop)> m.sendCoin(web3.eth.accounts[1], 10000)
{ tx: '0x175c04f4e568c865ef3735bc5ffd041b8e03b7832889ac4f9b7547cecdc2c3da',
  receipt:
   { transactionHash: '0x175c04f4e568c865ef3735bc5ffd041b8e03b7832889ac4f9b7547cecdc2c3da',
     transactionIndex: 0,
     blockHash: '0x529962199f9efb27c9111da7d4340df033b0eb659cb3a20a5f2949ca57cb7df4',
     blockNumber: 7,
     gasUsed: 23561,
     cumulativeGasUsed: 23561,
     contractAddress: null,
     logs: [],
     status: '0x01',
     logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' },
  logs: [] }
truffle(develop)> m.getBalance(web3.eth.accounts[0])
{ [String: '9000'] s: 1, e: 3, c: [ 9000 ] }
truffle(develop)> m.getBalance(web3.eth.accounts[1])
{ [String: '1000'] s: 1, e: 3, c: [ 1000 ] }
  • logsが空になっている

テストコード

truffle(develop)> test
  • テストを記述しておけば、正常に動作することをチェックできる
  • お金を取り扱うコントラクトを作成するのであれば、十分すぎるほどテストを実行しておくことをおすすめします

Truffleについて

Truffle

Truffle(トリュフ)は、スマートコントラクトの開発に必要となる、コンパイル、リンク、デプロイ、バイナリ管理の機能を持つ統合開発環境フレームワークです。

デプロイやマイグレーションスクリプトで管理することができます。

Solidityを使用したスマートコントラクト開発のデファクトスタンダートになりつつあります。

truffleframework.com

インストール方法

Truffleは、npmでインストールすることができます。

$ npm install -g truffle

プロジェクト作成

$ truffle init

を実行するとプロジェクトを作成することができます。

$ truffle init
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!

Commands:

  Compile:        truffle compile
  Migrate:        truffle migrate
  Test contracts: truffle test

コマンドの実行が完了すると、以下のディレクトリとファイルが作成されます。

名前 説明
contracts/ スマートコントラクトのディレクト
migrations/ スクリプトを記述できるデプロイメントファイルのディレクト
test/ テストファイルのディレクト
truffle-config.js Truffleの設定ファイル
truffle.js Truffleの設定ファイルの雛形

ちなみに、こんな感じのプロジェクトができました。

GitHub - akifumi/truffle-first

Truffle Develop

Truffleには、開発用のブロックチェーンとしてTruffle Developが組み込まれています。

$ truffle develop

で実行することができます。

インタラクティブなプロンプトが表示され、対話式でコマンドを実行することができます。

コントラクトのコンパイル

$ truffle compile

上記のコマンドでソースコードコンパイルできます。

truffle(develop)> compile

Truffle Developからコンパイルすることも可能です。

Truffleはコンパイル時間を短くするため、差分コンパイルが採用されています。

差分コンパイルではなく、全ファイルをコンパイルし直したい場合は、allオプションを付けます。

$ truffle compile --all

マイグレーション

マイグレーションファイルは、イーサリアムネットワークにコントラクトをデプロイする際に使用されます。

プロジェクトに新たなコントラクトを追加する際には、新規でスクリプトを追加します。

実行されたマイグレーションの履歴は、マイグレーションコントラクトによってブロックチェーン上に記録されます。

$ truffle migrate

上記のコマンドでマイグレーションが実行されます。

以前にマイグレーションが正常に実行されている場合、truffle migrateは最後に実行されたマイグレーションから実行を開始し、新たに作成されたマイグレーションのみを実行します。

新たなマイグレーションが存在しない場合は何も実行しません。

マイグレーションを最初から実行したい場合は、resetオプションを付けます。

$ truffle migrate --reset

最後に

Truffleを使って、早速アプリケーションを作成してみましょう!!