Ethereumを送金してみた

拝啓
先日立ち寄った和食屋さんでもビットコインやイーサリアムといった単語を耳にしました
この手の話を得意げに披露される方は往往にして声が大きいのは何故なのか不思議ですが
声を大にして今が仮想通貨のチャンスと仰っている方々はさておき
ブロックチェーンテクノロジーの本質を見誤ることのないようご自愛ください
敬具

前回、やっとでプライベートネットワークでの採掘に成功して達成感とぬか喜びに浸った非プログラマーが挑むブロックチェーンシリーズ。
ようやく採掘したEthereum、今回はいよいよ使ってみるというか送金処理に挑戦です。
あくまでプライベートネットワークでの採掘&送金なので実際のEthereumとは全く連動しませんが、それでも採掘したEthを時価換算すると結構な金額になったりして、金額に比例して虚しさも大きくなる感じで幕を開けます。


1. まずは現状の確認から
さて、そんな六本木界隈で見かける虚しさはさておいて、いつものGethを起動します。
ようやく最近になって、Consoleで上下キーを押すと今までのコマンド履歴が出てくることを学びました。

geth --networkid "8888" --nodiscover --datadir "/Users/me/eth" console 2>> /Users/me/eth/geth_err.log

起動したらまず、今の時点でテスト用に作成した2つのアカウントそれぞれにどれくらいEthが貯まっているのかを見てみます。
ついつい貯まるという漢字を使うあたり、西の方の金融道を彷彿します。

eth.getBalance(eth.accounts[0])
1.0895e+22

eth.getBalance(eth.accounts[1])
0

今までEthereumのcoinbase(口座)はずっとaccounts[0]の方にしてあったので、当然[1]の方はノーマネーでフィニッシュでした。
余談ですがわたくし、虎の出演経験ありまして、収録上はななhy

さて。
1.0895e+22という文字列ではいまいちマネーの実感が湧かないので、これをfromWei関数でEth単位に変換してみます。

web3.fromWei(eth.getBalance(eth.accounts[0]), 'ether')
17265
web3.fromWei(eth.getBalance(eth.accounts[1]), 'ether')
0

accounts[1]は当然ノーマネーですが、accounts[0]には17,265Ethが採掘されていました。
2018年2月14日現在の価格がざっくり1eth = 90,000JPYなので、1553,850,000円(税抜)ほど。
じゅうごおく・・・あと20億足して35億って言いたくなったけど、いつか見返して赤面するのは目に見えています。
念のためさらなる資金調達を行うべく、マイニングをちょっとやってみました。

miner.start()
null

miner.stop()
true

この間別タブでtailコマンドでログを見て、マイニングを確認します。
相変わらずnullが返ってくるけど、マイニングも動いていました。

2. 未知なる送金
それでは送金処理です。
送金処理を行うには以下の条件がありました。

  • 送金元のアカウントのロックを解除すること
  • 受け取る側のアカウントもロックを解除すること
  • マイニング処理を実行していること

そこでまずunlockAccount関数でロックを解除します。
Passphraseと聞かれたらパスワードを入力しますが、HTMLのフォームと違って表示されないので、キーボードをよく見てカチコチします。

personal.unlockAccount(eth.accounts[0])
Unlock account 0xaf6d968b9f076f3f47061af7add356d52ec85fac
Passphrase: 
true

続けて受け取る側もロック解除。

personal.unlockAccount(eth.accounts[1])
Unlock account 0x03e5f8ca8bbaf6762c0340ec058bd3ebaab40e11
Passphrase: 
true

これで準備が整いました。
ほんとはeth.accountsをwth.accountsと間違えたりして何度かエラーが出たんですが、ただのタイプミスあたかもスムーズに進行している感じで進めていきます。

送金処理はsendTransaction関数で行います。
fromとtoと、valueによっていくら送金するか指定してEnterでOKです。
送金する値はtoWei関数を使い、単位をetherと指定して行いました。
10ethの送金、今日時点ならこれだけで900,000円(税抜)くらいです。

eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(10, "ether")})
"0xbf2780a3f814ef11d4c23fb0e4bdfc8aa51244656c6a93b1d5c17af8053a8ef6"

これはほんとにちょっとビックリしたんですが、予想以上に早く終わりました。
次の行に表示されているのがトランザクションID、送金の記録のIDです。
ところが今はマイニングを実行していません。
この状態だとトランザクションはペンディングされ、次回マイニング実行時に実際に送金処理が行われます。
pendingTransactions関数でペンディング中の送金の内容をちらっと見てみます。

eth.pendingTransactions
[{
    blockHash: null,
    blockNumber: null,
    from: "0xaf6d968b9f076f3f47061af7add356d52ec85fac",
    gas: 90000,
    gasPrice: 18000000000,
    hash: "0xbf2780a3f814ef11d4c23fb0e4bdfc8aa51244656c6a93b1d5c17af8053a8ef6",
    input: "0x",
    nonce: 0,
    r: "0x66d77373bc0867e9254e415df8b4d030705fb7f39cad18cc6f675ee168c3b916",
    s: "0x67d386fb5ee3fa589521517efd7c1c6f11c30be9aff767a6b0713ce6c898e8d",
    to: "0x03e5f8ca8bbaf6762c0340ec058bd3ebaab40e11",
    transactionIndex: 0,
    v: "0x4593",
    value: 10000000000000000000
}]

