Go Ethereumで遊ぶ(3) 〜送金〜

コラム

前回はアカウントを作成し、マイニングまで行いました。今回は残高の確認から行おうと思います。

口座の確認

まずは口座の確認から行います。前回行ったマイニングでコインベースに設定したアドレスの残高が増えていました。

> eth.getBalance(eth.accounts[0])
80000000000000000000

これですが、単位はETHではなくWeiになっています。Ethereumを使ったことがある方なら送金の際などに見たことがあるかもしれません。

1ETHは10の18乗Weiです。WeiからEtherへの変換にはweb3.fromWei()を利用します。第一引数に変換対象となる値、第二引数に変換したい単位を渡します。第二引数には”ether”だけでなく、1000Weiであるkweiや、10の30乗Weiであるtetherなどetherより大きなものも指定できます。
尚、Weiへ変換するためのweb3.toWei()も用意されています。

> web3.fromWei(1e18, "ether")
"1"
> web3.fromWei(1e3, "kwei")
"1"
> web3.fromWei(1e30, "tether")
"1"
> web3.toWei(1, "kwei")
"1000"

ということでアカウントを第一引数に渡して残高を確認してみましょう。

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

やった。

送金

それでは確認もできたので、送金してみようと思います。
現在アカウントは2つあります。

> eth.accounts
["0xae9abfc6eca2b25d579be8649d4f232f80d3bd46", "0x46c001f57b55abbe9086d595e15cbf7dc3a9b5b2"]

この1つ目のアドレスから2つ目へ10ether送ろうと思います。送金にはeth.sendTransaction()を利用します。今回はfromに送金元アドレス、toに送金先アドレス、valueに送金額を指定します。
送金の際にはアカウントのロックを解除する必要があります。解除せずにeth.sendTransaction()を実行した場合、下記のようなエラーになります。

> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(10, "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

ロックの解除にはpersonal.unlockAccount()を利用します。
パスフレーズは前回personal.newAccount()を使ってアカウントを作成する際に入力したものです。

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

これでロックは解除できているので、先程と同じ送金を行ってみます。

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

今回はエラーが出ませんでした。この返り値は16進数のトランザクションハッシュで、トランザクションが成功したことを意味します。
では残高の確認です。

> eth.getBalance(eth.accounts[1])
0
> eth.getBalance(eth.accounts[0])
80000000000000000000
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
80

変化がありません。トランザクションはブロックに取り込まれて確定します。eth.getTransaction()を使ってトランザクションを確認してみましょう。この際、先程返ってきたトランザクションハッシュを引数として渡します。

> eth.getTransaction("0x29a48a49a140c0774b6876d343dda6df4af71b00bd515e22f6c9c08d1f4a7a00")
{
blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
blockNumber: null,
from: "0xae9abfc6eca2b25d579be8649d4f232f80d3bd46",
gas: 90000,
gasPrice: 1000000000,
hash: "0x29a48a49a140c0774b6876d343dda6df4af71b00bd515e22f6c9c08d1f4a7a00",
input: "0x",
nonce: 0,
r: "0xedda886d6f12d8bbc86608a408c5debe3207448b26a036ca8a463408aa48a8f1",
s: "0x9b82d6da651d0016fc19ba900fe47356905cb8861376e26fad42391bb632e41",
to: "0x46c001f57b55abbe9086d595e15cbf7dc3a9b5b2",
transactionIndex: 0,
v: "0x2e",
value: 10000000000000000000
}

ここで注目したいのはblockNumberのフィールドです。ここはトランザクションが何番目のブロックに取り込まれたのかを示すフィールドですが、Nullになっています。
前回の最後でマイニングを停止したので、このトランザクションはブロックに取り込まれておらず発行しただけになってしまいます。前回と同様にminer.start()でマイニングを開始してブロックに取り込んでみます。

> miner.start(1)
null
> eth.mining
true
> eth.getTransaction("0x29a48a49a140c0774b6876d343dda6df4af71b00bd515e22f6c9c08d1f4a7a00")
{
blockHash: "0x74dfcccd8a18dd661b449d5802bac83113356f7cd8dd598b0d0de191293f79c6",
blockNumber: 17,
from: "0xae9abfc6eca2b25d579be8649d4f232f80d3bd46",
gas: 90000,
gasPrice: 1000000000,
hash: "0x29a48a49a140c0774b6876d343dda6df4af71b00bd515e22f6c9c08d1f4a7a00",
input: "0x",
nonce: 0,
r: "0xedda886d6f12d8bbc86608a408c5debe3207448b26a036ca8a463408aa48a8f1",
s: "0x9b82d6da651d0016fc19ba900fe47356905cb8861376e26fad42391bb632e41",
to: "0x46c001f57b55abbe9086d595e15cbf7dc3a9b5b2",
transactionIndex: 0,
v: "0x2e",
value: 10000000000000000000
}
> miner.stop()
null
> eth.mining
false

blockNumberが17となり、トランザクションが17番目のブロックに取り込まれました。eth.accounts[1]の残高は変わっているでしょうか。

> eth.getBalance(eth.accounts[1])
10000000000000000000
> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
10

指定したとおり、10ETHが送られました。ではeth.accounts[0]はというと、

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

増えてますね。これは、マイニング報酬が加算されたからです。

> eth.blockNumber
19

こんな場合はeth.getTransactionReceipt()を使って実行したトランザクションを確認してみましょう。引数はトランザクションを発行した時の返り値であるトランザクションハッシュです。

> eth.getTransactionReceipt("0x29a48a49a140c0774b6876d343dda6df4af71b00bd515e22f6c9c08d1f4a7a00")
{
blockHash: "0x74dfcccd8a18dd661b449d5802bac83113356f7cd8dd598b0d0de191293f79c6",
blockNumber: 17,
contractAddress: null,
cumulativeGasUsed: 21000,
from: "0xae9abfc6eca2b25d579be8649d4f232f80d3bd46",
gasUsed: 21000,
logs: [],
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
root: "0x26234936f4df6824f9d4815e77c95c6dfd0edd5206be35d0325acc86a4629891",
to: "0x46c001f57b55abbe9086d595e15cbf7dc3a9b5b2",
transactionHash: "0x29a48a49a140c0774b6876d343dda6df4af71b00bd515e22f6c9c08d1f4a7a00",
transactionIndex: 0
}

このレシートではgasUsedフィールドで実際に利用されたガスの値を知ることもできます。

今回はここまでにします。