イーサリアムの面白いところは、スマートコントラクトを使い、簡単に自分のトークンを発行できるところだろう。これを利用してICOであったり、CryptoKittiesが作られている。
さて、今回はICOなどにも使われている一番オーソドックスなトークンを発行してみたい。ERC 20という規格の名前のトークンだ。
Truffleを使う
スマートコントラクトの開発環境は様々あるが、Truffleを使うのが便利そうだ。
さて、Truffleをインストールして、プロジェクトを作ってみよう
$ npm install -g truffle
$ truffle init
これで、必要なファイルがいろいろと作られたはずだ。次に必要なnode moduleがあるので、インストールする。
$ npm init -f
$ npm install --save zeppelin-solidity
ERC 20準拠のコードを書く
「 Truffle で始める Ethereum 入門 - ERC20 トークンを作ってみよう 」を参考にしながら、ERC 20準拠のトークンを作っていく(この記事では、KasajeiTokenを作成します!適当に自分の名前を付けて下さい)。まずは、contracts
フォルダの中にKasajeiToken.sol
というファイルを作成すし、以下のように記述する。
pragma solidity ^0.4.18;
import "zeppelin-solidity/contracts/token/StandardToken.sol";
// StandardTokenがERC 20に準拠しているOpenZeppleinのToeken
contract KasajeiToken is StandardToken {
string public name = "KasajeiToken"; // トークンの名前
string public symbol = "KSJT"; // 通貨の単位 BTC / ETHみたいな
uint public decimals = 18;
// 最初の供給量(initialSupply)がコンストラクタの引数になっている
function KasajeiToken(uint initialSupply) public {
totalSupply = initialSupply;
balances[msg.sender] = initialSupply;
}
}
このコードが、スマートコントラクトの実態だ。ここで、コンパイルしてみる。
$ truffle compile
コンパイルが終わると、build/contracts/KasajeiToken.json
というファイルができている。Contract Artifactといい、スマートコントラクトのインターフェースが定義されている。
マイグレーションファイルを作る
次に、このスマートコントラクトをデプロイするための、マイグレーションファイルを作る。先程のスマートコントラクトに、トークンの初期の供給量を与え、コンストラクタを呼び出し、トークンをデプロイする。migrations
フォルダ以下に、2_deploy_kasajei_token.js
を作る。
const KasajeiToken = artifacts.require('./KasajeiToken.sol')
module.exports = (deployer) => {
let initialSupply = 50000e18
deployer.deploy(KasajeiToken, initialSupply)
}
今回は、50,000 KSJT発行しちゃう!これをデプロイすると、デプロイしたアカウントが50,000 KSJT持っている状態になる。
ローカル環境にデプロイ
ローカル環境にデプロイしてみる。
$ truffle develop
Truffle Develop started at http://localhost:9545/
....
truffle(develop)>
これで、ローカル環境にイーサリアムのブロックチェーン環境が実行され、truffleのコンソールに入っている状態になる。さて、デプロイだ!
truffle(develop) > migrate
これで、migrations
のファイルに入っているJSが実行される。実行が上手く行けば、web3.eth.accounts[0]
に50,000 KSJTが発行されている。こちらの記事に従ってコンソールでトークンを移動したりして遊んでみよう。どんな関数が定義されているかはbuild/contracts/KasajeiToken.json
を見ればなんとなくわかる。
あとで使うので、truffleコンソールのweb3.eth.accounts[0]
のアドレスを調べておく。
' truffle(develop) > web3.eth.accounts[0]
0x627306090abab3a6e1400e9345bc60c78a8bef57
Metamaskで遊ぶ
MetamaskをインストールしてETHを送ってみる
さて、WebのUIを作るにはどうすればいいだろうか。それには、Metamaskを使うのが簡単だ。Chromeのextensionになっているので、インストールしよう。そして、ローカルで動いているネットワークに繋げるために、Custom RPCにhttp://localhost:9545
を設定する。
まずは、Metamaskのアカウントに1ETH送ってみる(僕のMetamaskのアドレスは0x97e7320814444F5f5274d78b1Ba1E2df5Ec8680f
だ)。
truffle(develop)>web3.eth.sendTransaction({from:web3.eth.accounts[0], to:"0x97e7320814444F5f5274d78b1Ba1E2df5Ec8680f", value: web3.toWei(1, "ether")})
これで、1ETHがMetamaskのアカウントに入金されているか確認しよう。
MetamaskをインストールしてKSJTを送ってみる
次に、MetamaskのアカウントにKSJTを送ってみよう。まずは、KasajeiToken
のインスタンスを生成し、web3.eth.accounts[0]
のKSJTの所持数を見てみよう。
truffle(develop)> kasajeiToken = KasajeiToken.at(KasajeiToken.address)
truffle(develop)> kasajeiToken.balanceOf(web3.eth.accounts[0])
{ [String: '5e+22'] s: 1, e: 22, c: [ 500000000 ] }
持っていることがわかったので、Metamaskのアカウントへ送金しよう。1000KSJT送金している。
truffle(develop)> kasajeiToken.transfer("0x97e7320814444F5f5274d78b1Ba1E2df5Ec8680f", 1000e18)
これで、metamask側で確認すると、指定したアドレスのアカウントに1000KSJTが付与されている。確認するには、MetamaskのUIからAdd Tokenして、KSJTのアドレスを入力する必要がある。
truffle(develop)> KasajeiToken.address
0x345ca3e014aaf5dca488057592ee47305d9b3e10
やったね!
Webコンソールで遊ぶ
次は、これをWebインターフェースで実装したい。Chromeで適当なページを開き、コンソールを立ち上げて確認していこう。Metamaskがインストールされていると、web3
がインジェクションされている状態になっている。
> web3.eth.accounts[0]
<-"0x97e7320814444f5f5274d78b1ba1e2df5ec8680f"
このような形で、Metamaskに設定されているアカウントが取得できる。
まずは、コントラクトをコンソールで使えるようにする必要がある。必要なのは、コントラクトのアドレス0x345ca3e014aaf5dca488057592ee47305d9b3e10
と、ABIだ。コントラクトのアドレスとABIはtruffleのコンソールで以下のように取得できる。利用するときは、一番外のシングルクオートは外して使う。
truffle(develop)> JSON.stringify(kasajeiToken.abi)
'[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"initialSupply","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]'
コントラクトを生成する。
> var contractAddress = "0x19dcf42be19806076a9f997708d79cae7c6d7954";
> var abiArray = [先程のArray];
> window.web3 = new Web3(web3.currentProvider);
> var contract = web3.eth.contract(abiArray).at(contractAddress);
コントラクトが作れたら、これで送金だ。さて、先程しらべておいたtruffleのweb3.eth.accounts[0]→ 0x627306090abab3a6e1400e9345bc60c78a8bef57
に送金してみる。
>contract.transfer("0x627306090abab3a6e1400e9345bc60c78a8bef57", 1e18, {from: web3.eth.defaultAccount}, function(err, txhash){})
これで、Submitをクリックすると送金できる。Metamaskで確認してみる。
あとは、UIを作ったりすれば良い。Webインターフェースまで作ったコードはgithub.com/kasajei/KSJTokenに公開してある。loz84氏の「Ethereum上のトークンを送金するWebアプリを作ってDecentralizedな方法で公開してみる」を参考に、vue.jsを使って書いてある(ちょっとだけシンプルにした)。
スマートコントラクトおもしろい!!
堅牢なスマートコントラクト開発のためのブロックチェーン[技術]入門
- 作者: 田篭照博
- 出版社/メーカー: 技術評論社
- 発売日: 2017/10/27
- メディア: 大型本
- この商品を含むブログを見る