イーサリアムにおけるトランザクションとは?
イーサリアムにおけるトランザクションとは、大きく3つの処理のことをいいます。
- ETH通貨の転送
- スマートコントラクトのデプロイ
- スマートコントラクトの関数呼び出し
トランザクションの4つの要素
トランザクションを実施するにあたって、重要な4つの変数があります。
- from : 誰がトランザクションを実施するのか、支払いをするのか。
- to: トランザクションの受信者、もしくは、チェーン上に配置する際はマイナー
- value: トランザクションで転送する価値。ETH通貨。
- data or input: スマートコントラクトの詳細となるデータ。eth通貨を扱う場合は、0
トランザクションにおける主要な参加プレイヤー
- 送信者
- 受信者
- マイナー
トランザクションとブロックの確認作業
これらを見ていくために、helloworldコントラクトをテスト環境上で走らせてみたいと思います。
準備をするには、
Ethereum入門(1) - スマートコントラクトの開発環境を構築する
Ethereum入門(2) - スマートコントラクトでHello world!
Ethereum入門(3) - スマートコントラクト Truffleの使い方
を参考にして、環境を構築してみてください。
まずは、testrpcを起動して、プライベートネットのエミュレータを起動します。
$ export PATH=$PATH:/usr/local/Cellar/node/8.9.1/bin/
$ testrpc
2つ目のコンソールを開いてください。ここでは、geth コンソールを使って、テスト環境用のノードに接続していきます。
$ geth attach http://localhost:8545
にアタッチします。
$ geth attach http://localhost:8545
Welcome to the Geth JavaScript console!
instance: EthereumJS TestRPC/v2.0.0/ethereum-js
coinbase: 0x0eea8963fd6f19ff4299ac9ccb774266a98ba6b1
at block: 0 (Sun, 12 Nov 2017 15:43:25 JST)
modules: eth:1.0 evm:1.0 net:1.0 personal:1.0 rpc:1.0 web3:1.0
ちなみに、coinbase は、accounts[0]のアドレスでした。先程立ち上げたtestrpcのログ上からも確認してみてください。
3つ目のコンソールを開きます。
ここでは、truffleを使って、マイグレーションとデプロイを行います。
$ export PATH=$PATH:/usr/local/Cellar/node/8.9.1/bin/
$ truffle migrate
Using network 'development'.
Running migration: 1_initial_migration.js
Deploying Migrations...
... 0x73151f02e403fc97d10d4778335035e7901e72270753ca7e5575b925386d204e
Migrations: 0x9f79b11e2d75da29cb460ffe20a6d388a0ce0e71
Saving successful migration to network...
... 0xa29e0f5d7471bb32f5d68f075efd73a40b785817106c38cac45593ba0b932a17
Saving artifacts...
Running migration: 2_deploy_contracts.js
Deploying helloworld...
... 0xd59f0a4c159aa2a2058bd7d8dc4b759d1d6474d3f4b85606e3b4a3d00ff73e10
helloworld: 0x362a4c8553e8b970c69e2abce7d3bf25335a5b85
Saving successful migration to network...
... 0xe4a566e516434046a23b80e2bd420cba316fe19d0114a6a63db41e0cbc27ffbf
Saving artifacts...
Hellowroldスマートコントラクトがデプロイされました。ちなみにですが、truffle のパスが自動的に通っているようではないので、コマンドが通らない場合は、PATHをexportしてみてください。
トランザクションを確認する
Block Number 3 つまり、Helloworldコントラクトがデプロイされた際の transaction を見ていきます。(2_deploy_contracts.js をデプロイしたトランザクション)
自分の環境では、このトランザクションのアドレスは、"0xd59f0a4c159aa2a2058bd7d8dc4b759d1d6474d3f4b85606e3b4a3d00ff73e10" でした。
geth コンソールで、eth.getTransaction(<トランザクションのアドレス>) 関数を実施します。
> eth.getTransaction('0xd59f0a4c159aa2a2058bd7d8dc4b759d1d6474d3f4b85606e3b4a3d00ff73e10')
{
blockHash: "0x3584caa04632ce227cf259ab8086d460d497067e666fdf9c5b58756f738ad51c",
blockNumber: 3,
from: "0x0eea8963fd6f19ff4299ac9ccb774266a98ba6b1",
gas: 4600000,
gasPrice: 100000000000,
hash: "0xd59f0a4c159aa2a2058bd7d8dc4b759d1d6474d3f4b85606e3b4a3d00ff73e10",
input: "0x6060604052341561000f57600080fd5b6040805190810160405280600c81526020017f48656c6c6f20576f726c642100000000000000000000000000000000000000008152506000908051906020019061005a929190610060565b50610105565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a157805160ff19168380011785556100cf565b828001600101855582156100cf579182015b828111156100ce5782518255916020019190600101906100b3565b5b5090506100dc91906100e0565b5090565b61010291905b808211156100fe5760008160009055506001016100e6565b5090565b90565b6102e3806101146000396000f30060606040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063d005bb8a14610051578063eaebeb50146100ae575b600080fd5b341561005c57600080fd5b6100ac600480803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190505061013c565b005b34156100b957600080fd5b6100c1610156565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101015780820151818401526020810190506100e6565b50505050905090810190601f16801561012e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b80600090805190602001906101529291906101fe565b5050565b61015e61027e565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156101f45780601f106101c9576101008083540402835291602001916101f4565b820191906000526020600020905b8154815290600101906020018083116101d757829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061023f57805160ff191683800117855561026d565b8280016001018555821561026d579182015b8281111561026c578251825591602001919060010190610251565b5b50905061027a9190610292565b5090565b602060405190810160405280600081525090565b6102b491905b808211156102b0576000816000905550600101610298565b5090565b905600a165627a7a72305820f40c0f74a210ee4da7bf7bc70cef39624ba757a318631509bf1312dbeaa4f6430029",
nonce: 2,
to: "0x0",
transactionIndex: 0,
value: 0
}
このトランザクションの詳細が取得できました。各パラメータを見ていきます。
blockHash
は、トランザクションが含まれているブロックのハッシュです。ブロックチェーン上では、各ブロックは、自分のブロックと、前のブロックのハッシュ値でつながるのでした。
ブロックハッシュの説明
blockNumber
は、ブロック番号です。この場合、このトランザクションが、3つ目のブロックに含まれていることを示しています。
from
は、コントラクトをデプロイした送信者のアドレスです。
gas
は、送信者によって提供されるgasの値です。truffle.js
に記述した値が記載されています。しかし、実際に送信者によって支払われたものではありません。これは、gasの上限値になります。
次に、gas price
は、送信者によって支払われる作業に対する対価で、デフォルト値が設定されています。この値は、マイナーがどのトランザクションを優先するかを決めるために使用されます。よって、gas price
を低く設定しすぎると、トランザクションが実施されないということもあります。いい賃金を払う経営者には、労働者が集まり、そうでないところには労働者が集まらない関係そのものです。このようなところにも、民主主義的なしくみという一端が伺えます。
hash
は、トランザクション自体のハッシュで、ブロックのハッシュとは区別してください。ブロックの中にトランザクションが含まれる関係です。
input
は、バイトコードで出来ていていて、ブロックチェーン上にデプロイしたスマートコントラクトそのものです。
nonce
は、ブロックのnonce
と区別してください。これは、トランザクションのnoce
でトランザクションが起こる度に、1増加します。
このnonce
値よって、次のトランザクションのハッシュ値が変動する仕組みになっています。
to
は、コントラクトの受信者です。スマートコントラクトをデプロイする場合は、受信者が送信者自身となるので、常に0x0となります。
transactionIndex
は、このブロック内のトランザクションのインデックスです。
value
は、トランザクションを実施する際に、送信者が設定した値です。ここでは指定していなかったため、0です。
ブロックを確認する
次に、ブロックを見ていきます。トランザクションにあるblockHashを引数にして、eth.getBlock(<ブロックのアドレス>)関数を使います。
> eth.getBlock('0x3584caa04632ce227cf259ab8086d460d497067e666fdf9c5b58756f738ad51c')
{
difficulty: 0,
extraData: "0x0",
gasLimit: 6712390,
gasUsed: 284220,
hash: "0x3584caa04632ce227cf259ab8086d460d497067e666fdf9c5b58756f738ad51c",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x0000000000000000000000000000000000000000",
nonce: "0x0",
number: 3,
parentHash: "0xe9596012b75cab0b512856a8b297e3f88079bc5798a0e1733db0ba2d0fdda2a8",
receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 1000,
stateRoot: "0x0c079b89eb849c1b654e7287cc7a8525271fd2eb58109a7a8aa6aed04851b362",
timestamp: 1510469942,
totalDifficulty: 0,
transactions: ["0xd59f0a4c159aa2a2058bd7d8dc4b759d1d6474d3f4b85606e3b4a3d00ff73e10"],
transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
uncles: []
}
このパラメータの意味するところを見ていきます。
difficulty
は、このブロックを検証するために使用されます。testrpcでは、常に0に設定されます。
extraData
は、このブロックにリンクされる追加のデータですが、この場合、リンクされたデータはありません。
gasLimit
は、このブロック上で許容される gas の上限値です。
gasUsed
このトランザクションでつかわれたgas の量です。
hash
は、このブロックのハッシュ値です。
logsBloom
は、イベントを格納することに関わるものです。
miner
は、このブロックを発掘したマイナーのアドレスです。testrpc上では、常に0の値となります。
nonce
は、ブロックのnonceです。このnonceは、マイニングを行う際に使用されます。
number
は、ブロックのnumberです。
この3つ目のブロックには、3つのtreeが形成されています。レシートツリーと、トランザクションツリー、ステートツリーです。
3つのツリーのルートハッシュを確認することができます。receiptsRoot
、rstateRoot
、stransactionsRoot
です。
totalDifficulty
は、全体のチェーンの難易度です。ここまで形成されたチェーンのdificultyの合計です。
size
は、ブロックのサイズで、byte単位です。
timestamp
は、ブロックが生成された際のUNIX時間です。
transactions
は、トランザクションの配列です。