はじめに
前回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を作成します。
> personal.newAccount("testA")
"0xd99c842bbee3b3c182b79a2cea50e551d49b85be"
“testA”はパスフレーズで、半角英数記号であれば任意の文字列を設定できます。
実行するとEOAのアドレスが発行されます。
アカウント間で送金させるのでもうひとつアカウントを作成しましょう。
> personal.newAccount("testB")
"0x436e9446d835df3016ba78379f8fe64d5231ceb1"
ノード内で作成されたアカウントは以下のコマンドで確認できます。
> eth.accounts
["0xd99c842bbee3b3c182b79a2cea50e551d49b85be", "0x436e9446d835df3016ba78379f8fe64d5231ceb1"]
配列で渡されるのでインデックスで任意のアドレスを取得することも出来ます。
> eth.accounts[0]
"0xd99c842bbee3b3c182b79a2cea50e551d49b85be"
マイニング
マイニングを行う際に報酬を受け取るアカウント(EOA)を紐付けます。
報酬を受け取るアカウントはEtherbaseと呼びます。
Etherbaseはデフォルトではeth.accounts[0]が設定されています。
以下のコマンドで現在設定されているアカウントを確認することが出来ます。
> eth.coinbase
任意のアドレスを設定する場合は以下のコマンドで変更します。
> miner.setEtherbase(eth.accounts[1])
true
マイニングを始める前に現在の残高を確認しておきます。
> eth.getBalance(eth.accounts[0])
0
それではマイニングを開始しましょう。
マイニングを実行するスレッド数を指定できます。デフォルトだとマシンのコア数が割り当てられます。
> miner.start(1)
null
しばらく待つとマイニングが開始します。
マイニングの様子は、別タブを開いてログファイルを確認して下さい。
$ 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
マイニングが実行されているかどうかは、コンソールで確認することも出来ます。
> eth.mining
true
採掘されたブロック高を確認します。
eth.blockNumber
105
時間が経つにつれてブロック高が更新されていきます。
マイニングの計算力を表すハッシュレートを確認します。
> eth.hashrate
30987
マイニングを停止します。
> miner.stop()
true
停止されていることを確認します。
ハッシュレートは除々に減っていき、暫く経つと0になります。
採掘されたブロック高は、マイニングを停止してもリセットされません。
> eth.mining
false
> eth.blockNumber
107
> eth.hashrate
0
Ether送金
それでは先程作成したアカウント間でEtherを送金してみましょう。
まずは現在の2つのアカウントの残高を確認しておきます。
> eth.getBalance(eth.accounts[0])
535000000000000000000
> eth.getBalance(eth.accounts[1])
0
マイニングの報酬としてeth.accounts[0]は535ether受け取っています。
Etherを送金するには送金元のアカウントのロックを解除します。
その際、パスフレーズを聞かれるので、先程設定した”testA”を入力して下さい。ロック解除が有効な時間は300秒ですので、もし超えてロックがかかってしまったら同じように解除して下さい。
> personal.unlockAccount(eth.accounts[0])
Unlock account 0xd99c842bbee3b3c182b79a2cea50e551d49b85be
Passphrase:
true
eth.accounts[0]からeth.accounts[1]へ10etherを送金するトランザクションを実行します。
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(10, "ether")})
"0x3ef44fabe8761f62567e1fbe7f5dc15d83b02204e4188ce67b1126f69ae02d3e"
するとトランザクションIDが発行されます。
ブロックチェーンでは、生成されたトランザクションがブロックに取り込まれることで処理が実行されます。
発行されたトランザクションIDからトランザクション情報を確認すると、blockNumberで処理されたブロックを確認することが出来ます。
> 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に変換しています。
> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
10
送金成功しました!
実際はトランザクションの処理に手数料がかかりますが、eth.accounts[0]はマイニングの報酬を受け取るため、見た目は手数料を払っていないように見えるので注意して下さい。
今度は、eth.accounts[1]からeth.accounts[0]へ5ether送金してみます。
> 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を使ってコントラクトを実行してみたいと思います。
それでは。