ERC20準拠のトークン
ERC20とは、イーサリアム上のトークンを標準化する仕様のことです。
ERC20に準拠するトークンをERC20準拠のトークンと呼びます。
ERC20に準拠することで、異なるトークン同士でのやり取りが簡単になり、ERC20対応のウォレットでの取り扱いが可能となります。
詳しくはこちらを参照してください。
ERC20 Token Standard - The Ethereum Wiki
プロジェクト作成
$ mkdir dapps-token $ cd dapps-token $ truffle init
OpenZeppelinのインストール
OpenZeppelinは、Solidity言語でセキュアにスマートコントラクトを開発できるオープンソースフレームワークです。
$ npm init -f $ npm install zeppelin-solidity
トークンコントラクトの作成
contracts/
にDappsToken.sol
ファイルを作成し、トークンコントラクトの実装を行います。
pragma solidity ^0.4.18; import "zeppelin-solidity/contracts/token/ERC20/StandardToken.sol"; contract DappsToken is StandardToken { string public name = "DappsToken"; string public symbol = "DTKN"; uint public decimals = 18; function DappsToken(uint initialSupply) public { totalSupply_ = initialSupply; balances[msg.sender] = initialSupply; } }
dapps-token/DappsToken.sol at master · akifumi/dapps-token · GitHub
デプロイ時に動作するスクリプトを記述します。
migrations/
に2_deploy_dapps_token.js
ファイルを作成します。
var DappsToken = artifacts.require("./DappsToken.sol"); module.exports = function(deployer) { var initialSupply = 1000; deployer.deploy(DappsToken, initialSupply); };
dapps-token/2_deploy_dapps_token.js at master · akifumi/dapps-token · GitHub
テストコードの作成
tests/
にDappsToken.js
ファイルを作成します。
var DappsToken = artifacts.require("./DappsToken.sol"); contract('DappsToken', function(accounts) { it("should put 1000 DappsToken in the first account", function() { return DappsToken.deployed().then(function(instance) { return instance.balanceOf.call(accounts[0]); }).then(function(balance) { assert.equal(balance.valueOf(), 1000, "1000 wasn't in the first account"); }); }); });
dapps-token/DappsToken.js at master · akifumi/dapps-token · GitHub
テストを実行します。
$ 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 ] }
アカウント別の発行量を確認します。
アカウントの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 ] }
送金してみましょう。
送金完了後に各アカウントが所持するトークン数を確認すると、トークンが正常に動作していることがわかります。
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 ] }