Ethereumテストネット上でクラウドセール(Crowdsale)を開催する

Ethereum(イーサリアム)

前回作成したCrowdsaleのコントラクトを今度は、Ethereumのテストネットにつないで、実験的にCrowdsaleを運用してみることにしました。
truffleの設定ファイルであるtruffle.jsを変更してtestnetに繋ぐようにします。mainnet(本当のEthereumのネットワーク)にもこの設定ファイルを変更することによって繋ぐことができます。

Ethereumのテストネットワークには3種類以下があります。

https://testnet.etherscan.io/

ROPSTEN (Revived) – Proof Of Work
KOVAN – Proof Of Authority (Parity only)
RINKEBY – Clique Consensus (Geth only)

今回は上記のROPSTENを使います。テストネットワークで試すときはROPSTENことが多いようです。

また、testnetに繋げる方法は以下の方法があります。

1. 自分のノードを立ち上げてネットワークに繋げる
2. InfuraというEthereumのノードホスティングを行なっているサービスを使う

truffeのページでもInfuraを紹介していたので今回は2番でやろうと思ったんですが、Infuraは秘密鍵を使うようなコマンド(たとえばsendTransaction)がtruffle consoleからできないので断念しました。
使えるRPCメソッドは以下を参考にしてください。
https://infura.io/docs/#supported-json-rpc-methods

よって、1番のgethでtestnetworkに繋いで試して見たいと思います。

Sponsored Link


testnet環境の準備

今回は gethのコンテナとtruffleが動くコンテナを分けて環境構築します。gethのバージョンは1.7.2を使用しています。

docker-composeの修正

gethのコンテナイメージを新たに作るようにdocker-composeファイルを修正しています。

gethのDockerfileは以下です。

gethのコンテナイメージ作成時に、時間をあわせるためにtzdataを使っています。コンテナ間で時間がずれるとクラウドセールが開始されているはずなのに、送金できないなどの問題がでるので気をつけてください。

truffle.jsの修正

fromの箇所にあとで作成するアカウントの最初に作成した方のアドレスを入れます。
networkidを3に指定することによりtestnetにつなげます。hostはdocker-composerで指定している名前の”gath”を指定しています。

migrationの修正

以下startTimeをハードコーディングします。自分の環境ではweb3.eth.getBlockがあるとdeployできなかったためです。
テーミナルなどで date -d “2017-11-6 23:35” +%s などと打てばunixtimestampを表示してくれます。

module.exports = function(deployer, network, accounts) {
  // const startTime = web3.eth.getBlock(web3.eth.blockNumber).timestamp + 1 // one second in the future
  // date -d "2017-11-7 23:40" +%s
  const startTime = 1510065600
  :

クラウドセール開催

事前準備

DAGファイル対応

gethは初めて起動するとDAGファイル(asic対策用のファイル)がまだ作成されていないので、一度gethコンテナを立ち上げてminerを動かしてDAGファイルを作成します。また、testnetの他のノードと同期を始めます。

$ docker-compose up -d geth

別のターミナルでattachをしてアカウントを2つ(オーナーと、コイン送付先)を作っておきます。その後、マイニングを開始(miner.start)するとDAGファイルが作成しはじめます。

$ docker exec -it geth
# geth attach rpc:http://localhost:8545
> personal.newAccount("XXX")
> personal.newAccount("XXX")
> miner.start(1)

Ether準備

5分〜10分程度したら最初に作成したアカウントにEtherが溜まっているので、sendTransactionで2つ目のアカウントにEtherを送金しておきます。

> personal.unlockAccount(eth.accounts[0], "XXX")
> personal.unlockAccount(eth.accounts[1], "XXX")
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(5, "ether")})

minerは停止せずそのままにしておきます。

クラウドセール開催

準備が整ったところで、いよいよコントラクトをdeployしてクラウドセールを開催します。

まずtruffleが起動するコンテナを立ち上げて、コンテナに入ります。

$ docker-compose up -d ico
# docker exec -it ico

ソースをコンパイルして

