【これからイーサリアムを学ぶ人のための教科書#2】イーサリアムの構成要素 アカウント・ステート・ガス

イーサリアム

【これからイーサリアムを学ぶ人のための教科書#2】イーサリアムの構成要素 アカウント・ステート・ガス

2019 年 5 月 - 7 min read

概要

  • 前回のおさらい
  • アカウント
  • アカウントの状態
  • ガス (手数料)

連載「これからイーサリアムを学ぶ人のための教科書」ではこれからイーサリアムに関する情報を追っていくための基礎としてイーサリアムのプロトコルへの本質的な解説をしていきます。この連載を読み、技術レベルでの理解をしていただければ今後のイーサリアムに関する情報にキャッチアップしていくことができます。

前回のおさらい

前回はイーサリアムのイエローペーパーに基づいてブロックチェーンの枠組みを解説し、イーサリアムブロックチェーンのざっくりとしたイメージをつかむことができたと思います。

押さえておくべきポイント以下の通りです。

イーサリアムは

  • トランザクションが実行されることによって現在の状態から次の状態へ移行する
  • 実行されるトランザクションの有効性がマイニングというプロセスによって検証される
  • トランザクション情報のグループであるブロックがチェーンのように連なって続いていく

前回をまだ読んでいない方はこちらから。

今回は少し具体的に上記のプロセスの構成要素にフォーカスして解説していきます。今回も前回同様、技術的に難しいと感じる部分に関しては漠然とした理解で読み進めて問題ありません。 

イーサリアムは大きく以下の要素によって構成されています。

  • アカウント
  • ステート (状態)
  • ガス (手数料)
  • トランザクション
  • ブロック
  • トランザクションの実行 (EVM)
  • マイニング
  • Proof of Work (プルーフオブワーク)

今回はその中の、アカウント・ステート、そしてガスについて解説していきます。

アカウント

イーサリアム上の全体に共有されるステート (状態) はアカウントと呼ばれる要素によって構成されており、アカウント同士はメッセージの送信によって交信することができます。各アカウントはそれぞれのステート (状態) と20バイトのアドレスという160bitの識別名のようなものを持ちます。

アカウントには以下の2種類が存在しています。

  • 外部所有アカウント (externally owned account, 以下EOA)

ユーザーが普段ETHを送信するときなどに使用するアカウントで、秘密鍵によって管理され、スマートコントラクトのコードは持っていません。

  • コントラクトアカウント

スマートコントラクトのコードを持っており、そのコードによって管理される。

EOAとコントラクトアカウントの違い

EOAは、秘密鍵を用いてトランザクションに署名をすることにより、別のEOAやコントラクトアカウントにメッセージを送信することができます。

EOA同士のメッセージ送信は単に送金のような機能です。一方、EOAからコントラクトアカウントへのメッセージの送信は、コントラクトアカウントが持っているコードのプログラムを実行させ、トークンの送金・計算、コントラクトの作成など様々なトランザクションを発生させることができます。

これに対し、コントラクトアカウントはトランザクションを自ら始めることはできず、他のアカウントからメッセージを受け取ることによってのみトランザクションを発生させることができます。このメッセージはEOAとコントラクトアカウントの両方から受け取ることができ、それぞれ以下のような流れとなっています。

このように全てのトランザクションはEOAによって始められます。

アカウントの状態

各アカウントはそれぞれのステート (状態) を持っていると前述しました。このアカウントのステートは以下の4つの要素によって構成されています。

  • ナンス (nonce)

EOAの場合:アカウントが送信したトランザクションの数

コントラクトアカウントの場合:そのアカウントのステートが移行した回数 ≒ 他のアカウントから受け取ったトランザクションを実行した回数

  • バランス (balance)

バランスはそのアカウントが保有するWeiの数を表します。Etherの最小単位で、1Wei = 0.000000000000000001です。

  • ストレージルート (storageRoot)

マークルパトリシアツリー (Merkle Patricia tree) のルートノードのハッシュ値のことを表します。初期状態では空となっています。詳しくは後述します。

  • コードハッシュ (codeHash)

EVM (Ethereum Virtual Machine) コードのハッシュ値のことを表します。コントラクトアカウントの場合、そのコントラクトが持っているコードのハッシュで、EOAの場合、空の文字列のハッシュとなります。詳しくは後述します。

ワールドステート (全体の状態)

ワールドステートはイーサリアム全体のステートであり、それぞれのアカウントがどのような状態であるかを集約した全体の状態です。全てのアカウントの状態を効率的に集約するために、イーサリアムではマークルパトリシアツリー (Markle Patricia tree)と呼ばれるデータ構造が使われています。

まずマークルパトリシアツリーの基礎となるマークルツリーについて説明します。

