覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

Ethereum - Gethコンソールのコマンドを試す

Gethコンソールのコマンドをいくつか試してみます。

以下エントリの続きという感じになっています。

Gethを起動した状態で以下色々コマンドを実行しています。


ブロック内容の確認

eth.getBlock コマンドでブロックの内容を書くにすることができます。
引数に何番目のブロックを確認したいかのインデックスをしていします。
ブロックは、0→1→2→3... と積み上がっていき、ブロック高と呼ばれることがあります。
ブロック0がgenesisブロックに該当します。

実行例

> eth.getBlock(0)
{
  difficulty: 256,
  extraData: "0x",
  gasLimit: 134217728,
  gasUsed: 0,
  hash: "0x83b885bae699c5650394963ed8927f780cf4fea39b55d3abf430e5a95aa305f3",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0x3333333333333333333333333333333333333333",
  mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  nonce: "0x0000000000000042",
  number: 0,
  parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 507,
  stateRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  timestamp: 0,
  totalDifficulty: 256,
  transactions: [],
  transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
  uncles: []
}

genesisブロックの内容が表示されました


マイニングの開始と確認

miner.start コマンドでブロックを生成する毎に具を開始します。
引数には、マイニング処理を実行するスレッド数を指定します。

実行例

> miner.start(2)
null

nulltrueと表示されれば成功です。
が、いまいち本当に動作しているのかよくわからないので、eth.mining コマンドでマイニング中かどうかを確認します。
trueが表示されれば、マイニング中です。

実行例

> eth.mining
true


コインベースの残高確認

ブロックをマイニングのたびにetherが獲得でき、コインベースカウントの残高が増加していきます。
eth.getBalance コマンドで引数にコインベースアカウントのアドレスを指定します。
コインベースアカウントがaccounts[0]になっている前提で、以下実行しています。

実行例

> eth.getBalance(eth.accounts[0])
2.53e+21

上記の表示結果は単位がweiになっています。
これだとわかりにくい場合は、以下のようにweb3.fromWeiを利用して単位をetherに変換します。

実行例

> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
2725


マイニングの停止

マイニングを終了する場合は、miner.stop コマンドを実行します。trueと表示されればOKです。

> miner.stop()
true


送金

送金を行うためには、eth.sendTransaction コマンドを使用します。from に送金元アドレス、to に送金先アドレス、value に送金額を指定します。
ここでの総金額はweiの単位で指定する必要があり、ether単位の値を指定できないため、web3.toWeiを利用して単位をweiに変換します。
例えば accounts[0]からaccounts[3]に、3ether を送金する場合は以下のようになります

実行例

> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[3], value: web3.toWei(3, "ether")})
Error: authentication needed: password or unlock
    at web3.js:3143:20
    at web3.js:6347:15
    at web3.js:5081:36
    at <anonymous>:1:1

しかし、コマンドの結果はエラーとなり、エラーメッセージが表示されました。
これは誤って送金してしまうのを防ぐために、accounts[0]がロックされているためです。ロックを解除する必要があります。


ロックの解除

ロックの解除には personal.unlockAccount コマンドを実行します。引数にはロック解除対象アカウントのアドレスを指定します。
accounts[0]のロックを解除する場合以下のようになります

実行例

> personal.unlockAccount(eth.accounts[0])
Unlock account 0xf7c80f38982e23707cad8a0ed0f78b0b65c5134e
Passphrase: (ここでアカウント作成時に指定したpasswordを入力します)
true

true と表示されれば、ロックの解除成功です。


アンロックオプション付きの起動

本番環境であれば、アカウントをロックしておくのが望ましいでしょうがプライベートネットでは毎回パスワードを入力して、
ロックを解除するのは面倒なので、以下作業を実施してgeth起動時にアンロックしてしまうようにします。


gethの終了

作業のため一旦exit コマンドでgethを終了します

> exit


アカウントパスワードファイルの作成

password.txt というようなファイル名を作成し、ファイル内に以下のようにacctounts[0]→acctounts[1]→acctounts[2]→acctounts[3]の順に
改行区切りで各アカウントのパスワードを記述して保存します。

password123
password123
password123
password123


アンロックオプション付きでのGethの起動

以下のオプションを加えてGethを起動することで、最初からアカウントのロックを解除した状態にできます。

--unlock {アンロックするアカウントのアドレス} --password {パスワードファイルのパス}

アンロックするアカウントを複数指定する場合は、アドレスをカンマ区切りで指定します。

実行例

$ geth --networkid "10" --nodiscover --datadir /Users/yuki/work/private_eth --rpc --rpcaddr "localhost" --rpcport "8545" --rpccorsdomain "*" --rpcapi "eth,net,web3,personal" --targetgaslimit "20000000" console 2>> /Users/yuki/work/private_eth/error.log --unlock 0xf7c80f38982e23707cad8a0ed0f78b0b65c5134e,0xbaa4290b7c18afe9905060e35b44ddd2a41b34e9,0x559a14163bef0d310f489042707e4c73461e651a,0x0e41e2a7b939ffa1b3d495ab43cda793939e41e5 --password /Users/yuki/work/private_eth/password.txt
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.10-stable/darwin-amd64/go1.10.2
coinbase: 0xf7c80f38982e23707cad8a0ed0f78b0b65c5134e
at block: 697 (Sun, 12 Aug 2018 15:33:13 JST)
 datadir: /Users/yuki/work/private_eth
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0