・・・なんかよく分からないけど、とりあえずマイニングして送金してしまいます。

miner.start()
null
miner.stop()
true

ログを見てみるとちゃんとトランザクションが送信されています。

INFO [02-13|22:55:47] Submitted transaction  fullhash=0xbf2780a3f814ef11d4c23fb0e4bdfc8aa51244656c6a93b1d5c17af8053a8ef6  recipient=0x03e5f8ca8BBaf6762c0340ec058bd3EBAaB40E11

もう一度ペンディング中のトランザクションを確認。

eth.pendingTransactions
[]

空っぽになっているので、送った先のaccounts[1]の残高を確認します。

eth.getBalance(eth.accounts[1])
10000000000000000000

?!!・・・!!
なんだこの読めないくらいの桁数!
数えて見たら1,000京・・・ってそういえばこれは、Weiの単位で表示されるんでした。
1ethは10の18乗なので(この辺は宇宙論で慣れてる)fromWei関数でEthに換算してみます。

web3.fromWei(eth.getBalance(eth.accounts[1]), 'ether')
10

と、ちゃんと10eth(こう見えて900,000円)になっていました。

3. 返送品は伊勢丹で
ここまでで送金は確認できたので、今度は逆にaccounts[1]から[0]にお礼の送金をしてみます。
もう一度アカウントのロック(デフォルトの場合300秒で自動的にロックされる)を解除して・・・

personal.unlockAccount(eth.accounts[0])
Unlock account 0xaf6d968b9f076f3f47061af7add356d52ec85fac
Passphrase: 
true

personal.unlockAccount(eth.accounts[1])
Unlock account 0x03e5f8ca8bbaf6762c0340ec058bd3ebaab40e11
Passphrase: 
true

お返しなので3th(とはいえ270,000円)だけ送金します。

eth.sendTransaction({from: eth.accounts[1], to: eth.accounts[0], value: web3.toWei(3, 'ether')})
"0x414163ccd1b7d8da3ef5cc95fa5d0414a8f012b1818dcd81287842810a95fcc2"

ペンディングのトランザクションを確認して・・・

eth.pendingTransactions
[{
    blockHash: null,
    blockNumber: null,
    from: "0x03e5f8ca8bbaf6762c0340ec058bd3ebaab40e11",
    gas: 90000,
    gasPrice: 18000000000,
    hash: "0x414163ccd1b7d8da3ef5cc95fa5d0414a8f012b1818dcd81287842810a95fcc2",
    input: "0x",
    nonce: 0,
    r: "0x787c5620762cdefe6e504d2d37b041fd416e3509f5c76a6de0477010b7613ac5",
    s: "0x5f31afc22088ae671793349f570ad8bf79d48a757453c7798d09784dda9d3db",
    to: "0xaf6d968b9f076f3f47061af7add356d52ec85fac",
    transactionIndex: 0,
    v: "0x4593",
    value: 3000000000000000000
}]

マイニング開始!

miner.start()
null
INFO [02-13|23:00:58] Submitted transaction  fullhash=0x414163ccd1b7d8da3ef5cc95fa5d0414a8f012b1818dcd81287842810a95fcc2  recipient=0xAF6d968b9F076f3f47061Af7ADD356d52eC85FaC
miner.stop()
true

先ほどと同じ手順でペンディングを確認してから、送金元accounts[1]の残高を確認します。

eth.pendingTransactions
[]
> web3.fromWei(eth.getBalance(eth.accounts[1]), 'ether')
6.999622

10引く3は7、かと思いきや0.000378足りません。
これが今回のポイントになるのですが、その前にトランザクションの中身を確認してみました。
getTransaction関数にトランザクションIDを渡してやると・・・

eth.getTransaction('0x414163ccd1b7d8da3ef5cc95fa5d0414a8f012b1818dcd81287842810a95fcc2')
{
  blockHash: "0x21c717114d53092611b810113193f825cd8dc9676c6f83a2dccd84da16d489c8",
  blockNumber: 3483,
  from: "0x03e5f8ca8bbaf6762c0340ec058bd3ebaab40e11",
  gas: 90000,
  gasPrice: 18000000000,
  hash: "0x414163ccd1b7d8da3ef5cc95fa5d0414a8f012b1818dcd81287842810a95fcc2",
  input: "0x",
  nonce: 0,
  r: "0x787c5620762cdefe6e504d2d37b041fd416e3509f5c76a6de0477010b7613ac5",
  s: "0x5f31afc22088ae671793349f570ad8bf79d48a757453c7798d09784dda9d3db",
  to: "0xaf6d968b9f076f3f47061af7add356d52ec85fac",
  transactionIndex: 0,
  v: "0x4593",
  value: 3000000000000000000
}

うん、これもイマイチ分からないところがありますが、でもこれこそがブロックチェーンによって繋がって、承認不要の価値を担保するとても重要な情報の中身なのです。

ここで、上記のポイントがハッキリと出てきました。
GASです。

4. ガス発電でエコライフ
いつもならここでお風呂を沸かしてとかボケるところですが、GASはなかなか重要な考え方なので、次回まとめたいと思います。

<続く>