マークルツリーとは以下の3種類のノードによって構成される二分木 (バイナリーツリー) の一つです。

  • リーフノード:基礎となるデータを保持したノード、画像では1番下のノード。
  • 中間ノード:2つの子ノードをハッシュ化したもの、画像では中間の2層。
  • ルートノード:下層の2つの中間ノードを子ノードとしてハッシュ化したもの

このように、ハッシュ化によって作られる木のような構造のことをマークルツリーと言います。

イーサリアムの場合、マークルツリーを応用したデータの検索挿入コストを減少させたマークルパトリシアツリーというデータ構造が使われていますが、基本的には以上のような理解で問題ありません。(マークルツリーやマークルパトリシアツリーなどのデータ構造に関しては別の機会に詳説します)

実際のイーサリアムのブロックチェーンの構造は以下のようになっています。

このように各ブロックのヘッダーにStateRootとしてワールドステートのハッシュが保存され、ワールドステートのハッシュは各アカウントステートのハッシュから作られます。

このマークルパトリシアツリーというデータ構造が使われているのはステートだけではなく、トランザクションやレシートでも使われており、以下のようにそれぞれがツリー構造を持っています。

こうしたデータ構造を用いることでひとつのアカウントステートが変更されれば最終的にワールドステートも変更されるようになっています。例えば、悪意のあるユーザーが偽物のトランザクションを作成し、リーフノードの部分を書き換えたとします。すると一つ上の層のハッシュが変化し、その上の層のハッシュが変化し、これが続くことによってルートノードの層が変化し、エラーが発生します。

ガス (手数料)

イーサリアムにおいて手数料はとても大切なの概念となっています。イーサリアムネットワークで発生するトランザクションに伴う全ての計算に手数料がかかります。この手数料のことをガスと言います。支払われた手数料はそのトランザクションを承認したマイナーの元へ報酬として送られます。

「Gas」は手数料の単位で、Gas Priceは1Gasにつき払うEtherの量となります。Gas Priceはgweiという単位で計られます。gwei = 1,000,000,000 Weiとなっています。

トランザクションを発生させるたびに送信者はガスリミット (Gas Limit) とガスプライス (Gas Price) を設定します。ガスリミットとガスプライスの積が送信者が支払い可能な最大値となります。

例えば、ある送信者がガスリミット= 50,000、ガスプライス= 20 gwei と設定したとします。 

この場合、送信者は最大

50,000 x 20 gwei = 1,000,000,000,000,000 Wei = 0.001 Ether を手数料として払ってもよいと設定していることになります。

ガスリミットは送信者が払う手数料の最大値なので、必要とされる手数料より多めに設定することができます。この場合、送信者に余った手数料は返金されることになります。

一方、もし送信者がトランザクションを実行するのに十分なガスを設定していなかった場合、トランザクションの途中でガス欠となり、そのトランザクションは無効とみなされ、トランザクション以前の状態に戻ります。そして失敗したトランザクションがどこでガス欠になり無効になったかが記録されます。

ここで注意しなければならないのはガス欠になった場合は、手数料が返金されないということです。この返金されなかった手数料はガス欠になるまでそのトランザクションを承認しようとしたマイナーへ送られます。

マイナーはどのトランザクションを有効化するか選ぶことができるので、ガスを高く設定すればするほどマイナーに選ばれやすくなります。マイナーは自分が有効化するトランザクションの最低手数料を決め、発表することができます。そのため、それを目安に送信者はガスを設定することになります。

ストレージの手数料

ガスはトランザクション承認のための計算以外に、ストレージ利用のためにも支払う必要があります。

ストレージ手数料はトランザクションの手数料とは少し異なり、保存するデータの容量をより小さくするインセンティブが設計されています。ストレージの容量を解放する手続きが含まれたトランザクションの手数料は免除、あるいは報酬を得ることができます。これは、ストレージに保存された容量が増えれば増えるほどノードのデータベースを圧迫してしまうからです。

手数料の目的

イーサリアムネットワークによって実行される全てのオペレーションはノードによるものなので、ネットワークへの過度な負担はネットワークの遅延を引き起こします。手数料は、過度な負担によるネットワークの遅延を防ぐために導入されています。

さらに、イーサリアムはチューリング完全な言語の機械となっています。チューリング完全とは簡単にいうと言語の仕組みによる制限がなく、どんなプログラムでも実行することができる言語です。

チューリング完全な言語は停止性問題という問題を抱えており、ループするプログラムを実行した際に、そのプログラムを永遠に実行し続けるか、停止するのかを決めることができません。

これがイーサリアムネットワークで起こってしまった場合、ネットワークへの多大な負担により、イーサリアムネットワークが崩壊してしまう可能性があります。そのため、計算の度に手数料を課すことでこれを防いでいます。

ここまでがアカウント、ステート、ガスの説明になります。

次回以降は構成要素の残りのトランザクション・ブロック、そしてマイニングについて解説していきます。


参考