次世代電子契約及び分散型応用ソフトウェア基盤#03

01 02

採掘
 信頼できる集中型のサービスを利用できる場合には、上述の状態遷移系を実装するのは容易である。単に上に記述されている通りに正確にコード化すれば良いだけである。しかしながら、Bitcoinは分散型の貨幣系を構築しようとしているものである。そのため、利害関係人全員が取引の順序について確実に合意することができることを保証するために、状態遷移系に合意形成系を結合しなければならない。Bitcoinの分散型の合意形成処理においては、ネットワーク上のノードは「ブロック」と呼ばれる取引の集合体の生成を絶えず試行し続けなければならない。ネットワークは約10分毎に1ブロックを生成するように設計されており、夫々のブロックは時刻印(timestamp)、仕事証明の解(nonce)、直前のブロックに対する参照(即ち、直前のブロックの要約値(hash))及び直前のブロックが生成されてから発生した全ての取引の一覧を含む。そして、最新のBitcoinの元帳の状態を表現するために絶えず更新され、時間の経過と共に何処までも成長していく永続的な「ブロック鎖」が形成される。
 ブロック鎖の枠組みにおける、ブロックが有効であるか否かを確認する手続きは次のようになる。
  1.直前のブロックとして参照されているブロックが実在し、有効であることを確認する。
  2.ブロックの時刻印が直前のブロックのものよりも後のものであり、2時間先の未来よりは前のものであることを確認する。
  3.ブロックの仕事証明が有効であることを確認する。
  4.直前のブロックが適用された時点での状態をS[0]とする。
  5.ブロックの取引の一覧をTXとする。TXはn個の取引を有するものとする。0...n-1における全てのiについて、S[i+1] = APPLY(S[i],TX[i])とする。状態遷移関数APPLY(S,TX) -> S'がERRORを返した場合には、偽を返す。
  6.S[n]をブロックが適用された時点での状態とし、真を返す。
 本質的に、ブロックの夫々の取引は有効な状態遷移を生起しなければならない。状態は決してブロックの中に直接的には含まれていないことに注意しなければならない。状態は単に検証を実行するノードによって認知される抽象的な観念であり、初期状態から全てのブロックの全ての取引を逓次に適用していくのが状態を(安全に)算出する唯一の方法である。採掘者が取引をブロックに格納する順序が枢要であることに注意しなければならない。ブロックの中に2つの取引A及びBが存在し、BがAによって作成された未使用の取引出力を使用する場合には、AがBより前に格納されている場合にのみブロックは有効となり、そうでない場合には無効となる。
 ブロック検証手続きにおける興味深い部分は「仕事証明」の概念である。あるブロックの仕事証明が有効であるためには、そのブロックのSHA256要約値を256ビットの数値と見做した場合において、その数値が動的に調整される目標値(target)より小さい値でなければならない。本文書の執筆時点においては、目標値は大凡2の192乗である。この要件の目的はブロックの作成を計算的に「困難」にすることであり、これによりSybil攻撃者は自身の利益になるようにブロック鎖全体を再作成することができなくなる。SHA256は完全に予測不可能な擬似無作為関数となるように作られているので、有効なブロックを作成する唯一の方法は単なる試行錯誤でしかない。即ち、仕事証明の解の候補に繰り返し1を加えていきながら、新たな要約値が要件に適合するか否かを逐一調べていくしかないのである。2の192乗という現在の目標値の下では、仕事証明の解を発見するためには、平均して2の64乗回の試行を繰り返さなければならない。通常の場合、目標値はネットワークによって2016ブロック毎に調整される。これにより新たなブロックは平均して10分毎にネットワーク上の何れかのノードによって生成されることになる。この計算的な仕事に対する褒賞として、夫々のブロックの採掘者は何もない所から自身に対して25BTCを給与する取引を自身の採掘したブロックの中に含めることができる。更には、ブロックに格納されている取引の取引入力の総額面価格が取引出力の総額面価格より大きい場合には、その差額も又、取引手数料として採掘者に給与される。尚、採掘がBTC発行の唯一の方法である。初期状態においては貨幣は1枚も存在しない。
 採掘の目的をより深く理解するために、悪意のある攻撃が実行された場合に何が起きるのかを見てみることにしよう。Bitcoinの根底において利用されている暗号は安全性が確立しているので、攻撃者はBitcoinの仕組みの中で、暗号によって直接には保護されていない部分を標的にすることだろう。即ち、それは取引の順序である。攻撃者の戦略は単純である。
  1.商人に何らかの商品(出来れば、迅速に提供されるデジタル商品が良い)と引き換えに100BTCを送付する。
  2.商品が提供されるまで待機する。
  3.同一の100BTCを自己に送付する別の取引を作成する。
  4.ネットワークに対して、自己に送付する取引こそが最初に発生した取引であると納得させる。
 1の後数分すると、取引は、例えば、ブロック番号が27万のブロックに格納される。約1時間後、更に5つのブロックがブロック鎖に追加される。夫々のブロックは間接的に最初の取引を指し示しており、そのため、最初の取引の「確証度を高めている」。この時点で商人は決済が結了したと認め、商品を提供する。今商品はデジタル商品であると想定しているので、商品の提供は即時に完了する。ここで攻撃者は同一の100BTCを自己に送金する別の新しい取引を作成する。このときただ単に新しい取引をネットワークに公開しただけでは新しい取引が処理されることはない。採掘者は状態遷移関数APPLY(S,TX) -> S'を新しい取引に適用しようとするが、新しい取引が既にSには含まれていない取引出力を使用しようとしていることを検知する。そのため、攻撃者はただ単に新しい取引をネットワークに公開するのではなく、ブロック番号が26万9999のブロックを親ブロックとして参照し、自己のブロック番号が27万となる別の、古い取引の代わりに新しい取引を含む新しいブロックを作成する所から開始し、ブロック鎖の「分岐(fork)」を作成する。ブロックの内容が異なるため、新しいブロックを作成するには仕事証明を再度行う必要がある。その上、新しいブロックは古いブロックとは異なる要約値を有しており、元の、ブロック番号が27万1から27万5までのブロックは新しいブロックを指し示してはいない。そのため、元のブロック鎖と攻撃者の新しいブロック鎖は完全に別物である。ブロック鎖分岐が発生した場合には、最長のブロック鎖が真のブロック鎖であると見做される。そのため、正当な採掘者は元のブロック鎖の下で採掘を行い、攻撃者だけが新しいブロック鎖の下で採掘を行うことになる。攻撃者が元のブロック鎖の長さに追い付いて、自己の新しいブロック鎖を最長のものにするには、ネットワークにおける自己以外の要約値計算能力を併せたものよりも大きな要約値計算能力が必要となる(即ち、「51%攻撃」である)。