目次
はじめに
前回Ethereum用のクライアントであるGethをインストールし、テストネットワークで起動まで行いました。
スマートコントラクト入門(1) ~ローカルにEthereum実行環境を整える~
Ethereum上での取引に使用される暗号通貨をEtherと呼びます。
今回はテストネットワーク上で実際にEtherをマイニングし、アカウント間で送金させてみます。
ちなみにEtherの単位はetherですが、ビットコインにおけるsatoshiと同じく、Etherにも最小単位があります。最小単位はweiと呼び、1etherは10の18乘weiです。
動作環境
- Mac Sierra Version: 10.12.6
- Geth Version: 1.6.7-stable
アカウントの作成
ローカルで起動したテストネットワーク上でアカウントを作成します。
Ethereumには2種類のアカウントがあり、ひとつはEOA(Externally Owned Account)と呼び、もうひとつはContractアカウントです。
EOAはユーザに紐づくアカウントで、送金やコントラクトの実行を任意のタイミングで行います。ContractアカウントはContractそのものに紐づくアカウントであり、内部にコントラクト用のプログラムを持っています。EOAからContractアカウントが呼び出されることでコントラクトが実行されます。
まずはEOAを作成します。
1 2 3 |
> personal.newAccount("testA") "0xd99c842bbee3b3c182b79a2cea50e551d49b85be" |
“testA”はパスフレーズで、半角英数記号であれば任意の文字列を設定できます。
実行するとEOAのアドレスが発行されます。
アカウント間で送金させるのでもうひとつアカウントを作成しましょう。
1 2 3 |
> personal.newAccount("testB") "0x436e9446d835df3016ba78379f8fe64d5231ceb1" |
ノード内で作成されたアカウントは以下のコマンドで確認できます。
1 2 3 |
> eth.accounts ["0xd99c842bbee3b3c182b79a2cea50e551d49b85be", "0x436e9446d835df3016ba78379f8fe64d5231ceb1"] |
配列で渡されるのでインデックスで任意のアドレスを取得することも出来ます。
1 2 3 |
> eth.accounts[0] "0xd99c842bbee3b3c182b79a2cea50e551d49b85be" |
マイニング
マイニングを行う際に報酬を受け取るアカウント(EOA)を紐付けます。
報酬を受け取るアカウントはEtherbaseと呼びます。
Etherbaseはデフォルトではeth.accounts[0]が設定されています。
以下のコマンドで現在設定されているアカウントを確認することが出来ます。
1 2 |
> eth.coinbase |
任意のアドレスを設定する場合は以下のコマンドで変更します。
1 2 3 |
> miner.setEtherbase(eth.accounts[1]) true |
マイニングを始める前に現在の残高を確認しておきます。
1 2 3 |
> eth.getBalance(eth.accounts[0]) 0 |
それではマイニングを開始しましょう。
マイニングを実行するスレッド数を指定できます。デフォルトだとマシンのコア数が割り当てられます。
1 2 3 |
> miner.start(1) null |
しばらく待つとマイニングが開始します。
マイニングの様子は、別タブを開いてログファイルを確認して下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ tail -f ~/ethereum/eth_test/geth.log INFO [09-26|01:55:05] Commit new mining work number=98 txs=0 uncles=0 elapsed=449.54µs INFO [09-26|01:55:05] Generating DAG in progress epoch=1 percentage=66 elapsed=5m21.299s INFO [09-26|01:55:06] Successfully sealed new block number=98 hash=658929…174d80 INFO [09-26|01:55:06] 🔗 block reached canonical chain number=93 hash=5c0b7a…bd9c03 INFO [09-26|01:55:06] 🔨 mined potential block number=98 hash=658929…174d80 INFO [09-26|01:55:06] Commit new mining work number=99 txs=0 uncles=0 elapsed=190.21µs INFO [09-26|01:55:13] Generating DAG in progress epoch=1 percentage=67 elapsed=5m28.660s INFO [09-26|01:55:13] Successfully sealed new block number=99 hash=3628ea…9ad6b8 INFO [09-26|01:55:13] 🔗 block reached canonical chain number=94 hash=9a0e0b…f48c07 INFO [09-26|01:55:13] 🔨 mined potential block number=99 hash=3628ea…9ad6b8 INFO [09-26|01:55:13] Commit new mining work number=100 txs=0 uncles=0 elapsed=232.489µs INFO [09-26|01:55:23] Generating DAG in progress epoch=1 percentage=68 elapsed=5m39.492s INFO [09-26|01:55:23] Successfully sealed new block number=100 hash=52e206…6d2c78 INFO [09-26|01:55:23] 🔗 block reached canonical chain number=95 hash=24b195…1a3738 |
マイニングが実行されているかどうかは、コンソールで確認することも出来ます。
1 2 3 |
> eth.mining true |
採掘されたブロック高を確認します。
1 2 3 |
eth.blockNumber 105 |
時間が経つにつれてブロック高が更新されていきます。
マイニングの計算力を表すハッシュレートを確認します。
1 2 3 |
> eth.hashrate 30987 |
マイニングを停止します。
1 2 3 |
> miner.stop() true |
停止されていることを確認します。
ハッシュレートは除々に減っていき、暫く経つと0になります。
採掘されたブロック高は、マイニングを停止してもリセットされません。
1 2 3 4 5 6 7 |
> eth.mining false > eth.blockNumber 107 > eth.hashrate 0 |
Ether送金
それでは先程作成したアカウント間でEtherを送金してみましょう。
まずは現在の2つのアカウントの残高を確認しておきます。
1 2 3 4 5 |
> eth.getBalance(eth.accounts[0]) 535000000000000000000 > eth.getBalance(eth.accounts[1]) 0 |
マイニングの報酬としてeth.accounts[0]は535ether受け取っています。
Etherを送金するには送金元のアカウントのロックを解除します。
その際、パスフレーズを聞かれるので、先程設定した”testA”を入力して下さい。ロック解除が有効な時間は300秒ですので、もし超えてロックがかかってしまったら同じように解除して下さい。
1 2 3 4 5 |
> personal.unlockAccount(eth.accounts[0]) Unlock account 0xd99c842bbee3b3c182b79a2cea50e551d49b85be Passphrase: true |
eth.accounts[0]からeth.accounts[1]へ10etherを送金するトランザクションを実行します。
1 2 3 |
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(10, "ether")}) "0x3ef44fabe8761f62567e1fbe7f5dc15d83b02204e4188ce67b1126f69ae02d3e" |
するとトランザクションIDが発行されます。
ブロックチェーンでは、生成されたトランザクションがブロックに取り込まれることで処理が実行されます。
発行されたトランザクションIDからトランザクション情報を確認すると、blockNumberで処理されたブロックを確認することが出来ます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
> eth.getTransaction("0x3ef44fabe8761f62567e1fbe7f5dc15d83b02204e4188ce67b1126f69ae02d3e") { blockHash: "0x653dd9f1c653eebcb99cc6871f39f0ac807f7a9907d9c3482546bf503ebab996", blockNumber: 108, from: "0xd99c842bbee3b3c182b79a2cea50e551d49b85be", gas: 90000, gasPrice: 18000000000, hash: "0x3ef44fabe8761f62567e1fbe7f5dc15d83b02204e4188ce67b1126f69ae02d3e", input: "0x", nonce: 0, r: "0x82ef57e981c06ec8dbec3b721d0283eb3a38e98f637da704bc83c6a408e269e8", s: "0x31d788e298dc947e338834235e86defa9057548395cff5d35e30fffca36e9c6a", to: "0x436e9446d835df3016ba78379f8fe64d5231ceb1", transactionIndex: 0, v: "0x7f3", value: 10000000000000000000 } |
eth.accounts[1]の残高を確認しましょう。
getBalanceメソッドではweiで値が返されるので、etherに変換しています。
1 2 3 |
> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether") 10 |
送金成功しました!
実際はトランザクションの処理に手数料がかかりますが、eth.accounts[0]はマイニングの報酬を受け取るため、見た目は手数料を払っていないように見えるので注意して下さい。
今度は、eth.accounts[1]からeth.accounts[0]へ5ether送金してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
> personal.unlockAccount(eth.accounts[1]) Unlock account 0x436e9446d835df3016ba78379f8fe64d5231ceb1 Passphrase: true > eth.sendTransaction({from: eth.accounts[1], to: eth.accounts[0], value: web3.toWei(5, "ether")}) "0xd80275fc933916829aa225a2c92b1392b59003a79172230c1d0fa1941162539c" > eth.getTransaction("0xd80275fc933916829aa225a2c92b1392b59003a79172230c1d0fa1941162539c") { blockHash: "0xc41c59954e342154fe8da47448c7223fac01350163bebe341e7323d9e1951198", blockNumber: 151, from: "0x436e9446d835df3016ba78379f8fe64d5231ceb1", gas: 90000, gasPrice: 18000000000, hash: "0xd80275fc933916829aa225a2c92b1392b59003a79172230c1d0fa1941162539c", input: "0x", nonce: 0, r: "0xce386e284357619d49d8b8ca82a1e3ff79f633e9f7d8764958dece5afc0cce94", s: "0x1ba213b58b2941341ee30f729b9104921ab1d9fe15bc605d53c4695e2c173dca", to: "0xd99c842bbee3b3c182b79a2cea50e551d49b85be", transactionIndex: 0, v: "0x7f4", value: 5000000000000000000 } > eth.getBalance(eth.accounts[1]) 4999622000000000000 |
手数料が支払われていることがわかります。
最後に
今回はローカルで起動したテストネットワーク上で、アカウントの作成からEtherの送金まで行いました。
Ethereumはビットコインとは違って通貨としての利用が目的ではなく、スマートコントラクトを実行するためのプラットフォームです。コントラクトを実行するための燃料としてEtherという仮想通貨が実装されており、そのEtherを擬似的な通貨として取引に使うことが出来ます。
次回以降は実際にマイニングしたEtherを使ってコントラクトを実行してみたいと思います。
それでは。