改めて送金

一度エラーとなった送金処理を、アンロックオプションを指定して起動したGethで再度実施してみます。
(送信先のアカウントの残高を送金前に確認しておきます)

> web3.fromWei(eth.getBalance(eth.accounts[3]), "ether")
0
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[3], value: web3.toWei(3, "ether")})
"0x621ef85ea52fe43b547eea00809d20fced26df7873dc62c8e358fc6ed94a5c58"

トランザクションが成功した場合は16進数のトランザクションハッシュ値が出力されます。(トランザクションハッシュ値は毎回異なります)


トランザクションの確認

発行したトランザクションがどうなっているかを eth.getTransaction コマンドで確認することができます。
引数にはトランザクションハッシュ値を指定します。

実行例

> eth.getTransaction("0x621ef85ea52fe43b547eea00809d20fced26df7873dc62c8e358fc6ed94a5c58")
{
  blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
  blockNumber: null,
  from: "0xf7c80f38982e23707cad8a0ed0f78b0b65c5134e",
  gas: 90000,
  gasPrice: 18000000000,
  hash: "0x621ef85ea52fe43b547eea00809d20fced26df7873dc62c8e358fc6ed94a5c58",
  input: "0x",
  nonce: 0,
  r: "0x50de58e50150a7325321814e09ef129b2bfca265721a077492fdbe485754e356",
  s: "0xfc01614f5150abe37fdeac2f22928dfc4200404f91370e4a4c882b7cb042ee2",
  to: "0x0e41e2a7b939ffa1b3d495ab43cda793939e41e5",
  transactionIndex: 0,
  v: "0xbd",
  value: 3000000000000000000
}

from にaccounts[0]のアドレスが、toにaccounts[3]のアドレスが表示されます。
blockNumber が null になっているので、このトランザクションはまだブロックに取り込まれていないことを意味しています。

ブロックに取り込まれていないトランザクションは確定していないため、送金はまだ完了していません。
この時点での送信先のアカウントの残高を確認してみると以下の通りです。

> web3.fromWei(eth.getBalance(eth.accounts[3]), "ether")
0

トランザクションを確定するためにはブロックを生成し、トランザクションがブロックに取り込まれる必要があります。
そのためにマイニングを再開します。

> miner.start(2)
null


マイニング後のトランザクション確認

一定時間後に改めて対象トランザクションの状態を確認してみます

> eth.getTransaction("0x621ef85ea52fe43b547eea00809d20fced26df7873dc62c8e358fc6ed94a5c58")
{
  blockHash: "0x369003471d86903a6527353318fcedb82ba400a551ceafabcf3c77e36a60c348",
  blockNumber: 698,
  from: "0xf7c80f38982e23707cad8a0ed0f78b0b65c5134e",
  gas: 90000,
  gasPrice: 18000000000,
  hash: "0x621ef85ea52fe43b547eea00809d20fced26df7873dc62c8e358fc6ed94a5c58",
  input: "0x",
  nonce: 0,
  r: "0x50de58e50150a7325321814e09ef129b2bfca265721a077492fdbe485754e356",
  s: "0xfc01614f5150abe37fdeac2f22928dfc4200404f91370e4a4c882b7cb042ee2",
  to: "0x0e41e2a7b939ffa1b3d495ab43cda793939e41e5",
  transactionIndex: 0,
  v: "0xbd",
  value: 3000000000000000000
}

blockNumberにnullではなく数値が設定されています。この例の場合は、698番目のブロックに取り込まれていることを示しています。

この後に、送信先アカウントの残高確認すると予定通り送金が完了していることがわかります。

> web3.fromWei(eth.getBalance(eth.accounts[3]), "ether")
3


トランザクションレシートの確認

トランザクションが実行されるとレシートが発行されます。eth.getTransactionReceipt コマンドで確認できます

> eth.getTransactionReceipt("0x621ef85ea52fe43b547eea00809d20fced26df7873dc62c8e358fc6ed94a5c58")
{
  blockHash: "0x369003471d86903a6527353318fcedb82ba400a551ceafabcf3c77e36a60c348",
  blockNumber: 698,
  contractAddress: null,
  cumulativeGasUsed: 21000,
  from: "0xf7c80f38982e23707cad8a0ed0f78b0b65c5134e",
  gasUsed: 21000,
  logs: [],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  root: "0x0e999db3606fdfdcde919e7b05dde9947e9b7d54a22954d810519d687401f27b",
  to: "0x0e41e2a7b939ffa1b3d495ab43cda793939e41e5",
  transactionHash: "0x621ef85ea52fe43b547eea00809d20fced26df7873dc62c8e358fc6ed94a5c58",
  transactionIndex: 0
}

このレシート上からも、698番目のブロックに取り込まれていることが確認できます。


まとめ

というわけで、Gethでの送金含めたいくつかのコマンドを試してみました。



関連エントリ