Ethereumテストネットワークで送金してみる
どうも、ぺろりんです。
「はじめてのブロックチェーン・アプリケーション Ethereumによるスマートコントラクト開発入門 (DEV Engineer's Books)」でのお勉強のつづきで、今回はテストネットで送金してみます。
あと、途中で出てきたコマンド(eth.getTransaction)の出力についてちょっと調べています。
前回はアカウントを作ってマイニングしたのでした。
送金は
送金元アカウントのロック解除→送金→マイニング
という手順でやっていきます。
ではやってみましょう。
テストネットでのEthereum送金
送金元アカウントのロック解除
まずはアカウントのロック解除をする必要があります。
アンロックせずに送金コマンドをたたくと、こんな感じで怒られます。
教科書によると、トランザクション発行が有料なので、誤送金を防ぐためデフォルトでは送金できないようにロックされているそうです。
アンロックには「personal.unlockAccount(〈ロック解除したいアカウント〉,〈パスフレーズ〉,〈アンロック有効時間(秒)〉)」コマンドを使います。
引数のパスフレーズとアンロック有効時間は省略可能です。
アンロック有効時間を「0」にするとそのGethプロセス起動中ずっとアンロック状態になります。
たとえば、「アカウント0を100秒アンロックする」という内容をやってみるとこんな感じ。
送金
ロックが解除できたので、「eth.sendTransaction」コマンドで送金してみましょう。
引数は、
from:送金元アドレス
to:送金先アドレス
value:送金額[wei]
を指定します。
アカウント0からアカウント1に10[ETH]送金すると、プロンプトにトランザクションIDか返されます。
送金トランザクションの発効後にマイニングしておらず、まだブロックが生成されていないため、この時点では今しがた送金したトランザクションを含むブロックがありません。
なので、まだ送金が完了しておらず、アカウント1の中身は0のままです。
この状態でさきほど送金時に返ってきたトランザクションIDを入れてトランザクションの内容を確認してみると、実際、ブロック番号(blockNumber)がnullになっています。
マイニング
マイニングしてブロックを生成し、上でやった送金を完了させましょう。
マイニングはminer.start(〈マイニングするスレッド数〉)で始めるのでした。
マイニング開始からしばらくは、「eth.pendingTransactions」で保留中のトランザクションを見てみると先ほど送金しようとしたものが出てきます。
しばらくマイニングを続けながら「eth.pendingTransactions」を連打していると、そのうち結果が空になります。
この時点でマイニングをやめてOKです(やめるのは「miner.stop()」コマンドでした)。
送金確認
先ほど送金したトランザクションIDの内容を見てみましょう。
今度はブロック番号(197)が発番されています。
fromに送金元、toに送金先、valueに10[ETH]=10000000000000000000[wei]が入っています。(r,s,vにつては後述)
一応アカウントのIDを確認しておきましょうか。
「eth.getBlock(〈ブロック番号〉)」で192番のブロックを見てみるとこんな感じです。
miner(マイナー)はcoinbaseアカウントのアカウント0になっていますね。
ちなみにマイニングをやめた時点でのブロック数は209です。
ペンディングが0になってすぐマイニングやめたつもりですが、意外と進行はやいw
興味本位で確認。。
209番目のブロックが今ある最後なので、このブロックには中身がありますが、210番目のブロック内容を見てみるとnullになります。
209番目のブロック内容。
210番目のブロック内容。
eth.getTransactionの出力内容
「eth.getTransaction」コマンドで出力されたパラメータの意味でよくわからないところがあったので、かるく調べてみました。
どこかというと、「r」、「s」、「v」というの。なんだこれ。
調べた結果、どうやらECDSA署名という、トランザクションの署名に使うアルゴリズムで出てくるパラメータのもよう。
ECDSAというのはDSAというアルゴリズムの改良版だそう。
数学的なところを見ると時間がかかりそうなので置いておきます。。
ご興味のある方は、参考に挙げたあたりのURLをたどっていただけるともっと色々書いています。
数学的なところは、ひと通り勉強したらまた戻ってくるかも。
(参考)
・ecrecoverでpublic keyが一意に定まる理由(アルゴリズムとかオーダーとか)
・EthereumのTransactionHashの計算方法(アルゴリズムとかオーダーとか)
・どうしてECDSA署名から公開鍵が復元できるのか?(Develop with pleasure!)
・What does v, r, s in eth_getTransactionByHash mean?(StackExchange)
・ECDSA: (v, r, s), what is v?(StackExchange)
・ECDSA - 用語解説辞典(【公式】NTTPC)
・楕円曲線DSA(Wikipedia)
まとめ
さて、今回はEthereumのテストネットワーク上で送金をしてみました。
今回のポイントは次の2点かなと思います。
(1)はじめにアカウントのロック解除をしないといけない
(2)マイニングしないと送金が完了しない
本を見ながらとかじゃないと1時間くらいハマる自信がある…w
あと、おまけで「eth.getTransaction」コマンドで出力されるr,s,vというパラメータの意味を調べました。
こいつらはECDSAという署名アルゴリズムで計算されるパラメータでしたが今回深くは触れませんw
と、こんな感じの内容でした。
次回は送金手数料の動きを見てみます。
ではでは。
「はじめてのブロックチェーン・アプリケーション Ethereumによるスマートコントラクト開発入門 (DEV Engineer's Books)」でのお勉強のつづきで、今回はテストネットで送金してみます。
あと、途中で出てきたコマンド(eth.getTransaction)の出力についてちょっと調べています。
前回はアカウントを作ってマイニングしたのでした。
送金は
送金元アカウントのロック解除→送金→マイニング
という手順でやっていきます。
ではやってみましょう。
テストネットでのEthereum送金
送金元アカウントのロック解除
まずはアカウントのロック解除をする必要があります。
アンロックせずに送金コマンドをたたくと、こんな感じで怒られます。
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(10, "ether")})
Error: account is locked
at web3.js:3119:20
at web3.js:6023:15
at web3.js:4995:36
at:1:1
教科書によると、トランザクション発行が有料なので、誤送金を防ぐためデフォルトでは送金できないようにロックされているそうです。
アンロックには「personal.unlockAccount(〈ロック解除したいアカウント〉,〈パスフレーズ〉,〈アンロック有効時間(秒)〉)」コマンドを使います。
引数のパスフレーズとアンロック有効時間は省略可能です。
アンロック有効時間を「0」にするとそのGethプロセス起動中ずっとアンロック状態になります。
たとえば、「アカウント0を100秒アンロックする」という内容をやってみるとこんな感じ。
> personal.unlockAccount(eth.accounts[0],"pass0",100)
true
送金
ロックが解除できたので、「eth.sendTransaction」コマンドで送金してみましょう。
引数は、
from:送金元アドレス
to:送金先アドレス
value:送金額[wei]
を指定します。
アカウント0からアカウント1に10[ETH]送金すると、プロンプトにトランザクションIDか返されます。
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(10, "ether")})
"0xc0d2389ef187b3d6b5d88c88f301ab6ccac16a4439d38e4102a8c8c473f316d0"
送金トランザクションの発効後にマイニングしておらず、まだブロックが生成されていないため、この時点では今しがた送金したトランザクションを含むブロックがありません。
なので、まだ送金が完了しておらず、アカウント1の中身は0のままです。
> eth.getBalance(eth.accounts[1])
0
この状態でさきほど送金時に返ってきたトランザクションIDを入れてトランザクションの内容を確認してみると、実際、ブロック番号(blockNumber)がnullになっています。
> eth.getTransaction("0xc0d2389ef187b3d6b5d88c88f301ab6ccac16a4439d38e4102a8c8c473f316d0")
{
blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
blockNumber: null,
from: "0x8ade49123c81461e676fd2f8f2eb31885cdb07e0",
gas: 90000,
gasPrice: 20000000000,
hash: "0xc0d2389ef187b3d6b5d88c88f301ab6ccac16a4439d38e4102a8c8c473f316d0",
input: "0x",
nonce: 0,
r: "0xc0a41f36a050c8ea2e2b2ccd6b85a749b40c1dc375c907340231b16d76b23a7f",
s: "0xa74113934ecf97130083a377728534ec8a1c7917e098f69e6fa8bb082ed7040",
to: "0x3a8e6c0304c761b88feeefb5cdefe27ced28d620",
transactionIndex: null,
v: "0x1c",
value: 10000000000000000000
}
マイニング
マイニングしてブロックを生成し、上でやった送金を完了させましょう。
マイニングはminer.start(〈マイニングするスレッド数〉)で始めるのでした。
> miner.start(1)
true
マイニング開始からしばらくは、「eth.pendingTransactions」で保留中のトランザクションを見てみると先ほど送金しようとしたものが出てきます。
> eth.pendingTransactions
[{
blockHash: null,
blockNumber: null,
from: "0x8ade49123c81461e676fd2f8f2eb31885cdb07e0",
gas: 90000,
gasPrice: 20000000000,
hash: "0xc0d2389ef187b3d6b5d88c88f301ab6ccac16a4439d38e4102a8c8c473f316d0",
input: "0x",
nonce: 0,
r: "0xc0a41f36a050c8ea2e2b2ccd6b85a749b40c1dc375c907340231b16d76b23a7f",
s: "0xa74113934ecf97130083a377728534ec8a1c7917e098f69e6fa8bb082ed7040",
to: "0x3a8e6c0304c761b88feeefb5cdefe27ced28d620",
transactionIndex: null,
v: "0x1c",
value: 10000000000000000000
}]
しばらくマイニングを続けながら「eth.pendingTransactions」を連打していると、そのうち結果が空になります。
この時点でマイニングをやめてOKです(やめるのは「miner.stop()」コマンドでした)。
> eth.pendingTransactions
[]
送金確認
先ほど送金したトランザクションIDの内容を見てみましょう。
今度はブロック番号(197)が発番されています。
> eth.getTransaction("0xc0d2389ef187b3d6b5d88c88f301ab6ccac16a4439d38e4102a8c8c473f316d0")
{
blockHash: "0x3ea566f775e49f4f58c7932713042b511ac60ecb9469b3d0558ab3663723eeba",
blockNumber: 197,
from: "0x8ade49123c81461e676fd2f8f2eb31885cdb07e0",
gas: 90000,
gasPrice: 20000000000,
hash: "0xc0d2389ef187b3d6b5d88c88f301ab6ccac16a4439d38e4102a8c8c473f316d0",
input: "0x",
nonce: 0,
r: "0xc0a41f36a050c8ea2e2b2ccd6b85a749b40c1dc375c907340231b16d76b23a7f",
s: "0xa74113934ecf97130083a377728534ec8a1c7917e098f69e6fa8bb082ed7040",
to: "0x3a8e6c0304c761b88feeefb5cdefe27ced28d620",
transactionIndex: 0,
v: "0x1c",
value: 10000000000000000000
}
fromに送金元、toに送金先、valueに10[ETH]=10000000000000000000[wei]が入っています。(r,s,vにつては後述)
一応アカウントのIDを確認しておきましょうか。
> eth.accounts[0]
"0x8ade49123c81461e676fd2f8f2eb31885cdb07e0"
> eth.accounts[1]
"0x3a8e6c0304c761b88feeefb5cdefe27ced28d620"
「eth.getBlock(〈ブロック番号〉)」で192番のブロックを見てみるとこんな感じです。
eth.getBlock(192)
{
difficulty: 141158,
extraData: "0xd783010505846765746887676f312e362e32856c696e7578",
gasLimit: 111260474,
gasUsed: 0,
hash: "0xbcd39cbb3854b49a2b99d8e00f8d0990637fff7acb3b571bf2092ef80513d768",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x8ade49123c81461e676fd2f8f2eb31885cdb07e0",
mixHash: "0xcddd957dbba5b47b9343e55db72c65880351163733b6fbe86ab5d6c9fd28689f",
nonce: "0x37e12cf34c23c215",
number: 192,
parentHash: "0xee5743b3a3bdfb7c4fff360717ebb32e8a8051971172570c7dcba81da327f2e9",
receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 537,
stateRoot: "0xc7336773e050bc12a068699f4b91cb2f93c6b302664ddf575c70041c774b0af6",
timestamp: 1523976539,
totalDifficulty: 26144279,
transactions: [],
transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
uncles: []
}
miner(マイナー)はcoinbaseアカウントのアカウント0になっていますね。
ちなみにマイニングをやめた時点でのブロック数は209です。
ペンディングが0になってすぐマイニングやめたつもりですが、意外と進行はやいw
> eth.blockNumber
209
興味本位で確認。。
209番目のブロックが今ある最後なので、このブロックには中身がありますが、210番目のブロック内容を見てみるとnullになります。
209番目のブロック内容。
> eth.getBlock(209)
{
difficulty: 141913,
extraData: "0xd783010505846765746887676f312e362e32856c696e7578",
gasLimit: 109427792,
gasUsed: 0,
hash: "0x0cd16490e3ceba375792cffd22f9ed4b4eecd6712485820f47ed04456de0fc66",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x8ade49123c81461e676fd2f8f2eb31885cdb07e0",
mixHash: "0x8ad56f8971fa16c901d3817837e19730f29a675daa38ad87c286cea60e768653",
nonce: "0x24014e4b135603da",
number: 209,
parentHash: "0xc8d6a2fde67cdd873ca2a69c1ee74f2e2b1b2624d4eed144de86499c2da5c47f",
receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 537,
stateRoot: "0xe194838290483fbaae5659796477b4614555d307ccd4ec4b2cae90ccd2aaa566",
timestamp: 1528010828,
totalDifficulty: 28550875,
transactions: [],
transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
uncles: []
}
210番目のブロック内容。
> eth.getBlock(210)
null
eth.getTransactionの出力内容
「eth.getTransaction」コマンドで出力されたパラメータの意味でよくわからないところがあったので、かるく調べてみました。
どこかというと、「r」、「s」、「v」というの。なんだこれ。
調べた結果、どうやらECDSA署名という、トランザクションの署名に使うアルゴリズムで出てくるパラメータのもよう。
ECDSAというのはDSAというアルゴリズムの改良版だそう。
数学的なところを見ると時間がかかりそうなので置いておきます。。
ご興味のある方は、参考に挙げたあたりのURLをたどっていただけるともっと色々書いています。
数学的なところは、ひと通り勉強したらまた戻ってくるかも。
(参考)
・ecrecoverでpublic keyが一意に定まる理由(アルゴリズムとかオーダーとか)
・EthereumのTransactionHashの計算方法(アルゴリズムとかオーダーとか)
・どうしてECDSA署名から公開鍵が復元できるのか?(Develop with pleasure!)
・What does v, r, s in eth_getTransactionByHash mean?(StackExchange)
・ECDSA: (v, r, s), what is v?(StackExchange)
・ECDSA - 用語解説辞典(【公式】NTTPC)
・楕円曲線DSA(Wikipedia)
まとめ
さて、今回はEthereumのテストネットワーク上で送金をしてみました。
今回のポイントは次の2点かなと思います。
(1)はじめにアカウントのロック解除をしないといけない
(2)マイニングしないと送金が完了しない
本を見ながらとかじゃないと1時間くらいハマる自信がある…w
あと、おまけで「eth.getTransaction」コマンドで出力されるr,s,vというパラメータの意味を調べました。
こいつらはECDSAという署名アルゴリズムで計算されるパラメータでしたが今回深くは触れませんw
と、こんな感じの内容でした。
次回は送金手数料の動きを見てみます。
ではでは。