-
Notifications
You must be signed in to change notification settings - Fork 2.6k
[Japanese] White Paper
🛑 This wiki has now been deprecated. Please visit ethereum.org for up-to-date information on Ethereum. 🛑
Contents
- Ethereum 白書
- 脚注 及び 参考文献 - 脚注 - 日本語翻訳脚注 - 参考文献
ナカモトサトシの論文により、2009年に開発された Bitcoin は通貨・貨幣における革新的な発明だと 謳われ、金兌換のような後ろ盾がなく、中央通貨管理局をもたないはじめての デジタル財産 の例です。( intrinsic value ) しかし、その壮大な Bitcoin の実験における、より特筆すべき重要部は別の所にあります。 それは分散型大衆決定のツールとして、まさにその基礎をなす Blockchain の技術であり、急速に人々の注目を集めつつあります。
一般的に、 blockchain テクノロジーを引用している Bitcoin の代替アプリで、 blockchain 上の電子財産を実装したものとして:
- 一定取引量のある通貨や金融商品をあらわすもの ( colored coins )
- 基礎となる物理デバイスの所有権 ( smart property )
- ドメインのような投資対象外の財産 ( Namecoin )
があり、より複雑なアプリケーションとしては以下のものが挙げられます:
- (役人や銀行員に取って代わり)、コーディングであらゆるルールを実装し、個々の電子資産を管理するもの( smart contracts )
- 上記のスマートコントラクトを blockchain 上で実装したもの ( DAO )
Ethereum が提供しようとしているものは、 チューリング完全なプログラミング言語の完成品を blockchain に埋め込み提供することにあります。 この言語は、"contract" を生成するために使用され、 "contract" とはあらゆる 関数 をプログラムしたものです。 これにより、ユーザーは上記の全てのシステムを実装することが可能で、 われわれがまだ想像すらしていない多くの可能性が、 論理を秘めし数行のコードを書き上げるだけで実現できるようになります。
上述の資産登録マシンのような代替アプリや、 分散型デジタル通貨の概念が現れ始めたのは、ここ数十年です。 80〜90年代にかけて、David Chaum の「ブラインディング署名 blinding signature」をよりどころとした 匿名のデジタル通貨プロトコルがたくさん開発され、高いプライバシーをもつ通貨を提供しましたが、 これらは中央集約型の媒体に依存していたため、広く注目を浴びるには至りませんでした。 1998年に発表された、Wei Daiによる b-money が、 現行の分散型のコンセンサスと同様のもので、計算問題を解くことによって お金を創造するというアイデアを、はじめて導入した事例となります。 しかし、このプロポーザルの詳細は不十分であったため、実用的な分散型の大衆意思決定を実装することができませんでした。 2005年、Hal Finney が、暗号通貨のコンセプトをつくりあげるために、 ABCD Hashcash パズル[jp-1] と b-money からアイデアをしぼり作られたシステムである "reusable proofs of work" というコンセプトを発表しましたが、バックエンドに、信用のある計算機を使用しなければならなかったため、真に分散型とは呼べず、再び失敗しました。 2009年のナカモトサトシによる実用的な実装がはじめての分散型の通貨となりました。 これは、昔からあった「公開鍵暗号(所有権を管理) 」と 大衆意思決定アルゴリズムである「 "proof of work" (誰がコインを所有しているのか追跡)」 を結びあわせたものとなります。
proof of work の背景にある技術は宇宙史に名を刻むほどの飛躍的進歩でありました。 なぜなら proof of work は、同時に二つの難題を解決したのです。
- ひとつめは、単純明快で適切な影響力をもつ大衆意思決定のアルゴリズムの提供で、 ネットワーク上のノードはBitcoinの帳簿の「一般規則に従う状態更新」ができるようになりました。
- ふたつめは、大衆意思決定のプロセスへの自由参加を可能にするメカニズムの提供で、 誰が、コンセンサスに影響をもたらすのかということを決める政治的問題を解決したのです。 これは同時に Sybil Attack(ひとりでノードを多数生成し多数決的に攻撃する手法)を防ぐことにつながります。
これは次のようにして、参加基準を定式化したということです。
- ノードに対し、特定リストにおける唯一性の証明書の提出を要求し、
- さらに「大衆意思決定のプロセスにおける単位ノードの重みは、ノードのもつ計算能力に応じて分配する」 という エコノミックバリア[jp-2] を採用する
その後、proof of stake と呼ばれる手法も提案されています。 計算資源ではなく保持している通貨量に比例してノードの重みを計算するというものです。 2つの手法の相対的な利点に関する議論はこの白書の枠を超えてしまいますが、 どちらの手法も暗号通貨を支える屋台骨として利用されていることは言及しておいて良いでしょう。
歴史に関しては、Ethereum を創設した Vitalik Buterin のブログ記事 Ethereum pre-history があります。 さらなる歴史については こちら の記事もあります。
技術的観点から見ると、(本来 Bitcoin は、状態を持たない、ただの関数の鎖に過ぎない純粋なものですが、) Bitcoin をはじめとした暗号通貨の帳簿は、全 bitcoin の所有状況をあらわす「状態」と、状態と取引(トランザクション、状態遷移関数のこと)から新たな状態を出力する「状態遷移関数」をもった、「状態遷移」のシステムとしてみることができます。 一般的銀行のシステムでは、たとえば「状態」はバランスシートにあたり、 「トランザクション」はAからBにXドル移動してくれ、というリクエストにあたり、 この状態遷移関数は、XドルだけAの口座の残高を減らし、Bの残高を増やします。 もし、Aの口座の残高がXドルに満たなかった場合には、 状態遷移関数はエラーを返します。 これを定式化し、
APPLY(S,TX) -> S' or ERROR
この銀行システムは以上で定義され、以下はその適用例です。
APPLY({ Alice: $50, Bob: $50 },"send $20 from Alice to Bob") = { Alice: $30, Bob: $70 }
APPLY({ Alice: $50, Bob: $50 },"send $70 from Alice to Bob") = ERROR
Bitcoin における「状態 state」とは、全コインの集合 であり、 技術的に説明いたしますと、 発行されているコインのうちで「UTXO(未使用の取引出力値)」の全集合 となり、各 UTXO には、それぞれ「残高」と「所有者」が記録されています。 「所有者」は、基本的に、暗号理論における公開鍵[1]である20バイト(160bit)のアドレスとなります。 「トランザクション」は、状態遷移関数であり、一以上の入力値 と 一以上の出力値 をとります。 各入力値は、「既存の UTXO への参照」と「所有者のアドレスと関連付けられた秘密鍵による暗号署名」 から構成され、 各出力値は、「新しく生成された UTXO」を保持しています。
状態遷移関数 APPLY(S,TX) -> S'
を定義するプログラムの概略は以下となります。:
- 各入力
TX
に対して:- もし、参照先の UTXO が、状態
S
に保持されていないならば、エラーを返す。 - もし、提供された署名がその UTXO の所有者のものとマッチしなければ、エラーを返す。
- もし、参照先の UTXO が、状態
- もし、入力用の全 UTXO の価値の合計が、出力用の全 UTXO の価値の合計より小さければ、エラーを返します。
- 入力用の全 UTXO を取り除き、出力用の全 UTXO を加えた新たな状態
S
を返します。
ひとつめのステップにおける 前半部により、トランザクションの送信者が、存在しないコインを不正に送ることを防止し、 後半部により、トランザクションの送信者が、他人のコインを勝手に送ることを防止します。 ふたつめのステップによって、トータルバリューの保存(入力値の総計 が 出力値の総計 と等しい)が執行されます。 これを実用的な支払いに適用するための、プロトコルは以下のようになります。
アリスがボブに 11.7 BTC を送信したいとします。 まずはじめに、アリスは、利用可能な UTXO を自分の持っているものの中からかき集め、 少なくとも総計 11.7 BTC になるようにします。アリスの UTXO を集めてちょうど 11.7 BTC をつくることはできず、6+4+2=12 BTC がアリスの得る最小の値です。 そして彼女は、3つの入力値と2つの出力値をもつトランザクションをつくります。 ひとつめの出力値は 11.7 BTC でボブのアドレスが所有者として記録され、 ふたつめの出力値は 0.3 BTC の"お釣り"がアリス自身を所有者として記録されます。
もし、アクセス対象として信用取引可能な 中央集約型 のサービスを使っているのであれば、 このシステムの実装は至極簡単なものであったでしょう。 単に上記のプログラムコードを記すのに、中央サーバーのハードディスクを使用し、「状態」を記録・維持すれば済む話であったでしょう。 しかし、わたしたちが Bitcoin を用いてやろうとしているのは、分散型通貨システムの構築です。 なので、トランザクションの順番をみんなが合意できることを確約するために、 状態遷移システム と 大衆意思決定のシステム をくっつけてやらなくてはなりません。 Bitcoin の分散型大衆決定プロセスでは、「ブロック」と呼ばれる「トランザクションを梱包したもの」を作り続けようとする、 ネットワーク上のノードが必要です。 ネットワークは、だいたい10分毎にひとつの ブロック を生成するように設計されており、 各々のブロックは、
- 「タイムスタンプ」
- 「ノンス」
- 「直前のブロックへの参照値」
- 「(直前のブロック生成後から現在までに遂行された)トランザクションのリスト」
を保持します。( ※ ノンス:ブロック生成時にインクリメントされ続ける個体識別ハッシュ値で、マイナーがブロックを掘り当てることを目標にして独自にインクリメントする。) このブロックが時間発展することによって、 Bitcoin の帳簿を最新状態に更新し続ける、 永続的かつ恒久的成長をなす " blockchain " (ブロックの鎖)を生成します。
現パラダイム下において、ブロックが有効かどうかをチェックするアルゴリズムは以下となります:
- そのブロックが参照する直前のブロックが存在し、それが有効であるかをチェックする。
- そのブロックのタイムスタンプが直前のブロック[2] より大きく、かつ2時間後の未来におけるものまでそれにおけるものより小さいかを確認する。
- そのブロック上での、proof of work が有効かチェックする。
- 直前のブロックの終状態を
S[0]
とします。 -
TX
をn
個のトランザクションからなる「リスト」だとします。0...n-1
における、全てのi
に対し、S[i+1] = APPLY(S[i],TX[i])
と順番に適用します。もし、一つでもエラーを返せば、exit し、false を返します。 - true を返し、このブロックの最後の状態として
S[n]
を記録します。
基本的に ブロック内の各トランザクションは、 トランザクション執行前の 過去の状態 をもとにして、有効な状態遷移を提供しなければなりません。 「状態」はいかなる点においても、ブロック内に記述されないことに注意してください。(ブロックは状態遷移関数をつなげ合わせた関数そのものであり、入力値 である「状態」については何も書かれていません); (このアルゴリズムは、「検証ノード」を説明する簡単な抽象例であり、 どのブロックの検証においても、開始状態から、全ブロックの全トランザクションを順番に適用することによって、 目的となるブロックの示す状態を計算すれば十分となります。) さらに「採掘者 miner」がトランザクションをブロックに取り込む順番がとても重要だということに注意してください。 (もし、A、Bという二つのトランザクションがあって、BはAの生成した UTXO(未使用出力値) を使う場合において、 AのあとにBがきているブロックは有効ですが、そうでない場合は無効となってしまいます。)
他のシステムでは見受けられない仕様として、 上述のトランザクションリストは、(どのトランザクションがどこに取り入れられるか、あるいは取り入れられないなど、によって数多の選択肢が考えられますが、)ここで「有効なものを一つ選ぶための選定条件」が "proof of work" には必要となります。 厳密な定義は、 全てのブロックの double-SHA256 hash値(256bit の数値)が 動的に変化するように設計された「目的値 target」より小さくなること、であり、 目的値は、これを執筆している当時では、約2187でした。 これは、ブロック生成を計算科学上 "難しく" する為であり、 その結果、Sybil Attack(ひとりでノードを多数生成し多数決的に攻撃する手法)による攻撃者が自身の好きなように 全 blockchain を改竄してしまうことを防止いたします。 SHA256(エスエイチエーにごろ)は、完全に予測不可能な擬似乱数関数として設計されており、 有効なブロックをつくる唯一の方法は、単に ノンス をインクリメントしてはその新しい hash値 が適合するかを確かめるという、試行錯誤を繰り返すしかありません。
現在における ~ 2187の「目的値」では、 ネットワークは ~ 269 回の試行錯誤をしてやっとブロックを見つけることができます。 ふつう、目的値 は、ネットワーク上で2016ブロック生成される毎に再設定され、 ネットワーク上にあるノードによるブロックの発掘が平均して10分毎に生じるよう調整されます。 採掘者に競わせてこの計算をさせるための設定として、 ブロックを採掘したものは、どこからともなく湧いた自分への25BTCの報酬を、 トランザクションとして最後に付け加えます。 さらに、 全入力値が全出力値よりも大きいような全てのトランザクションにおける、 その差額は「取引手数料 transaction fee」として、採掘者のもとへ行く仕組みです。 ところで、これはBitcoinが発行される唯一のメカニズムとなります。 つまり、初期状態においては、Bitcoin は皆無であったわけです。
マイニングの目的をより深く理解するために、 悪意ある攻撃者のおこす事件によって何がおこるのかを見ていきましょう。 Bitcoin の基礎となる暗号理論はセキュリティの高いものと知られているので、 攻撃者の狙い目としては、直接、暗号理論で守られていない部分 : トランザクションの順序 となるでしょう。
攻撃者の戦略は簡単なものです:
- ある商売人に 100 BTC をある商品の購入代金として送る (瞬間的な発送ができるデジタル商品が好まれます)
- 商品の到着を待つ
- 自分自身に 100 BTC を送る別のトランザクションを生成する
- ネットワークが、後に作った方のトランザクションの順番が最初にくるようなブロックを、承認するように試みる
一度、ステップ 1 が履行されると
数分後に採掘者がトランザクションをブロックに含めます。
ブロック番号は 270000 とします。
一時間後、5個以上のブロックが、そのブロックの後ろに追加され、
この5つのブロックが、間接的にそのトランザクションを参照しているため、
トランザクションは「承認 confirming」されたということになります。
この時点で、
商売人は、支払いが確定したものとみなし、商品を発送します。
ここではデジタル商品を考え、商品がすぐに届くこととします。
さていま、攻撃者が、別のトランザクションを作成し、自分宛に 100BTC を送るものとします。
攻撃者が、もし単にそれを野に放っただけならば、
そのトランザクションは受理されないでしょう。
法の番人である採掘者は、APPLY(S,TX)
を実行するとき、TX
が、使用済みUTXO を使用しようとしていることに気づくでしょう。
なので代わりに、
攻撃者はブロックチェーンを分岐させ、
親として同じ 269999 番目のブロックを参照する 270000 番目の新しいバージョンのブロックを生成します。
ここでは、もとのブロックに含まれていたトランザクションは含まれず、新しいトランザクションが追加されていくこととなります。
ブロックのデータの中身が違うので、
攻撃者は proof of work をやり直す必要があります。
さらに、攻撃者の新しいブロック 270000 では、異なるハッシュ値を生成するので、
もとのブロックチェーン上のブロック 270001 ~ 270005 は、このブロックを参照しません。
このように、もとのブロックチェーンと攻撃者のチェーンは完全に分断されるのです。
このとき適用されるルールは次のようになります。
ブロックチェーンの分岐時は、
一番長いブロックチェーンが "信用" あるものとして選択されます。
なので、攻撃者が新しい 270000 のブロックチェーン上で採掘し続ける傍で、
このシステムの法の番人である採掘者達はもとの 270005 のブロックチェーンを採掘し続けることになります。
攻撃者が、自分のブロックチェーンを最長にするためには、
ネットワーク上の残りのすべてのノードの総和より、高い計算能力を誇る必要があり、
これを「51%攻撃」と呼びます。
左 : 分岐の正当性の証明には、少しのノードを与えてやるだけでよい
右 : どの部分にいかなる変化を付与しても、鎖の上方で必ず不一致を生む
Bitcoin の重要なスケーラビリティ特性は「ブロックは多層データ構造で保管される」ということです。 ブロックの「ハッシュ値」とは実は、ブロックヘッダ(先頭部)のハッシュ値 に過ぎず、これは約 200 byte のデータであり、
- タイムスタンプ
- ノンス
- 直前のブロックの ハッシュ値
- マークル木(ブロック内の全トランザクションを保持するデータ構造)の ルート(根の元となる部分)の ハッシュ値
を保持します。マークル木は、バイナリ木のひとつで、以下の三つから構成されます。
- 基礎データを保持する木構造の最下層の「葉(リーフノード)」の集合
- 二つの 子ノード のハッシュ値である「枝(中間ノード)」の集合
- 唯一の「根(ルートノード)」(二つの子ノードのハッシュ値で "頂上" にくるもの)
マークル木は、ブロック中のデータをバラバラに運搬するためにつくられました。 ノードは、ひとつのソース(ネットワーク上の自身とは別のノード)からブロックヘッダだけを、 別のソースから、必要なトランザクションに関連する小さな部分木を、ダウンロードすることができ、それでもなお全データの整合性を保証できるのです。 これがうまく動作する所以は、ハッシュ値が上に伝播していくところ です。: もし悪意のあるユーザーが偽物のトランザクションをマークル木の底のノードと取り替えようとすると、この変化はその親のノードを変化させ、繰り返し伝播することで最終的にルートの値を変化させます。 つまり、ブロックのハッシュ値が変化し、マークル木のプロトコルにより、結果として、全く別のブロックとして記録され、このブロックは十中八九 proof of work が無効となります。
マークル木のプロトコルは、言うまでもなく長期にわたるアプリケーションの維持のために必要です。 Bitcoin ネットワークにおける「完全ノード、フルノード」とは、「全ブロックの全トランザクションを保管・処理するノード」のことで、 2014年4月の時点で 15GB の容量をとり、ひと月あたり1GB以上の速さで増え続けています。 現在、これはデスクトップコンピュータ上で目視できますが、携帯電話では確認できません。 容量的な観点から、後々の未来、完全ノード に参加できるのは、ビジネスや趣味の範疇に限られてくるでしょう。 「SPV (簡素な支払検証)」として知られるプロトコルにより、「完全ノード」とは別タイプのノードが開発されました。 「軽量ノード、ライトノード」と呼ばれ、このノードは、ブロックヘッダをダウンロードし、ブロックヘッダで proof of work を検証し、そして自身に関係のある トランザクションの「枝、ブランチ」だけをダウンロードします。 軽量ノードは、セキュリティを強く保ったまま、トランザクション履歴や残高を、状態遷移関数により決定することができるというのに、 全ブロックチェーンの小さな部分木をダウンロードすればよい、というものなのです。
基礎技術である blockchain の他コンセプトへの応用は、これもまた、長い歴史があります。 2005 年 Nick Szabo が "secure property titles with owner authority(自己の権威によるセキュアな財産の獲得)" というコンセプトを発表しました。この論文は、複製データベースの技術の進歩により、いかにして blockchain 基調のシステムが、土地所有の登記 の保管を可能にするのかを記述し、 「開拓 homesteading」「不法占有 adverse possesion」「ジョージの土地課税 Georgian land tax」といったコンセプトを含む枠組みを、苦労して築き上げました。 しかし、残念ながら、当時利用できる、効果的な複製データシステムがなかったため、プロトコルが実際に実装されることはありませでした。 とは言うものの、2009 年に Bitcoin の分散型コンセンサス が一度開発されてからは、急速に代替アプリが出現し始めました。
-
Namecoin - 2010年に作られた Namecoin は「分散型名前登録データベース」と表現されます。 Tor や Bitcoin , BitMessage のような分散型プロトコルでは、個体識別に アカウント が必要で、そのため他人による干渉が可能ですが、 どのようにしても利用可能な識別子は、
1LW79wp5ZBqaHW1jL5TCiBCrhQYtHagUWy
のような擬似乱数となります。 できれば "ジョージ" のような名前をつけることができたらいいな、と考えるでしょう。 しかしながら、問題なのは "ジョージ" という名前を誰でも、同じプロセスをたどることで登録でき、"ジョージ"として振舞えるのです。 唯一の解決策は 「first-to-file パラダイム」を用いることです。 これは、最初(first)の登録者は登録(file)に成功し、二番目以降では失敗するというものです。 この問題は Bitcoin の大衆意思決定のプロトコルに完全に合致し、 Namecoin は一早くにこの考えを使って名前登録のシステムを実装し、見事に成功しました。 -
Colored coins - colored coins の目的は、Bitcoin の blockchain 上に「自身で作ったデジタル通貨」や、 通貨の重要な性質である少額使用の例としてユニットを採用した「デジタルトークン」を、構築できるプロトコルを提供することです。 colored coins のプロトコルでは、 特定の Bitcoin UTXO に「色」を設定することで、 新しい通貨を "発行" します。 プロトコルは、colered coins を生成するトランザクションの入力値に「色」が付いていれば、他の UTXO も同じ「色」であるものと再帰的に定義します。 (様々な「色」の入力が混じった場合は、特別なルールが適用されます。) このことで、ユーザーは特別な色の UTXO だけを保持する財布を維持し、 ほとんど Bitcoin と同じように周囲に対し送金することが可能で、 受け取った UTXO の色を特定するには blockchain を遡ります。
-
Metacoins - metacoins の背景となる思想は「 Bitcoin を土台として、その上で動作するプロトコルをもつ」であり、 metacoins のトランザクションの保管に、Bitcoin のトランザクションを使用しますが、Bitcoin とは別の 状態遷移関数
APPLY'
を保持します。 metacoins のプロトコルは、無効な metacoins トランザクションが Bitcoin blockchain 上にでてくることを防止するために、 規則「 ifAPPLY'(S,TX)
returns an error, the protocol defaults to `APPLY'(S,TX) = S 」を加えます。 metacoins は、任意の独自暗号通貨をつくるための 簡単なメカニズム を提供しており、 Bitcoin 自体のシステム内部においては表面化することのない 先進的な独自機能 を持たせることができます。 採掘とネットワークのシステムといった複雑な部分がすでに Bitcoin プロトコルによって処理されているので、 開発コストはとても低く済みます。 metacoins はいくつかの金融契約や名前登録や分散型両替所を実装するのに使われています。
一般的に言って、大衆意思決定プロトコルを構築する方法は二種類あります。 「独自のネットワークをつくる方法」と「Bitcoin を土台とする方法」です。 前者の方法は、namecoin では適度な成功を収めたものの、実装するのが大変です。 と言いますのは、独自の実装はそれぞれにおいて、独自のブロックチェーンをつくる必要があり、 同様に、それに必要な状態遷移とネットワークを構成するコードのあらゆるビルド・アンド・テストが必要となります。 さらに、そうしてできた分散型大衆決定のアプリケーションの数々の集合は、 採掘(power)と検証(law)の分散を招き、仮にアプリケーションの中では多数派であったとしても、 規模が小さすぎて自分のブロックチェーンを公正なものとすることができない、といった事態を招きます。 そして次のことを認識するに至りました。 大きな種類の分散型アプリがあったとして、とりわけ分散型自動組織では、 それらはお互いに手を取り合わなければなりません。
一方で、「Bitcoin を土台とする方法」では、Bitcoin の SPV 特性 を継承しないという欠陥があります。 SPV は Bitcoin では動作しますが、それは blockchain におけるブロックの「深さ」が その正当性 を代弁するためです。 一度、トランザクションの祖先が深いところへ行ってしまえば、 そのトランザクションは、現在の「状態」を構成する正当な状態遷移関数であると、安心して言うことができます。 一方、meta プロトコル では、そのコンテクスト内でトランザクションが無効であっても、 Bitcoin の blockchain において、それが組み込まれることを阻止する方法はありません。 (Bitcoin のコンテクスト と Meta プロトコル のコンテクストは異なります。) このように、もし、完全にセキュアな SPV meta プロトコルの実装 が存在したならば、 あるトランザクションが有効かどうかを判定するために、 Bitcoin の blockchain の一番最初まで全過程を遡ってスキャンする必要があるでしょう。現在、meta プロトコル の軽量実装は、データを提供する信用機関としてのサーバーに依存しており、 言うまでもなく、とりわけ暗号通貨の当初の目的の一つが「信用機関の必要性の消去」であるような状況下では、最良の結果であるとは到底言えません。
たとえまったく拡張をせずとも、実は、Bitcoin プロトコルは「 smart contracts 」コンセプトの 機能的に弱いバージョン を簡単に実装したものなのです。 Bitcoin の UTXO は、「公開鍵」に保持されるだけでなく、 簡素なスタック・ベース・プログラミング言語で表現される少し複雑な「スクリプト」が、保持することもできます。 このパラダイムの下で、 トランザクションが、 スクリプト保持の UTXO を 入力値 とすれば、 スクリプトの記述内容を満たすデータが 出力値 となるように、 トランザクションの記述がされなければなりません。 さらには、 基本的な 公開鍵保有メカニズム(その公開鍵を使用したトランザクションがブロック内にあるかどうかを検証するメカニズム) でさえ、スクリプトを通して実装されています。 そのスクリプトは、 ブロック生成の証である 楕円曲線署名 を入力値として受け取り、 トランザクションとその UTXO を所有するアドレス(公開鍵)に対してその署名を検証し、 検証が成功すれば 1 を返し、そうでなければ 0 を返します。 他にも、より複雑なスクリプトが様々な使用場面のために存在します。 例えば、 トランザクション検証の際、与えられた三つの鍵の組のうち二つの署名を必要とする スクリプト(マルチシグ multisig)や、 企業アカウントや、セキュリティの高い口座アカウント、商売におけるエスクローが必要な状況に役立つ 初期設定 を構築することができます。 スクリプトは、計算問題の答えに対する懸賞金の支払いにおいても使用され、 「もしあなたがこの額の Dogecoin のトランザクションを送信したという SPV proof を提供できるならば、この Bitcoin はあなたのものだ」といったようなことを記述したスクリプトでさえ構築可能です。 そして基本的には、分散型のクロス暗号通貨の取引が可能です。
しかしながら、Bitcoin に実装されたようなスクリプト言語にはいくつかの重要な制限があります。:
-
チューリング完全性の欠如 - つまるところ、Bitcoin スクリプト言語 は計算理論の大部分をサポートしていますが、ほぼ全てという訳ではありません。 サポートしていない代表的なものとして ループ が挙げられます。 これは、トランザクションの検証中に無限ループに陥る事を避けるために除外されました。 理論的には、プログラマにとってはこれは簡単に克服できる障害で、if文と一緒に基本コードを繰り返せば、あらゆるループを模倣できますが、 スクリプトを記録する(ブロックチェーン上の)スペースを極めて非効率に使用することになります。 たとえば、楕円曲線署名の代替アルゴリズムをスクリプト上に実装したならば、 全く同じである掛け算の命令セットが256回個別に記述されてしまいます。
-
値が定まらない問題 - UTXO を保持する スクリプトが、取引量をきめ細やかに管理する方法はありません。 たとえば、 もしも、神のみぞ知るような内容の契約の大きな取引だっとしたら、それは価格操作等の生じうるヘッジング契約となってしまうでしょう。 それは次のような状況です。 AとBがそれぞれ $1000 相当のBTC をスクリプトに提出し、スクリプトが30日後に$1000相当のBTCをAに残りをBに送るものとします。 30日後の 1 BTC の USドル価格 を決定するのには神託が必要となり、しかし、これは、現在利用可能な完全な中央集約型の方法でさえ、信用とインフラの観点で大きな改良が必要となります。 しかしながら、 UTXO は使うか使わないかの2択なので、 神託が提示しうるすべての価格を UTXO で表すには、2進数計算しかなく、そのため極めて非効率な UTXO の"ハッキング"が必要で、様々な残高の UTXO を用意する必要があります。 たとえば、2k の値をもつ UTXO を k = 0 ,..., 30 まで 31個 つくれば良いでしょう。
-
状態の欠如 - UTXO は使うか、使われないかのどちらかを必ず決定してやらなければなりません。 このため、内部に「状態」を保持する多層形式の契約やスクリプトを記述することができません。 このことにより、多分岐選択可能な契約や、分散型取引のオファー、2段階の暗号理論による決定プロトコル(セキュリティの高い計算問題の賞金を与える場合に必要です)をつくるのはとても困難となってしまいます。 さらに、 UTXO は単純な一度きりの契約をつくることにしか使用できず、分散型組織のような、より複雑な「状態」を保持する契約を記述できず、 meta プロトコルの実装を困難なものとします。 また、値の定まらない2進数状態では、「引き出し制限」が不可能となります。これは重要なアプリケーションであり、大きな弊害であると言えるでしょう。
-
Blockchain が見えない問題 - UTXO は、ノンス、タイムスタンプ、直前のブロックのハッシュといった blockchain のデータに対して盲目です。 このことにより、スクリプト言語が、ランダム性の観点で潜在的価値のあるソースを参照するのを防いでしまい、 ギャンブル・アプリケーションや他のカテゴリのいくつかを、厳しく制限してしまうことになります。
このように、
暗号通貨の上に進化型のアプリケーションを構築する方法を3つ見てきました。
ひとつめは、新しい blockchain を Bitcoin を土台とした上につくり、スクリプト言語を使用し、meta プロトコルを実装する方法です。
ふたつめは、新しい blockchain をつくる方法で、その性質を決定するのに無限の自由が得られますが、
開発時間に関するコスト問題、スタートアップに関する問題とセキュリティー面の問題も同様に得られます。
みっつめは、Bitcoin のスクリプト言語を使用する方法で、開発や一般化は簡単ですが、
可能性が限られてくること、meta プロトコルの実装は簡単ですが、スケーラビリティの欠点に悩むことになります。
Ethereum では、 われわれは、代替となる骨格を築き上げ、 簡単な開発であっても、大きな成果物が得られ、 スマフォのようなライト・クライアントのもつ財産に対しても強固なものを提供し、 同時に、アプリケーションが 経済環境 と blockchain セキュリティ とを共有できるものを提供することを意図しています。
Ethereum の目的は、分散型アプリケーションのための代替プロトコルを創造し、 大規模な分散型アプリケーションにとって、われわれが非常に役立つだろうと信じるところの、数々の修正を加え提供することであります。 ここにおいて、アプリの高速開発にかかる時間、小規模かつ滅多に使われないアプリに対するセキュリティ、他アプリ間の効率のよい相互作用を可能とすること、が重要視されます。 Ethereum は、基本的に究極の抽象基盤層となるものの構築により、以上の目的を果たします。 究極の抽象基盤層とは、埋め込み型チューリング完全なプログラム言語を伴う blockchain であり、 これにより、所有・トランザクションの形式・状態遷移関数に関する、任意の独自規則を創造することのできる機能を備えた smart contracts と 分散型アプリ をだれでも記述することができます。 Namecoin の骨格だけを抜き出した実装は、二行のコードで記述できます。 通貨や評判を管理するシステムは20行以下で構築可能です。 「 Smart contracts 」と呼ばれる暗号理論で実装された「箱」は、値を保持し、ある条件が整った時にだけ、解錠できます。 この smart contracts は Ethereum プラットフォーム上に構築可能であり、 チューリング完全性、値が定まる仕様、状態の保持および blockchain への参照が可能となるところから、 Bitcoin スクリプトにはない、広大かつより強力なプラットフォームとなります。
Ethereum では、「状態」は、「アカウント」と呼ばれるオブジェクトから作り上げられ、各「アカウント」は、20 byte の アドレス と、アカウント間における値や情報の直接的やりとりである 状態遷移 を保持します。Ethereum アカウントは4つのフィールドを含みます。
- nonce 、各トランザクションの処理が一度きりであることを確約するためのカウンター
- アカウントの現在の ether balance
- アカウントの contract code (もし存在すれば)
- アカウントの storage (デフォルトは空)
Ether は、Ethereum における主要な内部暗号燃料であり、トランザクション手数料を支払うために使用されます。 一般的に、アカウントには二つの種類があります。 秘密鍵により管理される EOA (externally owned accounts) と自身のコントラクトコードにより管理される contract (contract account) です。 EOA はコードを持たず、EOA からトランザクションを生成し署名することによって メッセージ を送ることができます。contract では、メッセージを受信した時はいつも保持コードをアクティベートし、内部ストレージを読み書き可能にし、メッセージを送信するもしくは新しいコントラクトを作る、といった内容のことが順番に実行されます。
Ethereum における contract は履行されるべきあるいは一緒にコンパイルされるべきものというよりかはむしろ、 Ethereum 実行環境を職場とする「自動金融エージェント」といったものに似ており、メッセージやトランザクションによって起動されたときには、いつもある特定のコードを実行し、自身の ether 残高と、なんども使う変数を把握するのに必要な key/value ストレージ を直接管理する権限を持っている、ということに注意してください。
Ethereum において、「トランザクション」は、 EOA から送られたメッセージを貯蔵する 署名付データパッケージ を参照するために使用されます。 トランザクションは、以下を含みます。
- メッセージの受領人
- 送信者を特定する署名
- 送信者から受領人へ送られる ether の量
- オプショナルデータフィールド(署名付きデータパッケージ)
-
STARTGAS
値:トランザクションの実行にかかる 計算のステップ数 の最大値 -
GASPRICE
値:送信者が支払う、1計算ステップあたりの手数料
最初の3つは、どんな暗号通貨にもある標準的な、トランザクションの「フィールド」です。 4つ目のデータフィールドは、デフォルトでは関数を持ちません。 しかし、Ethereum 仮想マシンは、contract が使用する opcode を保持する必要があり、その際このデータフィールドが使用されます。 opcodeとは、「 contract がデータにアクセスするのに使用する opcode(オペレーションコード)」です。 もし、contract が blockchain 上のドメイン登録サービスとして機能しているならば、 contract は投げられたデータをふたつの「フィールド」を保持するものとして解釈したがることでありましょう。 ひとつめのフィールドは、登録するドメインで、ふたつめのフィールドはIPアドレスです。 コントラクトは、 opcode によって、メッセージに含まれるこれらの値を読み込むことで、適切にストレージの中に配置することが可能となるわけです。
STARTGAS
と GASPRICE
のフィールドは Ethereum サービス に対するモデル拒否運動を封じ込める狙いがあります。
偶発的あるいは故意による無限ループや他の計算理論的に無駄なコードの消費を避けるために、
各トランザクションにはそれらが実行するコードの計算ステップ数の上限を設ける必要があります。
計算の基本ユニットは「 gas 」と呼びます。
たいてい、1計算ステップは 1 gas を消費します。
しかし、幾つかの命令では、計算量的に見てより高価であるため、
少しおおきな gas の量が必要とされます。
また、状態の一部として保持しなければならないデータ量が増えたりします。
トランザクションにデータを埋め込む際には、1 byte 毎に 5 gas の「手数料」もかかります。
「手数料」システムの意図するところは、攻撃者に対し、計算資源や帯域、ストレージを含めた、
彼らが消費する全リソースの量に比例した支払いを強要するためです。
このようにして、ネットワークが消費するどんなリソースにも、それが大量消費とつながるような状況を生み出す、
すべてのトランザクションに対して、消費量の増加に比例した gas の支払いを強要することとなります。
contract は他の contract に対して「メッセージ」を送信することが可能です。 「メッセージ」はネットワークに対して配信されることがなく、 Ethereum 実行環境内でのみ存在します。メッセージは以下を含みます。
- メッセージの送信者 (implicit)
- メッセージの受信者
- メッセージと一緒に送信されるetherの量
- オプショナルデータフィールド
-
STARTGAS
値
基本的には「メッセージ」はトランザクションのようなものですが、
contract により生成され、外部での動作はしない、という点で異なります。
メッセージは contract が CALL
opcode を実行している時に生成され、
この opcode は「メッセージ」を生成し、実行します。
トランザクションのように、
メッセージは、そこに記述されたコードを実行する 受信者のアカウント へと導かれます。
このようにして、contract はEOAのやり方と全く同じ方法で、他の contract と関係性をもつことができます。
ただし、以下のことに注意してください。 トランザクションやコントラクトによって署名された gas の許容値は、そのトランザクションとトランザクション配下の実行ステップにおいて消費される gas の総量に適用されます。 たとえば、もし、外部管理者である A が B に対し、1000 gas と一緒にトランザクションを送信し、B は、C にメッセージを送信する前に 600 gas を消費し、C の内部実行として戻り値を返すまでに 300 gas が消費されたとすると、 B は、「ガス欠」とならないためには、もう 100 gas を使用することが可能です。( ガス欠 となってしまうとエラーを返し、トランザクションは実行されません。)
Ethereum の 状態遷移関数, APPLY(S,TX) -> S'
は次のように定義できます:
- トランンザクションが 「 well-formed 」であるか(例えば、値が正しい数値であるか)チェックし、 署名が有効であれば、ノンスが送信者のアカウントのものと合致するかチェックします。もし、そうでなければ、エラーを返します。
- トランザクションの手数料を
STARTGAS * GASPRICE
として計算し、署名から送信アドレスを決定します。 送信者のアカウントの残高から手数料を差し引き、送信者のノンスを次の値へとインクリメントします。 もし、残高不足であれば、エラーを返します。 -
GAS = STARTGAS
として、GAS
値を初期化し、トランザクションにおける byteデータ量 のぶんだけ byte あたり一定量の gas を支払います。 - 送信者のアカウントから受信者のアカウントにトランザクションの値を転送します。もし、受信者のアカウントが存在しないものであったならば、あたらしくつくります。もし、受信者のアカウントが contract であれば、すべての実行が完了するか、あるいは ガス欠 になるまで contract のコードを実行します。
- もし、送信者が十分なお金を持っていなかったり、 ガス欠 のために、値の転送が失敗した場合には、手数料の支払いを除いて、全状態を元に戻し、手数料はマイナーのアカウントに加えます。
- そうでなければ、余った全ての gas を全て送信者に返し、消費した gas は採掘者に支払われる手数料として送信します。
たとえば、contract コード が以下であるような場合を考えましょう。
if !self.storage[calldataload(0)]:
self.storage[calldataload(0)] = calldataload(32)
実際は、contract コードは低級EVM言語(アセンブラ)であることに注意してください。 このコードは Ethereum における高級言語であるひとつである Serpent 言語で書かれており、コードを確約したものにするために、 低級EVMコードへコンパイルすることが可能です。 さらに次に記す状況を想定しましょう。 この contract のストレージは空の状態から始まり、
- 10 ether の値と、
- 0.001 ether / gas の gasprice で 2000 gas 、そして
- 64バイトのデータ(0-31バイトが数字
2
を表し、32~63バイト番地がCHARLIE
という string を表しているものとします。)
の3つが、トランザクションとともに送信されるものとします。 この場合、状態遷移関数のプロセスは以下のようになります。
- トランザクションが有効かつ well-formed であるか確認する。
- トランザクション送信者が、最低限 2000 * 0.001 = 2 ether を所持しているか確認する。 もし、所持していれば、2 ether を送信者のアカウントから差し引く。
- gas の量を gas = 2000; として初期化します。トランザクションのバイト長が 170 byte であるとすると、byte あたりの手数料が 5 であったことから、850 を差し引くことなり、1150 gas が残ります。
- 送信者のアカウントから 10 ether を差し引き、それを送信先である contract アカウントに加えます。
- コードを走らせます。今回はとてもシンプルです。
まず contract は自身のストレージにおける
2
番目の項目が使われているか確認し、 未使用であることを確認し、ストレージの2
番地にCHARLIE
という値をセットします。
この操作で、187 gas を消費するとしましょう、すると残りの gas は 1150 - 187 = 963 となります。
- 963 * 0.001 = 0.963 ether を送信者のアカウントに返金し、結果として出てきた「状態」を返します。
もしも、トランザクションの受信側に contract がなかったら、当該トランザクションにおける全手数料は、たんに、トランザクションのバイト長に 与えられた GASPRICE
の値をかけたものとなり、トランザクションと一緒に送られたデータは全く関係のないものとなってしまうでしょう。
Note that messages work equivalently to transactions in terms of reverts: もしメッセージが gas を使い果たしてしまったらば、そのメッセージあるいはそのメッセージが引き金となるすべての実行処理がもとにもどされてしまいますが、その「親」の実行に関しては、やり直しになる必要がありません。 これは、contract が他の contract を呼ぶことに関して「安全」であることを意味し、これは、A が G gasもって B を呼び出すと、A による実行はたかだか G gas 分であることが保証されている、と捉えることができます。
最後に、contract を生成する opcode である CREATE
があることに注意してください。
その実行メカニズムは一般的に言って CALL
に似ていますが、実行結果があたらしく作られたコントラクトのコードを返すという点を除いて同じになります。
補足:contract が実際に信用あるものとして、機能するかどうかについてですが、 例として2人間の賭博をあげますと、二人のお金を預けることになるコントラクトはきちんと仕事をするという保証が必要です。 片一方が作成し、騙し取るということが可能に思われます。しかし、これは簡単に解決できます。片方により作成されたコントラクトの公開鍵はわかっているので、そのコードが実行する内容は明るみにでており、エミュレーターを使って、きちんと動作することを確認することで、簡単にコントラクトの安全性を逐一確認することができます。
Ethereum の contract コードは低級スタック・ベース・バイトコード言語で書かれており、「 Ethereum 仮想マシンコード 」や「 EVM code 」などと呼ばれております。
そのコードは一連のbyte列から構成されており、各 byte はひとつの命令を表しております。
一般的に、コード実行とは、プログラムカウンターが現在示すところの命令を実行してはプログラムカウンターを1つインクリメントする繰り返しにより構成される、無限ループであり、エラーや STOP
あるいは RETURN
といった命令が検出されるまで終わることがありません。
EVM における 命令 はデータを貯蔵するために必要な 三種類の スペース にアクセスします。
- stack, 後入れ先出しのコンテナで、push と pop という二つの命令により値を出し入れします。
- Memory, 無限拡張および無限展開可能なバイト配列
- storage, contract が保持する長期保存用ストレージで 、Key/value の貯蔵庫。スタックやメモリでは計算実行後毎にリセットされるのに対し、storage では長期間、値が保持される。
コードも、受信したメッセージにおける 値・送信者・データ にアクセス可能です。また ブロックヘッダ のデータにも同様にアクセスできます。コードは出力として byte 配列のデータ を戻り値として返すことも出来ます。
EVM コード における、形だけの実装が施された実行モデルは、驚くほどシンプルです。Ethereum 仮想マシン が動作しているとき、
ネットワーク全体における、全仮想マシン計算状態 は次のタプルにより決定されます。(block_state, transaction, message, code, memory, stack, pc, gas)
ここで、
block_state
は、全アカウントを保持し、残高やストレージといったデータをひきこんだ「 global な状態 」を表します。
実行の開始時毎に、「 命令 」は、変数pc
番目の byte コードを取ってきます。pc >= len(code)
の条件下では 0 となります。
各命令はタプルに対して、どのように影響するのかという点に関して、独自の定義があります。
例えば、
ADD
はスタックから、二つアイテムを引き出し(pop)、その合計をまたスタックへ押し込めます(push)。
SSTORE
は上部からふたつのアイテムを pop の上、二つ目のアイテムを contract のストレージにおける、一つ目のアイテムが示す番地に格納します。
即時コンパイルによる EVM マシン実行最適化の方法はたくさんあるにもかかわらず、Ethereum は基本的に、実装すると数百行ほどの byte コードスペースを費やします。
Ethereum の blockchain は多くの点で Bitcoin のそれと似ていますが、いくつか違う点があります。 blockchain のアーキテクチャに関する Ethereum と Bitcoin の違いは、次のようになります。 Bitcoin とは違い Ethereum のブロックはトランザクションのリストとブロック生成時点の 状態 のコピーを内部に保持しています。 脇道にそれますが、ブロック番号 と difficulty という、べつの二つの値もブロックに貯蔵されます。 Ethereum における基本的な、ブロック有効化 アルゴリズム は以下となります。
- ブロックの参照する 直前のブロック が存在し、それが有効であるかをチェックします。
- タイムスタンプが 、直前のにおけるそれよりも値が大きく、15分さきの未来まで後出のものより値が小さいことを確認します。
- ブロック番号、難易度、トランザクションのルート、Uncle のルート および ガスの上限(様々な、低級Ethereumの仕様概念)が有効であるか確認します。
- ブロックの有効証である proof of work が有効であるか確認します。
- 直前のブロックの最後の状態を
S[0]
とする。 -
TX
をトランザクション・リストとし、n
個のトランザクションを含むものとする。0...n-1
までの全ての数に対し、S[i+1] = APPLY(S[i], TX[i])
とする。 もし、アプリケーション群のどれか一つでもエラーを返したり、ブロックで消費される全 gas 量がこの段階でGASLIMIT
を超過していたりすると、エラーを返します。 -
S[N]
をS_FINAL
としますが、採掘者へのブロック採掘に対する報酬も加えます。 - 状態
S_FINAL
の マークル木 の ルート がブロックヘッダにおいて与えられる 最終状態のルート と一致するか確かめます。 もしそうであれば、ブロックは有効で、そうでなければ、ブロックは無効です。
さっと目を通しただけでは、このアプローチはとても非効率に思うかもしれません。 なぜならば、このやり方では、各ブロックで 全ネットワークの状態 を保存する必要があるからです。 しかし、現実的には、Etherum の効率は、Bitcoin のそれと比べなければなりません。 というのは、ここで 保存される状態 は、そのデータ木構造に貯蔵され、ブロック毎に、その小さな部分木が変更される必要があります。 このようにすると、一般的に、隣り合う二つのブロック間では、木の大部分は同じとなるはずであり、 そうであるがゆえ、データは、一度貯蔵され、ポインタ(つまり部分木のハッシュ値)を使用して二度 引用符 が付加される、という形式をとります。 この「状態」の保存方法を達成するために「 パトリシア木 」と呼ばれる 特別なデータ木 が使われ、 パトリシア木は、マークル木のコンセプトに対して修正がなされており、ノードの挿入・削除が可能であり、 ただ変わるだけでなく、効率が良くなります。 さらに、全状態の情報が、最新のブロックに含まれますので、ブロックチェインの全履歴を保存する必要がありません。 これは、Bitcoin に適用されたら、5 - 20倍のスペース節約になる 技術戦略 です。
ひろく尋ねられるのが、「どこで contract が実行されるのか」という質問で、物理デバイス上でどこか?ということです。
この質問に対しては、シンプルな回答があります。
「 contract の実行プロセスは、その状態遷移関数の定義の一部であり、それ故ブロックの有効化アルゴリズムの一部となります。
なので、もしトランザクションがブロック B
に付加されたならばそのトランザクションにより生まれるコード実行は全てのノードで実行されます。
その時点より未来において、ブロックB
をダウンロードした全てのノードということです。」
一般的に、Ethereum 上には、3 種類のアプリケーションがあります。 一つ目のカテゴリーは、金融系のアプリケーションで、金銭を使用する契約に対し、導入・管理の強力な手段をユーザへ提供するものです。 これには、副次通貨、金融ディリバティブ、ヘッジング契約、預金、資産相続文書や、さらに言及しますと、労働契約書まるまる含めたものなどがあります。 二つ目のカテゴリは、準金融系アプリであり、非金融的事象の結果に対して金銭を絡めてくるようなもので、その良い例として、計算理論における難題に対し懸賞金を自動執行するようなアプリが挙げられます。 三つ目としては、オンライン選挙 や 分散型統治機構 があります。
ブロックチェイン上の 証明書発行システム (token system) には、多々のアプリケーションがあり、 USドルや金を表す副次通貨から、株式、スマートプロパティとして個人発行した証明書、堅牢で偽造不可な商品券、あるいは全くの無から新たに作られた貨幣証書でさえその範囲に含まれ、経済原理となる(人々の行動の動機付けとなる)ポイント(稼ぎ)のシステムとして使われます。
Ethereum 上で 証明書発行システム を実装するのは驚くほどに簡単です。 理解するために重要点は、 通貨や証明書システムといった基軸となるものはすべて、 あるひとつの操作をともなうデータベース だということです。 そのひとつの操作とは :
A から X 単位を差し引き、それを B にやる
その時の条件として
(1) A は トランザクション以前に 少なくとも X 単位 を保持している
(2) トランザクションが A によって承認される
トークンシステムの実装するのにかかる手間は、このロジックを contract に実装するだけです。 トークンシステムの Serpent における実装の基本コードは以下のようになります:
def send(to, value):
if self.storage[msg.sender] >= value:
self.storage[msg.sender] = self.storage[msg.sender] - value
self.storage[to] = self.storage[to] + value
これは、基礎的に、このドキュメントの冒頭で説明した"銀行システム" の状態遷移関数の文字通りの実装となります。 このコードとは別に、初期化ステップとして通貨単位を共有するあるいはその他特例のために、数行必要となり、 理念としては、ある function は、他の contract に、あるアドレスの残高を探索してもらうために追加されるものですが、 コードの記述はこれで十分です。 理論的に、Ethereum 基盤の証明書発行システムで副次通貨としてふるまうものは、 潜在的に別の重要な特徴を持っています。それは Bitcoin 基盤の meta currency には無いもので、 副次通貨で直接トランザクションの手数料の支払いが可能だという機能です。 もしこれを実装すらならば、 手数料支払いに使用される ether を送信者に 再振込 する方法をとり、 contract は、その時の ether 残高を維持管理することになるかと思います。 手数料支払い時、および常駐のオークションにおいて副次通貨を再度売る時、に使用される、この内部保持されている副次通貨単位を集めることで、ether の残高を再度満たすことになるでしょう。 ユーザはこのため ether でアカウントをアクティベートする必要がありますが、 一度 ether が確認されると、contract がその度ごとに再度振込をするので、再利用可能となるでしょう。
金融ディリバティブ は、最も一般的な、smart contract のアプリケーションであり、コード実装が最も簡単なもののひとつです。 金融契約の実装における主な試練は、その大部分が価格表示器への外部参照が必要となるということです。 例えば、とても望ましいアプリケーションの例として、USドルに対するEther(あるいは別の暗号通貨)の価格変動に対して、リスク回避をおこなう smart contract がありますが、 これを行うには、ETH/USD の価格がいくらであるかを知るための contract が必要となります。 いちばんシンプルな実行方法としては、必要に応じて contract を更新する能力をもつように設計された(NASDAQの会社組織のような) 特定の「パーティ」(利害関係が一致し、結託した参加者の集合、党)により維持管理される「 データフィード contract 」を通す方法があります。これにより、他の contract はそのデータフィード contract にメッセージを送信し、価格情報が与えられた返答を受け取ることができます。
それらの重要な材料が与えられているとして, リスク回避 contract は次のようになるでしょう :
- パーティ A が 1000 ether 入金するのを待ちます
- パーティ B が 1000 ether 入金するのを待ちます
- 1000 ether の USD での価値を記録します。これはデータフィード contract を探索することで計算され、ストレージに対し、「Xドルだ」と告げます(記録します)
- 30日後、(データフィード contract から得られた新しい価格によって計算された)Xドル相当の ether をAに送信し、 残りをBに送るのに、A もしくは B が 該当 contract を再アクティベートすることができるようにします。
このような contract には暗号商取引における重要な潜在価値があるでしょう。 暗号通貨を取引等に引用するときに現れる主要な問題として、価格変動が大きいということがあります。 多くのユーザや商売人が暗号資産の取引の安全性や利便性を望んでいるかもしれないにもかかわらず、 たった1日で資金の23%を失うという場面には直面したくないでしょう。 この問題に対して、いままでに提案された、最も一般的な解決策としてあるのは、発行者の後ろ盾のある資産です。 この考えは、発行者が発行並びに無効化の権利を有した副次通貨をつくり、 金やUSDのような特定の原資産の一単位をオフラインで提供する全ての人に対し、その副次通貨の一単位を提供するというものです。 そして発行者は、その副次資産が送り返されたときには、原資産を提供することを約束します。 この仕組みによって、全ての非暗号化資産が、暗号資産へと "上場" されることが可能となりますが、これは発行主体が信用可能であることにより実現します。
しかし実際は、発行主体は常に信用に価するとは限らず、 中には、その銀行システムはあまりにも脆弱であったり、 あまりにも顧客対抗的であるようなことが見受けられ、 このような金融サービスは実現し難いものとなりえます。 金融ディリバティブ はこれに取って代わります。 金融ディリバティブにおいては、資産を裏付ける資金を提供する単一の発行主体の代わりに、 分散型の投資市場、つまり ETH ような基準となる暗号資産の価格が上昇するか賭けをする場所、がその役割を担います。 発行主体とは違って、投資家は自分たちの都合で売り出しをなかったことにすることができません。というのは、「 ヘッジング contract 」がエスクローとして資金を保持しているからです。この方法でも、まだ完全に非中央集約化したわけではないことに注意してください。というのは、価格表示器を提供するのに信用あるデータソースが必要となります。とはいうものの、インフラに対する要求事項を減らし(副次通貨の発行主体となるのとは違って、価格データの発行はライセンスが必要とされず、表現が自由な範疇に分類される可能性が高いのです)、かつ詐欺の可能性を減らした点で大きな進歩と言えます。
すべての代替暗号通貨のなかでいちばん早くに登場した Namecoin は、 名前登録サービスに Bitcoin と似た blockchain を用いる試みを行いました。 そこでは、ユーザは他のデータとともに 名前 を公共的なデータベースに登録することができます。 Namecoin の最も広く普及した利用方法は、DNS システムとして使う方法で、 "bitcoin.org" のような名前を、IPアドレスに対応( mapping )づけたものです。 他の使用方法として、email authentication や、潜在的発展性のある reputation システム などが考えられます。 以下に、Namecoin に似た名前登録システムの Ethereum 上での、基本 contract を示します。
def register(name, value):
if !self.storage[name]:
self.storage[name] = value
contract はとてもシンプルです。 システムの全容は、追加のみが可能で削除および修正が不可能な Ethereum ネットワーク内部にあるデータベースです。 誰でも、幾つかの値とともに名前を登録することが可能で、その登録内容は永遠に保管されます。 より洗練された名前登録 contract は、他の contract がその内容を探索できるようにするための 関数節( (内部)関数 )をもつでしょう。 同様に、(例えば、初期登録者のような) 名前の所有者 がデータを変更したり所有権を移行したりするためのメカニズム のようなものも考えられます。 reputation や web上の信用度 といった機能性さえ、システムの上層に追加可能です。
過去数年にわたり、オンライン上でのファイルストレージ・サービスのスタートアップが出現し、たくさんの非常に人気あるものが生まれました。 一番人気のあるのが、Dropbox です。ユーザはハードドライブのバックアップをアップロードし、保管してもらうことが可能で、月額使用料と引き換えにそのデータにアクセスできます。 しかしながら、使用料金支払いの点でファイルストレージの市場は比較的非効率です。 この使用料金問題に関する様々な現存の解決方法を概観しても、" uncanny valley "と呼ばれる、20-200 GBレベルでは、無料利用や企業割引が全く存在せず、ファイルストレージのアクセスに対する月額料金は、同等容量のハードドライブの調達に要する全コストをたった一ヶ月のうちに上回ってしまいます。 Ethereum の contract によって、分散型ファイルストレージという新しい経済圏を開発することが可能で、そこでは、個人ユーザが自分のハードドライブを貸し出すことで、小遣い稼ぎが可能となり、さらに未使用領域が使用されれば、ファイルストレージのコストは下がります。
そのようなデバイスを裏で繋ぎとめておくための 鍵 として、" 分散型 Dropbox contract " と命名したものがあります。 この contract は次のように動作します。
- まずはじめに、保存したいデータをブロックに分割し、プライバシーのために各ブロックを暗号化し、 その暗号化したブロック群から、(データ保管木として)ひとつのマークル木を作り上げます。
- N ブロック毎に、contract は マークル木からランダムに参照先を選び、 (ランダム性を提供するものとしては直前のブロックハッシュを使用し、contract コードでアクセスできるようにします)、 そのデータ木におけるその特定の参照先におけるそのブロックの所有のSPV証明のようなもの(ブロックを預けた人は当然ながら秘密鍵を持っており、その預け人の出すクイズに対して簡潔に回答した証明書)を載せたトランザクションを一番はじめに提供した個人に対して、X ether を与えます。
ユーザがそれらのファイルを再ダウンロードしたいときは、 micropayment channel プロトコル を使用することができ、 (例えば 32 KBで 1 szabo 支払うといった具合で、) ファイルを復元することできます。 micropayment channel を利用した最も支払い効率のよい方法は、 支払い者がその終わりまでトランザクションを発行せず、 かわりに、そのトランザクションを32KB毎に同じノンスを使用して 微量ではあるもののより利益を生むトランザクションに置き換え続けるというやり方です。
この 分散型 dropbox protocol の重要な性質として、 預け人はたくさんの乱雑なノードがファイルを忘れてしまうという決定をしないものと信用しているように見えるかもしれませんが、 秘密共有を通して、ファイルをたくさんの断片へと分割することで、また各断片がどこかのノードに未だに保存されていることを確認するために contract を監視することで、そのリスクは限りなくゼロに近づきます。 もし、その contract がお金の支払いを続けていたならば、それは、誰かまだファイルを所有している人がいるといった 暗号学的証拠 を提供していることとなります。
分散型自律組織 Decentralized autonomous organization (DAO) の一般的な概念としては、 会員あるいは株主が、67%以上の多数派を占めると、contract コードの修正や、資金の消費が可能となる、仮想団体としてのものです。 会員であれば、まとまることで資金の使い道を決定することができるでしょう。 資金の使い道としては、懸賞金、給料、あるいは、労働報酬として使用価値のある域内通貨のような、 異文化地域における仕組みにさえ、適用するこができます。 これは基礎的に、 伝統的な会社や非営利組織を合法的にとらえることのできる枠組みでありますが、 執行に際し使用するのは、暗号理論に則った blockchain テクノロジー だけとなります。
DAO の議論をさらに進めると、配当株主や株券をともなう 分散型自律株式会社 DACorp (decentralized autonomous corporation) といった資本主義を推し進めるモデルに行き当たりました。 代案としてある、分散型自律共同体 DACom (decentralizd autonomous community) では、 会員の除名あるいは入会を承認するといった決定に関し、全会員が平等に権利を保持し、在籍会員の67%の承認を必要とします。 というのは、一人一会員のみという要望があれば、グループによってまとまって執行される必要が有るのです。 (非中央型自動株式会社では、当然大株主が決定権を支配するので、こういった要望は、却下されるでしょう。)
DAO をコード化する方法の概要は次のようになります。 一番シンプルな設計を示しますと、それは「もし、2/3の会員が賛同すれば、変更する」といった 自己修正コード です。 理論的には contract コードは不変なものですが、 別のところに contract を複数保持し、 ストレージは修正可能なので、そこに呼び出す contract のアドレスを保持することで、 事実として、contract の書き換えが可能となります。 DAO contract のようなものの簡素な実装において、そのトランザクションが提供するデータによって、 三種類に分けることができます。
-
[0,i,K,V]
to register a proposal with indexi
to change the address at storage indexK
to valueV
-
[0,i]
to register a vote in favor of proposali
-
[2,i]
to finalize proposali
if enough votes have been made
contract はこれら各種類ごとに、複数の条項を持つでしょう。 contract は、誰が投票したかというリストに従い、全オープンストレージの書き換えを維持管理するでしょう。 さらに、contract は、全会員のリストも保持するでしょう。 どんなストレージの変化も、それが投票する会員の2/3に達したとき、ある最終決定トランザクションがその変化を執行できることとなるでしょう。 より洗練された枠組みとしては、 トランザクションの送信、会員の除名や入会のような特徴を組み込んだ投票システムを保持するものもあり、 そして流動的民主主義 Liquid Democracy スタイルの代議員議会の投票でさえ提供可能です。 (※誰でも代議員選出が可能で、その選出投票は、遷移的であり、結果、もしAがBを、BがCを選出したならば、CはAの投票権を保持することになります。) この設計であれば、DAO は分散型コミュニティとして、有機的成長を遂げることが可能で、 民衆は結果的に、会員の選出作業を専門家に委任することが可能となります。 しかし、これは "現行の政治システム"にみうけられるようなものとは異なり、 個々のコミュニティメンバが提携先を変えることで、時間軸上において、専門家は簡単に出現と消失(取り替え)することが可能です。
代わりとなる分散型株式会社のモデルでは、0以上の株式をもつアカウントがあり、株式の 2/3 が決定に必要とされます。 完璧な枠組みとしては、財産管理機能や、株式売買の申請機能および受諾機能を備えたものがあるでしょう。( contract 内部に注文一致させる機能があることが望ましいでしょう) 代議員選出による委任は、流動的民主主義を存在させ、" 意思決定機関 " という概念を一般化するものでしょう。
1. 預金ウォレット. 次のような場面を考えて下さい。アリスは、自分の資金を安全に管理したいとします。 しかし彼女は、資産を失うことや秘密鍵がハッキングされることを心配しています。そこで彼女は、銀行となるボブとともに、 contract をつくり、ether をその中に保管します。それは以下のようになります。
- アリスは自分一人で1日あたり最大資金の1%を引き出すことが可能です。
- ボブは自分一人で1日あたり最大資金の1%を引き出すことが可能です。しかし、アリスは自分の秘密鍵でこのボブの能力を奪い去るトランザクションを作成することができます。
- アリスとボブは一緒であればどんな額でも引き出し可能です。
通常、1日1%というは、アリスにとって十分な額であり、もしそれ以上引き出したいのであれば、ボブに頼めば済む話となります。 もし、アリスが秘密鍵をハッキングされたならば、アリスは、ボブのところに駆け寄り、ふたりで新しい contract に資金を移します。 もし、彼女が秘密鍵をなくしてしまえば、結果として、ボブは資金を引き出すことになるでしょう。 もしも、ボブが悪意をもっているとわかったならば、アリスは、ボブの引き出し能力を消去できます。
2. 農作物保険. 金融ディリバティブ contract は簡単に作成可能ですが、データフィードとして、価格表示器でなく天候を使用します。 アイオワ にいる農家が、逆にアイオワ における降水量を基盤として逆に支払いをするディリバティブを購入したとすると、 もし干ばつがあったならば、農家は自動的にお金を受け取り、もし十分な降水があったなら、作物が同様の働きをしてくれるので、農家は幸運を手に入れることができます。これは一般的に、自然災害の保険にも拡張可能です。
3. 分散型データフィード. 金融 contract その他において、"SchellingCoin" と呼ばれるプロトコルを通してデータフィードを分散化することが実際可能です。 SchellingCoin は基本的に次のように動作します。 N 個のパーティが全て、ある与えられた一つのデータ(例えば ETH/USD の価格)の値をそれぞれ提供するものとします。 その価格の値はソートされ、その値の順番が 25% ~ 75% であるものが、報酬を得られるようにします。 全員が、他の全員が提供するだろう答えを提供するインセンティブを保持し、その大多数のプレイヤが現実的に認める唯一の価格が、明白な基準となり、これは信用のおけるものとなります。 これによって、理論的にどんな数値をも提供することが可能な、分散型プロトコルが作られます。 それには、ETH/USD価格、ベルリンの気温、あるいは特定の重い計算の結果、でさえ含まれます。
4. スマート・マルチシグネチャ 認証. Bitcoin では マルチシグネチャ・トランザクション contact が可能で、例えば、5つの秘密鍵のうち、3つが揃えば資金を使用できるといったものです。 Ethereum では、より詳細な設計が可能です。たとえば、5つのうち4つで全て使用可能とし、5つのうち3つで1日10%使用可能とし、5つのうち2つで1日0.5%使用可能とすることができます。 加えて、Ethereum マルチシグネチャは同期します。というのは二つのパーティが、別々の時間に blockchain 上に署名を登録することが可能で、その最後の署名が行われれば、自動的にトランザクションは送信されます。
5. クラウド・コンピューティング. EVM テクノロジは、検証可能な計算環境を構築する目的でも使用され、 ユーザは他人に対して、計算の実行を依頼することができます。またオプションとしてランダムに選択したチェックポイントにおける、計算の整合性を示した証拠の提出を依頼することができます。 これによって、クラウド・コンピューティングの市場を作ることが可能で、どんなユーザでも、デスクトップ型あるいはノートパソコンあるいは特化型サーバを用いて参加することが可能です。そして、セキュリティ課金を用いたスポットチェックにより、システムが信用に足るかということを確かめます。(結果ノードはチートすることによって、より利益を得ることはできません。) このようなシステムは、あらゆるタスクに適する、ということはないかもしれません。たとえば、内部プロセスにおける高度な連携が必要なタスクだと複数のノードによる大きなクラウドにおいて、簡単に計算することは不可能です。 しかしながら、他のタスクは容易に並列化可能で、SETI@home 、folding@home や 遺伝的アルゴリズム のようなプロジェクトは簡単に、プラットフォーム上に構築可能です。
6. P2P 賭博. P2P賭博プロトコルはいくらでも実装可能で、例えば、 Frank Stajano と Richard Clayton による Cyberdice は Ethereum blockchain 上で実装できます。 簡素な賭博プロトコルは実はただの次のブロックのハッシュ値を当てるだけの contract で、より進化したプロトコルはそこから作り上げることが可能で、チート不可能な手数料が0に近い賭博サービスを作ることができます。
7. 市場予測. SchellingCoin あるいは Oracle が提供されることで、市場予測もまた実装が容易となります。 市場予測と SchellingCoin が一緒になることで、非中央組織の統治プロトコルである futarchy の主流アプリケーションとしては初のものと成る可能性があります。
8. blockchain 上の商取引市場, Identity と Reputation のシステムを基盤とします。
Greedy Heavist Observed Subtree (GHOST) は、Yonatan Sompolinsky と Aviv Zoharによって2013年12月に初めて導入されたイノベーションです。 GHOST開発の動機は、blockchain の検証時間を短縮すると、 現行のシステムでは、「非同期状態」(最新のブロックと同期していない状態)の割合が増えるため、 セキュリティを減少させてしまうという問題に苦しんでいます。 というのは、ブロックはネットワークを通して伝播するのにある程度の時間がかかるため、 もし、マイナーAがブロックを発掘し、つぎにマイナーBがたまたまAのブロックがBに伝わってくる前にその他のブロックを見つけた場合、 マイナーBのブロックは最終的に無駄となり、ネットワークセキュリティに貢献しないこととなります。 さらには中央集約の問題があります。 それは、もしマイナーAが30%の採掘能力を持つマイニングプールで、Bが10%の採掘能力を持つものとすると、 Aには、採掘時間の70%は無効なブロックを生成するリスクがあり、 (採掘時間の30%のあいだ、Aは有効な最終ブロックを生成しているということなので、採掘データをすぐに得る事ができます。) 一方、Bには、採掘時間の90%は無効なブロックを生成するリスクがあります。 このよう状況で、 ブロック生成の間隔が「非同期状態」の割合が高くなるぐらいに十分、ブロック間のインターバルが短いと、 Aは、単に自身のプールのサイズから得られる効能によって、実質上さらに効率的となります。 これら二つの効果が結びつくことで、 ブロック生成の速いブロックチェーンは、ネットワーク上の採掘能力のうち大きな割合を占めやすくなり、 マイニングのプロセス全体をコントロールできるマイニングプールを生み出してしまいます。
Somopolinsky と Zohar の説明によると、 GHOSTは、最長チェインの計算上において、無効ブロックを採り入れることで、 一つ目のネットワークセキュリティ損失の問題を解決します。 つまり、親ブロックや先祖ブロックのみでなく、 proof-of-workの裏付けされネットワーク上で最長チェインを誇る、 先祖ブロックの無効な子孫ブロック ( ethereum 用語では 「 uncle (叔父) 」) が計算に加えられます。 二つ目の中央集約のバイアスがかかるという問題を解決するためには、 Somopolinsky と Zohar によって描かれたプロトコルのさらに先を考える必要があり、 無効ブロックへの報酬を供給する必要があります。 無効ブロックは元となる報酬の87.5%を受け取り、 uncle として無効ブロックを採り入れた nephew (甥)ブロックには残りの12.5%が贈られます。 しかしながら、トランザクション手数料は uncle には与えられません。
Ethereum は、7層だけ遡る簡易版 GHOST を実装しました。 仕様としては以下の通りです。
- A block must specify a parent, and it must specify 0 or more uncles
- An uncle included in block B must have the following properties:
- It must be a direct child of the kth generation ancestor of B, where 2 <= k <= 7.
- It cannot be an ancestor of B
- An uncle must be a valid block header, but does not need to be a previously verified or even valid block
- An uncle must be different from all uncles included in previous blocks and all other uncles included in the same block (non-double-inclusion)
- For every uncle U in block B, the miner of B gets an additional 3.125% added to its coinbase reward and the miner of U gets 93.75% of a standard coinbase reward.
この制限版の GHOST では、7世代上までの uncle を取り込みますが、これが採択されたのには2つの理由がありました。 ひとつめとして、無制限の GHOST だと、与えられたブロックに対し、どの uncle が有効なのか確かめる計算が複雑になりすぎます。 ふたつめとして、無制限の GHOST と Ethereum で使用されている報酬の方法が合わさると、採掘者が、メインチェイン上で採掘する動機を取り去ってしまい、攻撃者のチェインにおいてはそうでないので、攻撃されすくなります。
blockchain 上に発行される全トランザクションは、ネットワークに対し、 ダウンロードと検証に際し必要なコストの支払いを強いるので、 乱用を防ぐために、トランザクション手数料に代表される、何らかの規制メカニズムが必要となります。
Bitcoin でとられている初期のアプローチでは、純粋な寄付金としての手数料をとり、 採掘者に対し、「門番」の役割と動的な最小額を決める役割を依頼しています。 このアプローチはBitcoinコミュニティには好意的に受け入れられました。 これには、採掘者とトランザクション送信者間の需給バランスにより価格が決まる、といった市場原理に基づくという理由があります。 しかしながら、この論理の道筋には問題があって、トランザクションの処理は市場ではないのです。というのは、 トランザクションを採掘者が送信者にオファするサービスと捉えることには本質的魅力がありますが、 実際は、採掘者が採り入れた全トランザクションは、ネットワーク内の全てのノードにおいて処理される必要があるため、 トランザクション実行のための大きなコストはサードパーティによって担われ、 あるトランザクションを取り入れるかどうかの決定は採掘者に担われている訳ではないのです。 このような仕組みでは、コモンズの悲劇の問題が発生する確率が非常に高いのです。
市場原理に基づくメカニズムにおけるこの欠陥が明るみにでましたが、 ある特定の厳密でないシンプルな仮定のもとで、その欠陥を手品のようにキャンセルすることができます。 論拠は以下のようなものです。
-
k
個のオペレーションを含むトランザクションに対して、送信者がそのオペレーションを含める採掘者に対してkR
の報酬をオファーする。ここで、R
は送信者によって決定され、k
とR
は採掘者に対しておおよその値が事前に分かるようにする。 - 一つのオペレーションはどのノードにとっても
C
という実行コストを持つ(すなわち、すべてのノードは同じ効率をもつ) -
N
個のマイニングノードが存在するとき、それぞれは全く同じ処理能力を持っている(すなわち1/N
である) - 採掘をしない フルノード は存在しない
採掘者は、期待できる報酬がコストより大きければ、トランザクションを喜んで処理します。
そして、採掘者が次のブロックを見つける確率は1/N
なので、予想される報酬は kR/N
となり、
採掘者にとっての処理コストはkC
だけです。
このように考えると、採掘者は kR/N > kC
つまり R > NC
の時、トランザクションを取り込みます。
ここで、R
は送信者がオペレーション処理の前に支払う手数料で、
送信者がトランザクション送信による利益を享受するのに必要な最低料金となります。
NCはオペレーションを処理するためのネットワーク全体のコストであり、
よって、採掘者は、実利のトータルがコストを超えるトランザクションだけを取り入れようとします。
しかし、実際の仮定では、いくつか重要な逸脱が生じます。
- 採掘者は実際には他の検証ノードよりもトランザクション処理に高いコストを払う事があります。それは、追加の検証時間がブロックの伝搬を遅らせ、ブロックが無効になる可能性が増加するためです。
- 採掘を全くしないフルノードが存在します。
- 現実には採掘能力の分散は非常に不平等なものとなります。
- 投機家、政敵、ネットワークの存在に対して攻撃を仕掛ける道具をもった狂人が存在しまう。彼らは頭が良く、contract において、自分たちのコストが他の検証ノードが払うコストよりもかなり低いような環境を設定します。
(1)は採掘者が少ししかトランザクションを取り込まない傾向を生み出してしまいます。
(2)はNC
を増加させます。よって、(1)と(2)は、少なくとも互いに部分的にキャンセルします。
(3)(4)は重要な問題です。これらの問題を解決する方法としては、単純に上限を設定しました。
どのブロックもBLK_LIMIT_FACTOR
回 x 長期指数関数移動平均
以上のオペレーションを行うことはできません。
つまり、
blk.oplimit = floor((blk.parent.oplimit * (EMAFACTOR - 1) + floor(parent.opcount * BLK_LIMIT_FACTOR)) / EMA_FACTOR)
BLK_LIMIT_FACTOR
と EMA_FACTOR
は、当分は、65536と1.5に設定される定数で、さらに解析が進めば、変更される可能性があります。
Bitcoin に見られる大きなブロックを推奨しない別の理由として、 大きなブロックは伝播するのに、時間がかかります。 そして、このように、高確率で新鮮でないものとなってしまいます。 Ethereum においては、ガス消費量の大きいブロックも同様に伝播するのに時間がかかります。 それには、物理的に大きいトランザクションの状態遷移を検証するのに時間が掛かるという双方の理由があります。 この遅延がゆえの非推奨はBitcoin においては重要な問題ですが、 Ethereum においては、GHOST プロトコルのおかげでそれほど問題ではありません。 このように、ブロックを規制することにより、より安定した基盤工程ができあがります。
Ethereum 仮想マシン が チューリング完全 だというのはとても重要なことです。
これは、EVMコード が無限ループを含む計算もコード化できることを意味します。
EVMコード は二つの方法でループを可能にします。
第一に、
JUMP
命令はプログラムにコードの以前のどこか指定した場所へジャンプします。
JUMPI
命令はwhile x<27; x= x*2
のような条件分岐を可能にします。
第二に contract は別の contract を呼ぶ事ができ、
潜在的に再帰によりループが可能となります。
この方法では当然問題に行き当たります。
悪意をもったユーザは、無限ループに陥らせる事で採掘者を黙らせ、フルノードをダウンさせることができるのか?という問題で、
これは、コンピュータサイエンスの「実行停止問題」として知られる問題を浮かび上がらせます。
実行停止問題とは、一般的に与えられたプログラムがいつまでも停止しないかどうかを知る方法が無いというものです。
"状態遷移の章" で説明したように我々の解決方法は、 トランザクションに対し、許される最大の計算ステップ数を設定し、もし実行が長引けば計算を元に戻し、費用だけを支払うといったもので、 メッセージも同じ方法をとります。 我々がこの解法を選んだ動機を理解するために、以下のような例を考えてみましょう。
- 攻撃者が、無限ループを引き起こす contract を作り、採掘者に対してそのループを引き起こすトランザクションを送信します。 採掘者はトランザクションを実行し、無限ループを実行し、そして燃料が切れるのを待ちます。実行は燃料切れになり、途中で止まりますが、トランザクションはまだ有効であり、採掘者は各実行ステップのための手数料を攻撃者に要求し続けています。
- 攻撃者は非常に長い無限ループを作り、数ブロックが認証されるほどの時間、採掘者を計算させ続け、採掘者がトランザクションを含めて手数料を要求することを不可能にさせます。しかし、攻撃者は計算ステップ数の上限を決める
STARTGAS
の値を提供する必要があるので、採掘者は計算が非常に大きなステップ数であることを前もって知ります。 - 攻撃者は
send(A,contract.storage[A]); contract.storage[A] = 0
のようなコードを持った contract を見て、最初のステップのみ実行できて二番目のステップは実行できないような量の燃料を持ったトランザクションを送付します。 (つまり、引き出しはするが差額を減らさせない)。contract の作者はそのような攻撃に対する防御を考える必要はない。なぜならば、実行が途中で終わる時には状態の変化は元に戻ります。 - ある金融 contract がリスクを減らすために9つの固有のデータフィードの中央値をとるとします。DAO の章で説明したような、呼出アドレスを変数化するメカニズム を通して変更可能な設計をされている一つのデータフィードを攻撃者は乗っ取り、無限ループを引き起こすように変更し、金融 contract から資金を要求するものを燃料切れにしていきます。しかしながら、金融 contract は、メッセージ上で燃料の上限を設定できるので、このような問題は防ぐ事ができます。
チューリング完全 に取って代わるものは、チューリング不完全 です。JUMP
や JUMPI
命令は存在せず、
コールスタックにはそれぞれの contract の一つだけのコピーが存在できます。
このシステムではこれまでに述べた手数料システムや我々の解決策の効果についての不確実性は必要なくなります。
なぜなら contract を実行するコストはそのサイズによって上限が決まるからです。
さらに、チューリング不完全 はそれほど大きな制約ではありません。
というのは、我々が内部で想像した全ての contract の例で、一つのみがループを必要とし、
さらにそのループはコードを26回繰り返す事によって取り除くことができました。
チューリング完全 のもたらす厳しさや限定された利益を考えた時、
何故チューリング不完全な言語を使用しないのでしょうか?
しかし実際は、チューリング不完全では、与えられた問題の正しい解決からはほど遠いものです。
その理由を知るために、以下のcontractを考えましょう。
C0: call(C1); call(C1);
C1: call(C2); call(C2);
C2: call(C3); call(C3);
...
C49: call(C50); call(C50);
C50: (run one step of a program and record the change in storage)
いまあるトランザクションをAに送ります。 このように、51個のトランザクションにおいて、250 の計算ステップを持つ contract を保持するものとします。 採掘者はそれぞれの contract に付随する、 最大の計算ステップ数や、contract が呼出す contract を前もって見る事によって そのような論理爆弾を事前に察知することが可能ですが、これには、採掘者が他の contract を作り出す contract を禁止する必要が有ります。 (なぜなら、上記の 51 個の contract の生成と実行は簡単に一つの contract に書き記すことができるのです。) 他の問題となるポイントはメッセージのアドレスフィールドが変数であり、一般的に contract が呼出す他の contract を事前に理解することが不可能なことです。 よって、我々は驚くべき結論を得ます。 チューリング完全 では驚く程容易に管理でき、 一方、チューリング不完全 では、チューリング完全と同じ機能を持たせようとすると、驚く程管理が難しくなります。 そのような場合、チューリング完全にしない理由はありません。
Ethereum ネットワークは、ネットワークに組み見込まれた自身の通貨Etherを持っています。この通貨は二つの目的で使われます。一つ目は、多様なデジタル資産間の効率的な交換を可能にする、基本的な流動性レイヤーを提供する事です。二つ目はより重要ですが、トランザクションフィーを支払うメカニズムを提供する事です。話を簡単にするため、また今後の議論を避けるため(Bitcoin における mBTC/uBTC/satoshi に関する現在の議論を参照してください)、通貨の単位は予め決まっている予定です。
- 1: wei
- 1012: szabo
- 1015: finney
- 1018: ether
これは、"ドルとセント"、あるいは" BTC と satoshi "の概念を広げたものと考えられるはずです。近い将来、ether は通常のトランザクションで使用され、finney はマイクロトランザクションで使用され、szabo と wei は手数料やプロトコル実装のテクニカルな議論で用いられると予想しています。他の単位は、今後役立つ事として、現時点では、クライアントで利用するべきではないでしょう。
Ether 発行のモデルは以下の通りです。
- Etherは1BTCあたり1000-2000 ether で、プリセールにて公開される予定です。これは、Ethereum Organization の資金調達と開発資金の調達を目的としており、Mastercoin や NXT のような他プラットフォームでも使われ、成功している方法です。より早く購入した人はより大きなディスカウントを得る事ができるでしょう。プリセールで得られたBTCは、全て、開発者の給与や報奨金の支払いに使われます。また、Ethereum や仮想通貨エコシステム内の、様々な営利または非営利プロジェクトへの投資に使用されます。
- 0.099 x プリセール総販売額 ( 60,102,216 ETH ) は、Ethereum Organization へ割り当てられ、初期に貢献した人達への報奨金と、ジェネシスブロック生成開始前のETH建て経費の支払いに利用されます。
- 0.099 x プリセール総販売額は 、長期準備金として維持管理されます。
- 0.26 x プリセール販売額は、それ以降ずっと、1年毎にマイナーへ割り当てられます。
Group | At launch | After 1 year | After 5 years |
---|---|---|---|
Currency units | 1.198X | 1.458X | 2.498X |
Purchasers | 83.5% | 68.6% | 40.0% |
Reserve spent pre-sale | 8.26% | 6.79% | 3.96% |
Reserve used post-sale | 8.26% | 6.79% | 3.96% |
Miners | 0% | 17.8% | 52.0% |
長期的な供給量の成長率(パーセント)
通貨発行量は線形増加するが、Bitcoin と同様、長期的には供給量の成長率はゼロに収束してゆく
上記モデルの主な特徴は、(1)基金プールとその規模、(2)Bitcoinにおける"供給量上限ありモデル"とは対照的な"供給量成長モデル"、の二つです。
基金プールが正当である理由は次のとおりです。もし基金プールが存在せず、同じインフレ率を実現するために発行量を0.217倍に減少させたとすると、ether の全供給量は16.5%減り、ether 1単位の価値は19.8%上昇するでしょう。従って、均衡を成立させるなら、19.8%多くの ether がセールで購入されれば、1単位が再び以前と全く同じ価値を持つことになるでしょう。Ethereum Organization は、1.198倍のBTCを持つことになりますが、これは、オリジナルのBTCと追加の0.198xのBTCの二つに分ける事ができます。従って、この基金プールなしの状況は、基金プールがある状況と 完全に等価 ですが、一つだけ重要な違いがあります。それは、Ethereum Organization が純粋にBTCを保持しており、ether の価値を維持するインセンティブを持たないという事です。
"供給量成長モデル"は、Bitcoin における富の集中リスクを減らします。そして、現在および今後、個人に公平な通貨の獲得機会を与えます。同時に、"サプライ成長率"はゼロに収束していくため、Etherを得て保持しようという強いインセンティブを維持します。また次のような理論化ができます。コインは、不注意、死、その他の理由で時と共に失われており、コインの消失は一年あたりの総供給量に対する割合としてモデル化できます。そして、全通貨供給量は、年間発行量を消失率で割った値に落ち着きます。(例えば、損失率が1%の場合、供給量が26Xに到達すると、0.26Xがマイニングされて、0.26Xが毎年失われるので、均衡状態が成立します)。
将来、Ethereum はセキュリティのため proof of stake モデルに切り替える可能性が高いことに留意してください。これにより、発行量の必要条件は年間0から0.05Xの水準に減ります。Ethereum Organization が資金を失ったり、他の理由で消滅した場合に備えて、"social contract"を残します。誰もが 次世代版の Ethereum を作る権利があり、唯一の条件は ether の総額が最大で 60102216 * (1.198 + 0.26 * n)
( n
: ブロック生成開始からの年数 ) に等しくなければならないという事だけです。クリエイターは開発費用を捻出するために、自由にクラウドセールを行ったり、PoS による供給拡大と供給拡大の上限との差の一部または全てを自由に使用することができます。socail contract に準拠しないアップグレード版の候補は、準拠版として公正にフォークされる可能性もあります。
Bitcoin のマイニングアルゴリズムは、毎回少しずつ異なるブロックヘッダー上で、マイナーにSHA256の演算を何百万回も繰り返し、最終的に一つのノードがあるターゲット(現在は2192)以下のハッシュ値を見つけるまで、計算させることで機能しています。しかし、このマイニングアルゴリズムは、二種類の一極集中に対する脆弱性を持っています。一つは、マイニングのエコシステムが、Bitcoinマイニングのタスク用にデザインされ、数千倍の効率を持つASIC(application-specific integrated circuits)に支配されるようになってきているという事です。つまり、Bitcoin のマイニングは、もはや分散化されているわけでも平等を追求しているわけでもありません。マイニングに参加して報酬を得ようとするなら、数百万ドルが必要になります。第二に、殆どのBitcoinマイナーはブロックの検証プロセスを実際はローカルでは行っていません。その代わり、ブロックヘッダを供給するために、一極集中したマイニングプールに依存しています。この問題は、おそらくもっとひどいものです。この文章を書いている時点で、トップ3のマイニングプールが、間接的にBitcoinネットワークの約50%の計算パワーをコントロールしています。(もし、あるマイニングプールや結託したマイニングプールが51%攻撃をしようとした場合、マイナーは他のマイニングプールへ移る事でこの状況は緩和はできるけれども)
現在 Ethereum が使用しようとしているアルゴリズムでは、マイナーは、ブロックチェーンの「状態」をもとに ランダムなデータ を作り出し、ブロックチェインの最後のNブロックからランダムに選ばれたトランザクションを計算し、結果のハッシュを返す事が要求されます。これは二つの重要な利点があります。第一に、Ethereum の contract はどのような種類の演算も取り込む事ができるため、Ethereum用のASICは汎用的な計算用のASICになるでしょう ー すなわち、より良いCPUです。第二に、マイニングが、完全なブロックチェインへのアクセスを要求します。その結果、マイナーに、完全なブロックチェインの保持、そして少なくとも全てのトランザクションが検証できることを強制します。これは一極集中したマイニングプールの必要性を取り除くことになります。マイニングプールは、報酬分配の確率を平準化する役割を果たしていますが、このマイニングプールの機能は、P2Pプールによって中央的な管理無しで、同じくらい上手く実現できます。
このモデルはまだテストされていません。そしてマイニングアルゴリズムとしてcontractを実行する時、途中で巧妙な最適化を避けるのは困難かもしれません。しかし、このアルゴリズムの面白い特徴の一つは、大量のcontractを、ある種類のASICを妨害するよう特別に設計されたブロックチェインに導入する事で、誰でも井戸に毒を盛る事ができるということです。ASIC 製造者にはお互いにそのようなトリックを使って攻撃する経済的なインセンティブが存在します。よって、我々が開発中のソリューションは、純粋なテクニカルなものというよりも、突き詰めると経済的、人間的なものです。
Ethereumに関するよくある懸念点の一つは、スケーラビリティの問題です。Bitcoin のように、Ethereum では「全てのトランザクションがネットワーク上の全てのノードで実行される必要がある」という欠点があります。Bitcoin の現在のブロックチェインのサイズは約15GBであり、一時間ごとに1MB増加しています。もし Bitcoin ネットワークが Visa のように一秒当たり 2000 トランザクション を処理するとした場合、3 秒当たり1MB(1時間あたり1GB, 一年当たり8TB)増加することになります。Ethereum も同じ成長パターンを経験するでしょう。Bitcoin のようなただの通貨とは異なり、Ethereum ブロックチェイン上に様々なアプリケーションが存在するという事は、この成長パターンを悪化させるでしょう。しかし、Ethereum のフルノードは、ブロックチェインの全ての履歴に代わり、状態だけを保持すれば良いという事は、この成長パターンを改善するでしょう。
このような巨大なブロックチェインサイズに関する問題は、中央集権化のリスクです。仮にブロックチェインのサイズが100TBになったとします。このとき想定されるのは、非常に少数の大企業がフルノードを稼働させる一方、通常のユーザーはライトなSPVノードを使うというシナリオです。そのような状況では、フルノードが、利益を得るために結託して不正行為に合意するかもしれないという、潜在的な懸念が発生します。(例えば、ブロック報酬を変更する、自分達にBTCを与える、など)。ライトノードは、これを即座に検知する方法がありません。もちろん、少なくとも一つは正直なフルノードが存在するでしょうし、数時間後には、不正行為に関する情報は、Redditのようなチャンネルを通じて広まるでしょう。しかし、その時点ではもう遅すぎるのです。つまり、与えられたブロックをブラックリストに載せるかどうかは一般ユーザに委ねられており、51%攻撃を摘み取るのと同規模な、大規模かつおそらくは実行不可能な調整の問題なのです。Bitcoin の場合、このことは現在問題になっています。しかしPeter Todd の提案がこの問題を緩和するでしょう。
近い将来、Ethereum はこの問題に対処するため、さらなる二つの対策を採用する予定です。第一に、ブロックチェインベースのマイニングアルゴリズムなので、すくなくとも全てのマイナーがフルノードになる事を強制します。その結果、フルノード数の下限ができます。第二に、さらに重要なのは、各トランザクションを処理した後、ブロックチェイン内部に中間状態木ルートを含めます。たとえ、ブロックの検証が中央集権化したとしても、一つの正直な認証ノードが存在する限り、中央集権問題は検証プロトコルにより回避可能です。もし、あるマイナーが無効なブロックを発行した場合、そのブロックはフォーマットが間違っているか、もしくは状態S[n]
が正しくないか、の何れかに違いありません。S[0]
は正しい事が分かっているので、どこかにS[i-1]
は正しいが、S[i]
は正しくないという最初の状態が存在しなければいけません。検証ノードは、APPLY(S[i-1],TX[i]) -> S[i]
を処理するのに必要なパトリシア木ノードのサブセットから構成される"無効証明"と共に、インデックス i
を提供します。ノードは、これらの検証ノードを、演算の一部として実行したり、与えられたS[i]
と生成されたS[i]
がマッチしない事を確かめたりするのに利用できるでしょう。
もう一つのより洗練された攻撃は、悪意のあるマイナーによる不完全なブロックの発行です。これにより、ブロックが有効かどうかを決定するのに、十分な情報が存在しないことになります。この攻撃に対する解決策は challenge-response プロトコルです。つまり、検証ノードは、ターゲットとなるトランザクションのインデックスの形式で「 challenge 」を発行します。そして、軽量ノードは、あるノードを受け付けると、(マイナーか検証ノードかに関わらず)別のノードが有効証明としてのパトリシアノードの部分集合を提供するまで、ブロックを信用できないものとして扱います。
Ethereum プロトコルは、元々は、アップグレード版の暗号通貨と考えられていました。ブロックチェイン上で、エスクロー、引き出し上限、金融コントラクト、ギャンブルマーケットといった進んだ機能を、高度に一般化されたプログラミング言語を通して提供する暗号通貨です。Ethereum のプロトコルはどんなアプリケーションも直接にはサポートせず、チューリング完全なプログラミング言語のみが存在します。それは、理論的には、どのようなトランザクションやアプリケーションに対しても、任意のコントラクトを作れるということです。しかし、Ethereum について、さらに興味深い事は、Ethereum のプロトコルは単なる通貨を超えているということです。
分散型ファイルストレージ、分散型コンピューティング、および分散型予想市場に関するプロトコルは、その他多くのアイデイアの中でも特に、計算の効率を飛躍的に向上させる可能性があります。そして、その他のP2Pプロトコルを、経済レイヤーを加えることにより、強力に後押しします。最終的には、お金とは全く関係のない数々のアプリケーションが現れるでしょう。
Ethereum プロトコルによって実装された状態遷移関数のコンセプトは、ユニークな可能性を持ったプラットフォームです。Ethereumは、データストレージ、ギャンブル、金融などの特定のアプリケーションを意図したクローズドで単一の目的を持つプロトコルではなく、 オープンな設計になっています。我々は、Ethereumが、今後の金融および非金融の多くのプロトコルの基礎レイヤーとして、 非常に適したものであると信じています。
- Bitcoin のアドレスが公開鍵そのものでは無く、楕円曲線公開鍵のハッシュであることに気づくかもしれませんが、 実際は、公開鍵ハッシュを公開鍵と呼ぶのは、暗号用語としては正しい呼び方です。 これは、Bitcoin の暗号法は、特別なデジタル署名アルゴリズムであるためです。 このアルゴリズムでは、公開鍵は楕円曲線(以下ECC)公開鍵のハッシュから構成され、 署名はECC署名と結合したECC公開鍵から構成されます。 そして、検証アルゴリズムは、公開鍵として与えられたECC公開鍵ハッシュに対して署名内のECC公開鍵をチェックして、 続いて、ECC公開鍵に対してECC署名を検証をします。
- 技術的には、11個前のブロックの中央値です。
- 内部的には 2 も "CHARLIE" も両方とも番号です。 後者は ビッグエンディアンの256ビットベース の表現です。番号は最小で 0 、最大で 2256-1 を取る事ができます。
- [jp-1] ABCD Hashcash パズル : Adam Back's computationally difficult Hashcash puzzles
- [jp-2] エコノミックバリア : 新規事業者がある市場へ参入するのにかかるコスト。https://en.wikipedia.org/wiki/Barriers_to_entry
- Intrinsic value: http://bitcoinmagazine.com/8640/an-exploration-of-intrinsic-value-what-it-is-why-bitcoin-doesnt-have-it-and-why-bitcoin-does-have-it/
- Smart property: https://en.bitcoin.it/wiki/Smart_Property
- Smart contracts: https://en.bitcoin.it/wiki/Contracts
- B-money: http://www.weidai.com/bmoney.txt
- Reusable proofs of work: http://www.finney.org/~hal/rpow/
- Secure property titles with owner authority: http://szabo.best.vwh.net/securetitle.html
- Bitcoin whitepaper: http://bitcoin.org/bitcoin.pdf
- Namecoin: https://namecoin.org/
- Zooko's triangle: http://en.wikipedia.org/wiki/Zooko's_triangle
- Colored coins whitepaper: https://docs.google.com/a/buterin.com/document/d/1AnkP_cVZTCMLIzw4DvsW6M8Q2JC0lIzrTLuoWu2z1BE/edit
- Mastercoin whitepaper: https://github.com/mastercoin-MSC/spec
- Decentralized autonomous corporations, Bitcoin Magazine: http://bitcoinmagazine.com/7050/bootstrapping-a-decentralized-autonomous-corporation-part-i/
- Simplified payment verification: https://en.bitcoin.it/wiki/Scalability#Simplifiedpaymentverification
- Merkle trees: http://en.wikipedia.org/wiki/Merkle_tree
- Patricia trees: http://en.wikipedia.org/wiki/Patricia_tree
- GHOST: http://www.cs.huji.ac.il/~avivz/pubs/13/btc_scalability_full.pdf
- StorJ and Autonomous Agents, Jeff Garzik: http://garzikrants.blogspot.ca/2013/01/storj-and-bitcoin-autonomous-agents.html
- Mike Hearn on Smart Property at Turing Festival: http://www.youtube.com/watch?v=Pu4PAMFPo5Y
- Ethereum RLP: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP
- Ethereum Merkle Patricia trees: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-Patricia-Tree
- Peter Todd on Merkle sum trees: http://sourceforge.net/p/bitcoin/mailman/message/31709140/
- Home
- Ethereum Whitepaper
- Ethereum Introduction
- Uses: DAOs and dapps
- Getting Ether
- FAQs
- Design Rationale
- EVM intro: Ethereum Yellow Paper, Beige Paper and Py-EVM.
- Wiki for (old) website (still a good introduction)
- Glossary
- Sharding introduction & R&D Compendium, FAQs & roadmap
- Casper Proof-of-Stake compendium and FAQs.
- Alternative blockchains, randomness, economics, and other research topics
- Hard Problems of Cryptocurrency
- Governance
- Chain Spec Format
- Inter-exchange Client Address Protocol
- URL Hint Protocol
- Network Status
- Mining
- Licensing
- Consortium Chain Development
- RLP Encoding
- Patricia Tree
- Web3 Secret Storage
- Light client protocol
- Subtleties
- Solidity Documentation
- NatSpec Format
- Contract ABI
- Bad Block Reporting
- Bad Chain Canary
0x927c0E368722206312D243417dA9797424b56434