開発者によるWeb3の再学習「イーサリアムとは何か?」
「イーサリアムとは何か?」全体像は曖昧なままWeb3系のアプリを作成している人も多いかと思います。本格的にWeb3業界に足を踏み入れ、独自ブロックチェーンを作りたくなったので、再学習ということで、「マスタリング・イーサリアム スマートコントラクトとDAppの構築」を元に、ブロックチェーン、特にイーサリアムに関して、徹底的に再学習します。
目次
自己紹介と「開発者によるWeb3の再学習」シリーズの説明!
初めてWeb3に触れたのは2019年ごろでした。
カナダに留学していた頃、突然?Udemyでブロックチェーンの動画がおすすめに現れました。その直後、友人にブロックチェーンという面白い技術があることを聞き、最近よく聞く単語「ブロックチェーン」に興味を持ちたました。つまり偶然ですね。
当時はビットコインという言葉は聞いたことがありましたが、それが何なのか全く知りませんでした。一時期価値が急上昇していましたが、そのことも知らず、私が初めて触れたのは、底値くらいに落ち込んでいた時期でした。
最初はクリプトゾンビというイーサリアムで使用されているSolidityというプログラム言語の学習サービスを実践したり、クリプトキティーズのソースコードを読んで学習したりしました。
その後はスマートコントラクト上でCryptoKoiという鯉の柄や形、サイズなどを生成するゲームを作成しました。
Web3関連企業で働いていたものの、3年くらいは仕事が忙しくて、あまりWeb3に触れない日々が続きました。
最近仕事も落ち着いてきて、何かやりたいなと考えていたのですが、Web3の流行なども相まって本格的にWeb3業界に進出したいと思うようになりました。
「開発者によるWeb3の再学習」シリーズでは、Andreas M. Antonopoulos, Gavin Wood著「マスタリング・イーサリアム スマートコントラクトとDAppの構築」を1章から読み進めて、自分の理解できなかった部分は追加情報を用いて説明しようかと考えています。
最終目標は「独自ブロックチェーンの開発」です。 よろしくお願いします!
イーサリアムとは何か?
- イーサリアム = 世界中に点在したコンピュータを用いた非中央集権的な演算基盤
- スマートコントラクト = プログラムコード
- イーサ = プログラムコードを動作させるためのエネルギー
ビットコインとの比較
ビットコインとイーサリアム共通要素
- P2P(Peer to Peer/ピア・ツー・ピア)
- ビザンチン障害耐性コンセンサスアルゴリズム
- 暗号技術(デジタル署名・ハッシュ等)
- デジタル通貨
ビットコインとイーサリアムの違い
項目 | ビットコイン | イーサリアム |
---|---|---|
デジタル通貨の目的 | 決済ネットワーク | ワールドコンピュータの使用料 |
汎用性 | 限られた情報を記録できる | 仮想マシンによるチューリング完全なプログラム環境 |
ビザンチン障害耐性とは
ビザンチン障害耐性(Byzantine Fault Tolerance/BFT)とは、ビザンチン将軍問題に帰結される故障や障害への耐性を言います。
ビザンチン将軍問題とは、非中央集権的なシステムにおいて、システムの一部に故障や悪意が含まれる状態で、全体として正しい合意を形成できるかを問う問題です。
これまで、ビザンチン障害耐性は複数のセンサーの結果をもとに決断を求められる航空や原子力発電所などの分野で使用されていました。 このような考え方が金融に取り入れられるとは、非常に興味深いです。
非中央集権的なシステム(ネットワーク)には不特定多数の人(コンピュータ)が集まっています。そして、ネットワークの参加者は以下のような問題を抱えている可能性があります。
- 通信障害
- アプリの動作不良
- 遅延
- 盗まれたパソコンを使用
- 盗まれたアカウントを使用
- 悪意を持って情報を改竄しようとする
- 嘘をつく
このネットワーク内でとある合意を求めようとします。 例えば、以下のようなものがあります。
- プログラムの実行によって状態が変化する
- プログラムは正しいルールで記述されている
- プログラムの実行に十分な暗号通貨が添付されている
- 送金に十分な残高を所有している
参加者全員がネットワークが合意の状態、すなわち「コンセンサス」に達する必要があります。
ネットワークの一部に上記のような問題点があった場合にも、正しい合意を行えるシステムをビザンチン障害耐性のあるシステムと呼びます。
Practical Byzantine fault tolerance
ビザンチン障害耐性のあるシステムとして、PBFT(Practical Byzantine fault tolerance)があります。
「Hyperledger」と言われるLinux Foundationによって設立されたコンソーシアム向けのブロックチェーンでは、このPBFTを使用することができます。
簡単にアルゴリズムと特徴を説明します。
登場人物は、以下の3パターンのノードです。
- リレーノード(承認不可)
- リーダーノード(承認可能、単一)
- フォロワーノード(承認可能、複数)
承認プロセスは、以下の8プロセスです。
- リーダーノードの決定
- リレーノードからリーダーノードにトランザクションを送信
- リーダーノードからフォロワーノードにトランザクションを送信
- フォロワーノードはトランザクションの「正しさ」をチェックし、他のフォロワーノードに「正しい(仮)」と共有
- フォロワーノードは一定以上の「正しい(仮)」が得られたら、他のフォロワーノードに「正しい(正式)」と共有
- フォロワーノードは一定以上の「正しい(正式)」が得られたら、トランザクションを実行し、台帳を更新する
- フォロワーノードは「トランザクションの完了」をリレーノードに伝える
- リレーノードは一定以上の「トランザクションの完了」を受け取ったらトランザクションを完了とする
メリット
- 高速に処理可能
- トランザクション完了のタイミングが明確
デメリット
- リーダーノードが大きな権利を持つ
- 参加ノード数に制限がある(ノード数が増えると速度が低下する)
PBFTはHyperledgerに加えて、ZILLIQAやARKに使用されているとのことです。
DBFT(Delegated Byzantine Fault Tolerance)というリーダーノードを変更可能なPBFTなども提案されていて、NEOで使用されているとのことです。
上記、PBFTは基本的にはプライベートチェーンやコンソーシアムなどの少数の参加ノードという限られた環境でのみ有効となります。
Proof of Work
不特定多数のユーザーが参加できるような投票システムにおいて、The Sybil Attackという、一人の利用者が複数の IDを作成して投票をコントロールする攻撃があります。
The Sybil Attackの対策として、Aspnesの論文があります。悪人だけでなく善人も複数のIDを作成できるようにすることで、投票は悪人だけにコントロールされず、善人のコンピューターパワーvs悪人のコンピューターパワーという構図となる、Proof of Workの前身となる考え方が生まれました。
Proof of workでは、IDの数を投票権として扱うのではなく、より本質的な部分である、「コンピューターパワー = 投票権」をシステムとして表現しています。
Proof of workでは、簡単に説明すると、「履歴情報(一つ前のブロックの情報)」と「追加情報(新しいブロックの情報)」をもとに、コンピューターパワーを競わせる問題を作成して、その問題を一番最初に解いた人(ナンスを見つけた人)に報酬とブロックを繋げる権利を与えています。
- ネットワークとして正しく動作させるためのインセンティブ(マイニング報酬)
- 深刻な悪意は反映させられない限定された権利(ブロックを繋げる権利)
- 価値を維持し続けるためのルール(最も長いチェーンを採用)
などによって、Proof of workはビザンチン障害耐性を実現しています。
プルーフ・オブ・ワークに関して、疑問点がいくつか湧いてきたので、ここで解決を図ります。 ※ 未解決の疑問は後日追記します。
ナンスを見つけた後、周囲のネットワークは気づかないフリとかしないのかな?
ナンスを見つけた後、周囲のネットワークに情報が伝播されます。
この時、周囲のネットワークは気づかないふりとかしないのかな?
受け取った側は、以下の二つの選択肢があります。
① 他の人がナンスを見つけたことに気づかないふりをして、PoWを続ける
② 他の人のナンスを受け入れて、自分のノードのチェーンを伸ばす
(恐らくココが認識違い!?)
ビットコインは、10分に一度の記録タイミングがあるとのことだが、情報を受け取った後に次のマイニングが行えないのであれば、気づかないふりをして、PoWを続ける(①を選択する)人がいてもおかしくないイメージ。
あくまでも10分はDifficulity(採掘難易度/ディフィカルティー)に依存しておおよそ決まるもので、マイニングが完了したら次のマイニングを始められるのではないかと考える。
情報を受け取った後に次のマイニングが行えるのであれば、②を選択して、ネットワークとして良い方向に向かいそう。
マイニングが運ゲーでマイニング結果で採掘難易度が決まるなら採掘難易度がとても低いタイミングもあるのかな?
調べたところ、採掘難易度の調整は約2週間に1度しか行われません。
マイニング一回一回は運ゲーですが、採掘難易度は2週間分の平された結果をもとに決まるので、今日だけ急激に採掘難易度が低くなるということはないです。
プルーフ・オブ・ワークで解いている問題はネットワーク全体で同じなのかな?
もし、以下の条件でナンスを探索する場合、必ずスペックの良いPCが勝利してしまい、投票権=マシンパワーを実現できていないのではないですか?
- 良いスペックのPCと悪いスペックのPCが同じ問題を解く
- ナンスを探索する順番も同じ(0から順にインクリメント)
実際のプルーフ・オブ・ワークではおそらく以下のどちらかを採用していると考えます。
①ナンスを探索する順番を変えている
②難易度は同じだが、全く同じ問題を解いているわけではない
取り入れるトランザクションによって求めるべきナンスが異なると思うので、難易度は同じだけど違う問題を解いている(②)のかと考えます。
調べたところ、マイナーによって正しいナンスは異なるとのことでした。
ブロックチェーンに正式に記録されていないトランザクションはメモリプールに保存されます。マイナー毎に構築しているメモリプールは異なるので、正しいナンスも異なるとのことでした。
ナンスの探索は0から順にインクリメントで求めているのかな?
調べたところ、0から順番に数字を増加させていくという方法が最も効率的とのことでした。
求めるナンスがマイナーによって異なっているので、問題はなさそうです。
ナンスに規則性があるのであれば、工夫のしようがありますが、全く規則性がないのであれば、乱数を使用するコストも無駄なので、インクリメントするのが最も効率的なのかと考えます。
最も長いチェーンが正しいチェーンって誰が決めているの?
ブロックチェーンでは、最も長いチェーンが正しいチェーンと見做される。
なぜこれが成り立つのだろうか?
長いチェーンであればあるほどマイニング報酬を得ている人が多いので賛同も得られやすい。
「最も長いチェーン = 投票数が最も多いチェーン」という意味合いで、民主主義的な決定法則が含まれているのではないかと考える。
一番早くナンスを求めた人がわかるの?証拠はあるの?
「最も長いチェーン=一番早くナンスを求めた人のブロックが入る」は成り立つのだろうか?
結論、必ずしも一番早くナンスを求めた人の結果が記録されるわけではないと考える。
ブロックが追加されるフローをAさん〜Eさんの参加者間で考えてみる。
00時00分00秒にナンスを求めた人(Aさん)と00時00分01秒にナンスを求めた人(Bさん)、ナンスを求めることができなかった人(Cさん、Dさん、Eさん)がいたとする
Aさんの情報の方が先にネットワークに広がっていくが、それと1秒遅れでBさんの情報もネットワークに広がっていく。
Cさん・Dさんは先にAさんの情報が伝わってくるので、Aさんのブロックを採用する
Eさんは先にBさんの情報が伝わってくるので、Bさんのブロックを採用する
Aさんの作成したブロックが入れられたチェーンは、Aさん・Cさん・Dさんによってマイニングされる
Bさんの作成したブロックが入れられたチェーンは、Bさん・Eさんによってマイニングされる
Aさんの作成したブロックが入れられたチェーンの方が合計のマシンパワーが大きいので、次のマイニングでも先に成功する確率が高くなる。
ブロックが積み上がっていく毎に、その差が大きくなり、ブロックの数自体に差ができてくる。
最終的に、より長いチェーンであるAさんのブロックが入れられたチェーンが採用されて、Bさんのブロックが入れられたチェーンは破棄される
あくまでも確率論的にパワーバランスが変わってくるので、早くナンスを見つけた人のブロックが有利にネットワークに伝播できるだけで、必ずしも採用されるわけではないと考える。
プルーフ・オブ・ワークで一番最初にナンスを求めた人が悪意を持っていた場合、何ができる?
考えられる操作としては、以下の操作が挙げられる
- マイニングプールから特定の人物のトランザクションを追加しない
- トランザクションを追加しない
- 全く同じハッシュ値の改ざんされたトランザクションを追加
実際問題、プルーフ・オブ・ワークで一番最初にナンスを求めたとしても追加するトランザクションの取捨選択くらいしかできない(3番目は確率論的に困難)。
以上の考えから、同期が正しく行われる仕組みがあるのであれば、必ずしもチェーンは一つである必要はないのかと考える。
一番最初にナンスを求めた人が情報を記録するインセンティブはあるの?
ビットコインには取引手数料があります。イーサリアムもガス代という取引手数料に値する概念があります。
ナンスを求めて記録した人が、この手数料とマイニング報酬を得ることができます。
十分な情報を記録するインセンティブになるかと考えます。
ネットワークの一部の人が結託した場合、報酬の期待値を上げられる
結論:考えた限りでは難しそう
- ネットワークの参加者のうち20%が悪意の協力関係をもつ
- 残りの80%からのブロックの追加を一旦無視してPoWを続ける
- 無視して得られた報酬を20%の協力者で分配する
- ある程度負け越したら80%側の情報を同期して仕切り直し
なんだか期待値が上げられそうなイメージですが、ナンスの探索は完全確率で実施されるため、例えば、1/100の抽選を99回ハズレを引いても100回目も1/100です。
ブロックの追加を無視すると、20/100の確率でナンスを見つけることができますが、ブロックの追加を無視しなかったとしても、20/100の確率でナンスを見つけることができます。
しかし、80%側のブロックの追加を無視した場合には、必ずしも正式採用されるわけではないので、計算してはないですが、不利になりそうです。
チューリング完全
チューリング完全とは簡単にいうと、なんでも計算できるシステムです。
基本的にはプログラミング言語はなんでも計算できるので、チューリング完全と言われます。 しかし、一部の言語では機能の一部を制限して(チューリング不完全)、安全性の向上を図ったりします。
プログラム言語においては、「順次」「分岐」「反復」という処理を実現できれば、チューリング完全と呼ぶようです(参考)。
- マインクラフトはレッドストーンを使えば、チューリング完全となり、どんなシステムでも構築することができるらしいです
- HTMLとCSSは人力チューリング完全と考える人もいるようです
イーサリアムで使用されるプログラミング言語Solidityはチューリング完全であり、理論上どんなシステムでも構築することができます。
一方で、チューリング完全であることは、反復などもサポートするということなので、自身を再起的に呼び出す関数を作成することで、無限ループなども実現できてしまいます。
イーサリアムではガス代という制約によって、無限ループが起きないような仕組みを導入していますが、誰でも利用でるパソコン(イーサリアム、ワールドコンピュータ)で再起呼び出しが実現できてしまうこと自体を問題視している人もいます(スマートコントラクトはチューリング不完全な方が良いのでは?)。
- The DAO事件では再起呼び出しを悪用された
- スマートコントラクトの実行手数料が予測不可能
イーサリアムの構成要素
項目 | 説明 |
---|---|
P2Pネットワーク | devp2pというプロトコル |
コンセンサスルール | イエローペーパーを参照 |
トランザクション | 送信者、受信者、値、データペイロード |
状態マシン | イーサリアム仮想マシン |
データ構造 | LevelDBにトランザクションとシステムの状態がマークルパトリシアツリーとして記録 |
コンセンサスアルゴリズム | ナカモトコンセンサス → Proof Of Stake |
経済的な安定 | Ethash → Proof Of Stak |
クライアント | Go-Ethereuam, Parity |
まとめ
途中で脱線してしまい、Proof of workやビザンチン障害耐性にかなりの時間と分量を割くことになってしまいました。 ですが、知識をかなり深めることができたと思います。
次回は2章「イーサリアムの基礎」です。