こんにちは、あんちぽちゃんです。最近は、暗号通貨ハッカーをやってます。今日は、EthereumでHiEtherTokenという名前のトークン(略称HETH
)を作って、パブリックなネットワーク上で実際に送るところまでやってみたいと思います。
この記事はEthereum Advent Calendar 2017の6日目の記事です。
はじめに
Ethereum Advent Calendar 2017の1日目の記事「Ethereum 開発者向けコミュニティを作ったよ」を読んだみなさんは、EthereumのテストネットのひとつRopstenにアカウントを持ち、1ETH以上のEtherを保有していることと思います。「お前は何をいってるんだ???」という方は、すぐに調べてHi-Etherコミュニティにジョインしてください。このビッグウェーブに乗り遅れるな!
さらに、2日目の記事「Truffle で始める Ethereum 入門 - ERC20 トークンを作ってみよう」を読むと、ERC20なる仕様に基づくトークンの作成方法が解説されており、誰でも簡単に自分のトークン、すなわち(流行りさえすれば)通貨足り得るものを作れてしまいます。楽しいですね。
そうなってくると、作ったトークンを自分の手元のパソコン内で送付するのみならず、周囲の人々とやりとりをしたい気持ちになってきますね。そのためには、なにかしらパブリックな場にあるネットワークを使う必要がでてきます。とはいえ、いきなり本番のEthereumネットワーク(mainnet)を使うのはこわいですし、お金もかかりますので、Ropstenというテスト用のネットワークを使ってみましょう。
というわけで、既にアカウントをお持ちのRopstenにERC20トークンをデプロイし、トークンを送付してみます(ローカルネットワークで送付する方法はあちこちで解説されていますが、パブリックなネットワークを使う例が日本語ではあまり見当たらないので、その意味でも役に立ち得るドキュメントであるように思います)。
ネットワークの準備
とはいえ、あれこれ準備するのも面倒ですので、Ethereumのノードをホスティングし、かつ、JSON-RPCやRESTfulなAPIを提供してくれているInfuraというサービスを使いましょう。ローカルでGethなどのクライアントを立ち上げたりする必要もなく、楽にパブリックなネットワーク上でトークンをやりとりできる環境を作れます。便利ですね。
登録画面から適当に登録すると、アクセストークンを入手できます。それを控えておいてください。そのトークンを用いて、以下の用にJSON-RPC APIを叩けます(YOUR ACCESS TOKEN
の箇所を上記で入手したトークンに変更してください)。
$ curl -X POST \
-H "Content-Type: application/json" \
--data '{"jsonrpc": "2.0", "id": 1, "method": "eth_blockNumber", "params": []}' \
"https://mainnet.infura.io/YOUR_ACCESS_TOKEN"
コントラクトのデプロイ
ネットワークの準備が済んだところで、実際に使うERC20トークンのコントラクトを用意する必要があります。とはいえ、ここではとりあえず送ってみたいので、2日目の記事「Truffle で始める Ethereum 入門 - ERC20 トークンを作ってみよう」にあるものをそのまま使います。
pragma solidity ^0.4.18;
import "zeppelin-solidity/contracts/token/StandardToken.sol";
contract HiEtherToken is StandardToken {
string public name = "HiEtherToken";
string public symbol = "HETH";
uint public decimals = 18;
function HiEtherToken(uint initialSupply) public {
totalSupply = initialSupply;
balances[msg.sender] = initialSupply;
}
}
その他、デプロイのために必要なスクリプト等を含め、以下のリポジトリに置いてあります。
セットアップ
まずはセットアップから。git clone
して、npm install
で依存モジュールをインストールします。
$ git clone git@github.com:kentaro/hi-ether-token.git
$ cd hi-ether-token
$ npm install
次に、上記で取得したInfuraのアクセストークンと、1日目の記事Ethereum Advent Calendar 2017の1日目の記事「Ethereum 開発者向けコミュニティを作ったよ」でRopstenのアカウントを作成した際に保存してあるはずのニーモニック(orange apple banana ...
みたいな文字列が書かれたCSVファイルの中身)を、以下のようにして環境変数に設定してください(以下はfishの例。bashなど使ってるひとはexport ...
などと変更してください)。
$ set -x ROPSTEN_MNEMONIC "..."
$ set -x INFURA_ACCESS_TOKEN "..."
truffle.js
の中身
Ethereumのスマートコントラクトの開発には、Truffleというツールチェインを使うのが楽ちんです。Truffleを用いて、かつ、Infuraを利用するために、以下のような設定を用いています。truffle-hdwallet-providerとprovider
パラメータを使っているところがキモですね。
var HDWalletProvider = require("truffle-hdwallet-provider");
var mnemonic = process.env.ROPSTEN_MNEMONIC;
var accessToken = process.env.INFURA_ACCESS_TOKEN;
module.exports = {
networks: {
ropsten: {
provider: function() {
return new HDWalletProvider(
mnemonic,
"https://ropsten.infura.io/" + accessToken
);
},
network_id: 3,
gas: 500000
}
}
};
デプロイ
上述のリポジトリ内に、HiEtherToken.solというコントラクトを用意してあります。さっそくデプロイしてみましょう。
$ node_modules/.bin/truffle migrate --network ropsten
Using network 'ropsten'.
Running migration: 1_initial_migration.js
Replacing Migrations...
... 0xebc162b66af31d4de06b69598d32fc69dc8d48b3dd377ee4e7bc9f52080b8996
Migrations: 0x286712bd51601443b0b200fa0f6f1b21e015b6c6
Saving successful migration to network...
... 0x1ef71b61f82a9255fcfe226d33b014d598124079514f5c55391ae694561fc795
Saving artifacts...
Running migration: 2_deploy_hi_ether_token.js
Deploying HiEtherToken...
... 0xfa27a67c463fc0820934c57775c08a3a8053b85d329bfa8f2af2993aecf2b060
HiEtherToken: 0x99da589b68821d54721fd7db344bf5e7a4ad3af4
Saving successful migration to network...
... 0x90e46b04867f800949031d844845d05575dfeb17bc549f52b2786c3c0284affd
Saving artifacts...
うまくデプロイできたようですね。コントラクトのアドレスは0x99da589b68821d54721fd7db344bf5e7a4ad3af4
のようです。以下のURLから、様子を眺めてみましょう。
(↑はご自身のコントラクトのアドレスを使ってみてください)
ちゃんと、HiEtherTokenという名前のERC20トークンとして認識されているようですね。
トークンの確認
ChromeのMetaMask拡張で、トークンが自分のアドレスに付与されたかを確認してみましょう。
まずは、トークンをMetaMask拡張に登録します。Token Contract Addressは、上記で得られたコントラクトのアドレスを入力してください。その他はスクリーンショットを参照してください。
すると、ちゃんと50,000HETH
が付与されているのが確認できました!我々は通貨を作ってしまった!!!!1
ごく簡単なこととはいえ、ちょっと感動しちゃいますよね〜。
トークンの送付
さて、自分に付与されただけでは物足りないので、ネットワーク経由で、周囲のひとに送ってみましょう。ここでは、同僚の@june29さんのアドレスに送ってみたいと思います。
かっこいいUIなどがあるとよかったのですが、そこまでは作り込めなかったので、プリミティブな方法になりますが、Truffleの提供するコンソールを使ってトークンを送ります。以下のようにして、コンソールを起動してください。
$ node_modules/.bin/truffle console --network ropsten
truffle(ropsten)>
さきほどのコントラクトのアドレスからインスタンスを作ります。
truffle(ropsten)> contract = HiEtherToken.at("0x99da589b68821d54721fd7db344bf5e7a4ad3af4")
TruffleContract {
constructor:
...(省略)...
@june29さんあてにトークンを送ってみましょう。ここでは、1 HETH
を送っています(数十秒ほど時間がかかります)。
truffle(ropsten)> contract.transfer("0xc66d779b340e333ba696b2b3687fb4bca1eb7d0b", 1e18)
{ tx: '0xdaeb44da7d21734f4ab5fe05eec555bb013d7c063436f5a803b41a96fb6f4e65',
receipt:
{ blockHash: '0x49002e7b261e434de410e864a00335c7e61cf3aa517da9a9918f023d688f96a1',
blockNumber: 2204284,
contractAddress: null,
cumulativeGasUsed: 36839,
from: '0x4a736926f8296053024b8949807e1cbb60ae8f95',
gasUsed: 36839,
logs: [ [Object] ],
logsBloom: '0x00000000000000000001000010000000000000400000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000010800000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000008000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000',
status: '0x1',
to: '0x99da589b68821d54721fd7db344bf5e7a4ad3af4',
transactionHash: '0xdaeb44da7d21734f4ab5fe05eec555bb013d7c063436f5a803b41a96fb6f4e65',
transactionIndex: 0 },
logs:
[ { address: '0x99da589b68821d54721fd7db344bf5e7a4ad3af4',
blockNumber: 2204284,
transactionHash: '0xdaeb44da7d21734f4ab5fe05eec555bb013d7c063436f5a803b41a96fb6f4e65',
transactionIndex: 0,
blockHash: '0x49002e7b261e434de410e864a00335c7e61cf3aa517da9a9918f023d688f96a1',
logIndex: 0,
removed: false,
event: 'Transfer',
args: [Object] } ] }
うまくいったようですね。@june29さんのMetaMask上でも、以下の画像の通り、ちゃんとトークンが送付されていることが確認できました(もちろん、Etherscanでも確認できます)。
簡単でしたね!こんな感じで、いろんなひとにトークンを配れば、上述のコンソールを用いて、トークンを受け取った人々もまた、HiEtherTokenを他のひとに配ることができるようになります。これがトークンエコノミーか!!1
おわりに
Ethereum関連の記事を見ると、ERC20トークンやスマートコントラクトの作り方やテストの入門についてはすぐに知れるのですが、実際に作ったものをパブリックなネットワーク上でやりとりするイメージがあまりわかなかったりします。ここでは、テストネットではあるものの、実際にインターネット越しにトークンを送付してみました。そのことで、自分自身、スマートコントラクトをよりリアルな実感をともなって理解できた気がします。
さらに、このコントラクトをブラウザなどから実行するようなWeb UIや、チャットボットなどを作れると、より面白くなるでしょう。それはみなさんの課題としておきましょう。そんなに難しいことでもありません。
(追記:その後、同じくEthereum Advent Calendarにおいて、Web UIについては「Ethereum上のトークンを送金するWebアプリを作ってDecentralizedな方法で公開してみる」が、チャットボットについては私自身による「tiperc20: Slack上でERC20トークンを送りあってコミュニケーション」という記事が書かれています。どうぞご参照ください)
Ethereumなどを始めとするブロックチェーン上でのプログラミングは、今後数年をかけて、インターネットサービスにたずさわるエンジニアの基本的なスキルになっていくと思います(ちょうど、Webの黎明期には珍しかったHTMLが、しばらくすると誰もが扱うものになったように)。みなさんも、もしまだスマートコントラクトを書いたことがないとしたら、この機会にぜひ試してみてください。