# cd /ico
# truffle compile
Compiling ./contracts/Migrations.sol...
Compiling ./contracts/WakuWakuCoin.sol...
Compiling ./contracts/WakuWakuCoinCrowdsale.sol...
Compiling zeppelin-solidity/contracts/crowdsale/Crowdsale.sol...
Compiling zeppelin-solidity/contracts/math/SafeMath.sol...
Compiling zeppelin-solidity/contracts/ownership/Ownable.sol...
Compiling zeppelin-solidity/contracts/token/BasicToken.sol...
Compiling zeppelin-solidity/contracts/token/ERC20.sol...
Compiling zeppelin-solidity/contracts/token/ERC20Basic.sol...
Compiling zeppelin-solidity/contracts/token/MintableToken.sol...
Compiling zeppelin-solidity/contracts/token/StandardToken.sol...
Writing artifacts to ./build/contracts

前回と同様migrateするのですが別ターミナルでattchしているgethコンソール上でアカウントロックを外しておきます。
(geth起動時にアカウントロック外せるのですが、今回は都度外しています)

> personal.unlockAccount(eth.accounts[0], "XXX")
> personal.unlockAccount(eth.accounts[1], "XXX")

truffle.jsのstartTimeとendTimeを適宜修正して、その後migrate。
このとき、アカウントロックが外れてないとmigrateできないので注意してください。

# truffle migrate --network testnet

その後は前回と同様に、以下コマンドを打っていき送金できることを確認します。

> account1 = web3.eth.accounts[1]
'0x70b2711d29dd72b0e058f6b6909aae540096fb2c'
> WakuWakuCoinCrowdsale.deployed().then(inst => { crowdsale = inst })
undefined
> crowdsale.token().then(addr => { tokenAddress = addr } )
undefined
> tokenAddress
'0x6fcbb923d9be7935b6ebef70d3dab5eac9572d12'
> wakuwakuCoinInstance = WakuWakuCoin.at(tokenAddress)
TruffleContract {
  constructor:
  :
  :
> wakuwakuCoinInstance.balanceOf(account1).then(balance => balance.toString(10))
'0'
> WakuWakuCoinCrowdsale.deployed().then(inst => inst.sendTransaction({ from: account1, value: web3.toWei(5, "ether")}))
{ tx: '0x940917e32df0dca4bc48ce52dbcadb39da2d33bfec7fb1e660dbf36fc053a55c',
 :
 :
> wakuwakuCoinInstance.balanceOf(account1).then(balance => account1GusTokenBalance = balance.toString(10))
'5000000000000000000000'

まとめ

今回はローカル環境でgethとtruffleの連携してクラウドセールを開催する方法のような記事になってしまいましたが、このあとテストネットへの反映の確認等はまた別途機会があれば描きたいと思います。

今回記事中では触れておりませんが、コンテナ間の時刻がずれて送金できなかったりや、
“Error: Insufficient funds for gas * price + value”
という色々な原因を示すエラーだったりとかかなりはまりました。もう少しエラーの内容をわかりやすく出して欲しいですね、、、本当にわかりずらい。

Ethereum開発時にいろいろはまるポイント列挙

にはまるポイントをメモで残していきます。

また、Infuraで途中までプログラムを書いていたんですが、sendTransactionがInfuraだとtruffleコンソール上からできないことに途中で気づいたときは結構な精神的ダメージをくらったのですが、なんとかgethでtestnetつなげてクラウドセール動いてよかったよかった。
Infuraの使いどころも一度まとめて記事にしたいと思います。

今回のソースは以下にあげております。

https://github.com/todoroki-yudai/zeppelin-crowdsale-sample

Sponsored Link

ビットコイン(Bitcoin)、イーサリアム(Ethereum)、リップル(Ripple)、ネム(NEM)などの仮想通貨を買うならコインチェックがおすすめです。

※アプリは指値売買ができず手数料が高いので、アプリをダウンロードするのではなくメール&パスワード登録へ!まずは5万円ほど入金して仮想通貨とブロックチェーンの世界を楽しんでください!

ビットコイン取引高日本一の仮想通貨取引所 coincheck bitcoin

コメントはまだありません

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


NEM
秘密鍵からnanoWalletにアカウント情報をインポートする方法

NEMの開発をしていて、NEMのAPIを使って作成したアドレスの内容をnanoWalletで参照した …

miningpoolhub
miningpoolhubのAPIを使って自動スイッチングを試してみる in ethOS

* アイキャッチの男性は、Flicker上のライセンスフリーの画像ひっぱってきているだけで、本文とま …

ICO
感動を可視化するOKWaveのWowoo!

最近よく思うことがあって、些細な感謝をお金に還元できたらなぁと思うことがあるんです。 感謝すればお金 …