PCで苔を育てる人

自作シミュレーションゲームPraparatを作っています。 人工生命をシミュレーションするゲームです。https://www.nicovideo.jp/watch/sm41192001

【後編】仮想通貨の仕組みについて勉強したのでアウトプットしたい

前回 の続きです。

4. 「ブロックチェーン」〜さいきょうのノート〜

 ここまでは安全に取引内容を書き込む方法を紹介してきたが、それを書き込むノートについては何も言ってこなかった。

 ここではどのようなノートに書き込みを行うのが良いかを考えていこう。

4.1 すでに最強では?

 とは言えだ。先程導入したデジタルなハンコのおかげで、既に取引の改ざんや偽造は誰でも検証可能になっている。とすれば、それを何に書き込もうかあまり問題ではないのではないだろうか?

 しかし、実はここには大きな落とし穴がある。先程のデジタルなハンコは、改ざんの検証は出来るが取引内容をまるごと消してしまうことに対しては無力なのだ。

 例えば私があなたに100Sを支払い、その対価として私があなたからリンゴを受け取ることを想定する。

改めて述べておくが、ここでの「支払う」というのは、"支払った"と電子ノートに書き、デジタルなハンコを押すことであって、実際に紙幣などの実体をやり取りするわけではない。

あなたはこの取引内容を検証し、ちゃんと両者のハンコが押されている(取引内容のハッシュ値と、暗号化されたハッシュ値の解読結果が一致する)ことを確認し、今後改ざんされないことを確信してリンゴを渡すのである。

 一見何の問題もないように見えるこのやり取りだが、もし私に悪意があればこの取引自体をなかったことにすることが出来る。つまり、あなたが安心しきってしばらくした後で、しれっとこの取引内容を消してしまえば良いのだ。そうすれば私は100Sを支払ったという事実を消し去り、リンゴのみを手に入れることができる。

4.2 鎖になったノート

 これは困ったことになった。デジタルなハンコは取引内容の削除については無力であった。これを解決するのが、実は先程も活躍したハッシュ関数なのである。

 ここで新たにブロックという概念を導入する。ブロックというのはいくつかの取引をまとめて文字通りブロックにしたものである。それではブロックを使ったノート作成の流れを見てみよう。

 まず、ある程度取引が溜まってきたら、それらをまとめてブロックを作る。

そして、このブロック全体のハッシュ値を計算する。

そしてさらに取引が溜まってきたら、新たなブロックを作るのだが、そのブロックにこのハッシュ値を加える。

これを繰り返して行くことで、ブロックをどんどん数珠つなぎにしていくのだ。

 先程最初に書いたブロックが一番最初のブロックでないなら、これも当然前のブロックのハッシュ値を含んでいる。

このようなブロックが連なったっものを「ブロックの鎖」という意味でブロックチェーンと呼ぶ。

「それで?」

そんな読者の声が聞こえてくる。それでは続きをお話しよう。実はこのようなチェーンを作ることで、先程問題となった取引内容の削除が簡単に検出できるようになるのである。

 例えばCさんがBさんに20S送金した後で、Cさんがその20Sを惜しくなったとする。そこでCさんはその取引自体を削除してしまうことを考える。しかしそんなことをしてしまうと、その取引を含むブロックのハッシュ値が変わってしまい、次のブロックに書かれているハッシュ値と食い違ってしまうのである。

つまりブロックチェーンは、このような取引の削除を誰でも検出できる仕組みなのだ。

「次のブロックに書かれたハッシュ値を書き換えれば良くない?」

仰るとおりである。何度も言うようにこのハッシュ値の計算は誰でもすぐにできるのだ。そうであれば、取引を削除した後でそのブロックのハッシュ値を再計算、その次のブロックに書かれているハッシュ値をこれに置き換えてしまえばいい。

 しかし、このブロックチェーンの素晴らしいところは、これが連鎖しているということである。つまり、次のブロックに書かれているハッシュ値を書き換えてしまうと、次のブロック自体のハッシュ値も変わってしまい、さらにその次のブロックに書かれているハッシュ値と食い違いが生まれるのである。

つまり、チェーンの途中のブロックから取引を削除してしまうと、その後に続く全てのブロックを書き換えなければならないのである。

「じゃあ全部書き換えれば?」

あ、はい、その通りです。

 そう、全て書き換える必要があるなら、本当に全部書き換えてしまえば良いのだ。ハッシュ値の計算は一瞬で出来てしまうので、この作業は実はそんなに大変なものではない。

 そこでこれを防ぐために、何かしらの工夫を施す必要がある。

4.3 時間稼ぎで書き換えを不可能に

 容易にハッシュ値の書き換えが行われてしまうとどうしようもない。そこでこれを阻止するために最初に思いつくのが、先程導入したデジタルなハンコである。前のブロックのハッシュ値をブロックに書き込んだ後でこれにハンコを押してしまえば、誰でも書き換えられるという状況を打開することができる。

 しかしここで、この仮想通貨の前提が牙をむく。

誰も信用できないコミュニティで
信頼されることを目指した通貨 

そう、このコミュニティは誰も信用できないのだ。

 例えばグループのリーダーや国家の大統領、総理大臣のように、何かしらの基準で信頼にたる存在があれば、その人のハンコを押すことでしか前のブロックのハッシュ値が承認されないようにしておけば良い。もちろんその場合でも、その信頼に足ると思われていた人物が不正にハッシュ値の書き換えを行ってしまう可能性は残る。しかし今はもっと状況が悪いのであり、そのような都合の良い存在がいないため、ハンコによる書き換えの阻止が不可能となってしまっている。

 そこでここでは時間稼ぎによって書き換えを不可能にすることを考える。

 結局のところ、先程の問題はハッシュ値の計算と書き換えが一瞬で行われてしまうことが問題であった。そこで、このハッシュ値の計算を時間がかかるようなものに変更したい。そのためにはどうするのかと言うと、生成されるハッシュ値に制限を設けるのである。具体的には「ブロックのハッシュ値として許されるのは、先頭の文字が0のものだけ」というようなルールを作ってしまうのである。

 記憶力の良い読者は次のように思うかもしれない

「え?同じデータからは同じハッシュ値しか得られないんじゃないの?」

その通りである。最初に話したハッシュ関数の特徴の1つ目

  1. 同じデータをハッシュ関数に入力すると必ず同じハッシュ値が得られる。

が問題となる。つまり、取引が集まってきてブロックを作った段階で、そのハッシュ値はただ1つに決まってしまうのである。

 そこでハッシュ値をいじれるようにブロックにてきとうな数を加えることを考える。これをナンスという。

「先頭が0のハッシュ値しか許されない?」

ハッシュ値をいじれるようにナンスという数をブロックに加える??」

正直何がなんだか分からないと思う。これに一体どんな効果があるのか、実際にブロックを作る過程を追うことで確認していこう。

 まず、ある程度取引が溜まってきたら、それらをまとめてブロックを作る。

そしたらここに、てきとうな数、ナンスを加える。これは本当に何でもいいので、例えば0とかにしておく

そして、このブロック全体のハッシュ値を計算する。

もしこのとき、このブロックのハッシュ値の先頭が0でなければ、それはハッシュ値として認められないので、ナンスを変更する。

 例えば今度は1にしてみる。そして再度ハッシュ値を計算する。

新しいハッシュ値の先頭を確認し、それが0になっていなければ再度ナンスを変更し、先頭が0になるまでこれを繰り返す。ハッシュ値の先頭が0になるようなナンスを見つけたら、それをブロックに加えてブロックの完成とする。次のブロックには、この先頭が0のハッシュ値が追加されることになる。

要は時間稼ぎである。ハッシュ関数の性質から、先頭が0になるようなハッシュ値からナンスを逆算することは出来ないし、またデータを少し変えるだけで全く違うハッシュ値が得られるので、あるナンスでハッシュ値の先頭が1になったからといって、そのナンスが目的のナンスに近いわけでもない。このハッシュ値の先頭を0にするような「正解のナンス」を探す最も効率的な方法は、さっきの例のように0から順番に試すことである。したがって、誰であろうと一瞬でブロックを作ることが出来なくなる。こうすることによって、チェーンの途中のブロックから取引を削除して、その後に続く全てのブロックのハッシュ値を書き換える作業にめちゃくちゃ時間がかかるようにできるのである。

 この正解のナンスを探す時間を調整したい場合には、先頭の文字にもっと強い制限をかけたり、あるいは制限を緩めたりすればいい。例えば先頭の2文字が00であるようなナンスしか認めないようにすれば、先頭の1文字が0であれば良い場合に加えて、より探索時間がかかるようになる。ビットコインの場合には、このナンスの探索に10分程度の時間がかかるように制限を調整している。

4.4 誰がそんな面倒な作業をするのか

 誰がそんな面倒な作業をしてくれるのだろうか。この正解のナンスを探して新たなブロックを追加するのは別に誰が行っても良い。誰がやったとしても、バレないように改ざんを加えることは不可能だからだ。しかし、この作業は計算資源や電力といった膨大なリソースを消費する。何の旨味もないのにこんなことをしてくれる物好きはいないだろう。そこで、ここに報酬を与えるのだ。つまり、「正解のナンスを見つけてブロックの追加に貢献してくれた人に1Sプレゼントしますよ」ということを約束するのである。

 この計算資源を使って正解のナンスを探し出し報酬を得る作業をマイニングと呼び、それを行う人達のことをマイナーと呼ぶ。

 これは「作業による証明」という意味でProof of Work、通称PoWと呼ばれる仕組みである。また、この作業でしか仮想通貨を発行しないようにすれば、仮想通貨の総量が無意味に増えたりすることはなくなる。マイナーは、本当の意味で、通貨を掘り出して流通させる役割を担っているのだ。

5. 「P2P」〜さいきょうのうんよう〜

 もういい加減に最強なのではないだろうか?いやしかし、実はまだ問題が残っている。ここまでの方法ではノートをまるごと消してしまうような攻撃に対して無力である。そう、最後はノートの保管方法が問題となるのだ。

5.1 2つの方針

 「ノートを安全に保管する方法」と聞いて最初に思いつくのは、パスワードがなければアクセスできないようなファイルサーバに保存しておくことである。

 しかし、しかしだ仮想通貨の大前提

誰も信用できないコミュニティで
信頼されることを目指した通貨 

こいつが問題となる。誰も信用できないのだ。安心してデータを保存できるファイルサーバなど存在しないのである。

 そこで現れるもう1つの方針が「みんなで同じノートを持つ」である。みんなが常に同じノートをコピーして持っておけば、それら全てを同時に消してしまうことは困難になる。

 ここで重要になってくるのがPeer to Peer、通称P2Pと呼ばれるアーキテクチャである。

5.2 長いものが正義

 P2Pというのは、言うなれば参加者のPCネットワーク全体が、ファイルサーバとして機能するような仕組みであり、どこか一箇所にデータを置くのではなく、みんなで同じデータを持つようにするものである。参加者全員のPCにP2P用の領域を作っておき、常に全員分のデータを同期しておくというわけだ。したがって、どのPCからでも同じデータにアクセスできるのである。これは通常のファイルサーバと比較したとき、ユーザーが増えてもアクセスが集中して回線が遅くなるような事態が発生せず、また参加しているいくつかのPCが壊れても、同じデータを持っている人は他にもいるので、障害に非常に強いというメリットがある。日本ではWinny事件の影響でP2Pに悪い印象を持つ人も多いが、上手に使えば素晴らしい仕組みなのだ。

 そして、これは仮想通貨のノートを保管する方法としては大変優れている。

 このP2Pを利用したブロック追加の流れは次のとおりである。

  1. 取引を行いたい人は、署名した取引内容をP2Pに流す。
  2. 報酬が欲しい人は、P2Pに流れている署名済みの取引内容を集めブロックを作り、正解のナンスを探し、ブロックを追加する。
  3. 正解のナンスを探している人が同時に複数人いた場合には、最も早くナンスを探しだした人のブロックが追加され、その人だけが報酬を受け取る。

ここまでの話で、勘の良い読者は気づいたかもしれないが、取引内容に署名をしただけでは、取引内容としてはまだ未確定の状態であり、誰かがそれを含めたブロックを追加するまでは承認されない。

「ナンスを探しだした人が同時に複数人現れた場合にはどうするのか?」

やはり、勘が良い。

 そう、実際そういった事態も起こりえるのである。その場合には、なんとブロックチェーンは分岐するのである。さらに厄介なことに、新たに作成するブロックに含める取引は、マイナーが好きに選んで良いので、全く異なる取引を含む分岐が生じる可能性が高いのである。

また、同時にナンスが見つかる場合以外にも、分岐が生じることがある。例えば、通信にはどうしてもタイムラグが生じるため、アメリカと日本ではブロックチェーンに違いが生まれたりすることがあるのだ。そのような場合でも当然ブロックチェーンは分岐する。そういったわけで、実はブロックチェーンにはいろんなバージョンが存在してしまうのである。そんなとき、どのブロックチェーンを信じたら良いかと言う問題が発生する。

 先にこの問題に対する解決策を言ってしまうと、一番長いチェーンを信用することにすれば良い。つまりブロックチェーンが分岐したらしばらくそれを放置し、ある程度泳がしたところで、より伸びた方の分岐を採用して、他の分岐については消してしまうようにする。こうして常に長い1本が残るようにするのである。これは単に、複数あるブロックチェーンのせいで混乱が生じることを防ぐという目的以外にも、不正な取引を自動的に削除するという効果もある。

「おいおい、ハンコのおかげで不正な取引はできないんじゃないのかよ?(笑)」

そう思うのも無理はないが、実はこれは重要な点を見落としている。私は「ハンコのおかげで不正な取引を検証できるようになる」とは言ったが、「不正な取引が書き込めない」とは言ってないのである。つまり、取引内容を改ざんしてそれをP2Pに流してやることも可能ではある。もちろん、参加者はその取引内容が改ざんされているかどうかを確認することができるので、マイナーもわざわざ改ざんを含んでいるような取引内容はブロックに取り込まないだろう。しかし、その改ざんを行った人間がブロックを追加することだってできるのである。したがって、改ざんされた取引が含まれるブロックが追加されることはありえるのである。

「でもその改ざんされた取引は検出できるので、
追加したところで意味ないのでは?」

確かにそうなのだが、えーと、誰が検出してくれるのだろうか?

 繰り返しになるが、今は誰も信用できないコミュニティにいるのだ。他の人が「検証してみたけど、このチェーンは不正がないから安全だよ!」といったところで信じられない。もちろんあなた自身が自分で検証を行うということも出来るが、他の人だってあなたのことを信用できないのだ。このような状況で誰もが「あ、このチェーンは信用できるな」と思える方法を探さなければならない。

 実は先程の「しばらく泳がせてから長く伸びた方を採用する」がその方法なのである。マイナーはブロックを追加する際にブロックに含める取引内容を選ぶだけではなく、どのチェーンに追加するかも選ぶ必要がある。そのとき、全てのブロックを検証することができるし、これは一瞬で完了する。時間がかかるのはあくまで正解のナンスを探す過程であり、既にナンスが与えれらているブロックを全て検証するのは造作もないことなのだ。そうすると、多くの参加者は改ざんの含まれるチェーンを信用しないため、そんなブロックにわざわざ膨大な計算資源を投じてブロックを追加しようとは思わない。そうなると、改ざんを含むブロックは全然伸びなくなるのである。この仕組みによって、この改ざんを含む分岐は勝手に消滅してくれるのだ。改ざんを含むブロックを伸ばし続ける唯一の方法は、改ざんした本人が、そのチェーンにブロックを追加し続けることである。しかし、ご自慢の計算資源を携えたマイナー達が犇めき合う戦場で、彼らに勝ち続けてブロックを追加していくのは現実的に考えて非常に難しいし、わざわざそんなことをしようとする人はいないと考えられる。というのも、これを可能にするためは、参加者の半分以上に相当する計算資源を保有する必要があり、もしそんな資源を持っているのであれば、大人しくマイニングで稼いだほうがお得だからだ。だいたい、そんな力技で改ざんを含むチェーンを伸ばしても、みんながその仮想通貨を信用しなくなるだけであり、自分の持っている通貨の価値を落とすようなことはわざわざしないだろうということである。参加者の過半数分に相当する計算資源を使って、改ざんを含むチェーンを伸ばす攻撃を「51%攻撃」という。

5.3 現実世界との接点

 ここまでの話は、全て仮想通貨内で完結していたものであり、現在国が発行しているような円やドルといった通貨との接点については何も述べてこなかった。というか本来接点などないのである。もしあなたが仮想通貨が欲しければ実際にマイニングなどを行うことで仮想通貨を集めるのが正当なやり方である。しかし実際には、マイニングを行えるような立派な計算機を持っていない人がほとんどだ。そんな人が仮想通貨を手に入れるためには、既に仮想通貨を持っている人から送金してもらうしかない。あなたは仮想通貨を持っている人と交渉し、国が発行する円やドル、もしくは物と引き換えに仮想通貨を送付してもらうのである。これは完全にこの仮想通貨の仕組みの外側の話であることに注意したい。そういったやり取りを行ってくれるのが、コインチェックbitFlyerなどの取引所である。

5.4 成功した攻撃

 ところで、この「さいきょうのつうか」は本当に最強なのだろうか?一見すると、もはやこれを改ざんしたり勝手に削除したりする術は残されていないような気がする。しかし実は、仮想通貨が攻撃を受けて不正にお金を引き出されてしまった例が存在するのである。ここでは、その実例を紹介することにする。

 実際に攻撃を受けてしまったのは「モナコイン」と呼ばれる日本の2ちゃんねるで生まれた仮想通貨である。

 犯人の手口はこうだ。まず、取引所を利用して自分の保有しているモナコインを日本円として出金する。このときの仮想通貨の流れは、

"犯人が口座に????MONA送金した"

である。取引所は、ブロックチェーンの新たなブロックにこの取引内容が加えられていることを確認した後、登録されている口座に日本円で相応の金額を送金するわけである。犯人は自身の口座に日本円が振り込まれたのを確認した後、予め分岐させておいたチェーンを高速で伸ばしていったのである。この「予め分岐させておいたチェーン」というのは、先程の"犯人が口座に????MONA送金した"という取引内容を含まないものである。このチェーンが他のどの分岐よりも長くなってしばらく経つと、他の分岐は全て消えてしまい、犯人が高速で伸ばしたチェーンが正しいチェーンとして君臨するのである(5.2参照)。この犯人が伸ばしたチェーンには口座に送金した事実が含まれていないため、犯人はモナコインを失うことなく日本円をゲットできてしまうのである。ポイントは、犯人は一切改ざん等は行っていないという点である。では問題はどこにあるのかというと、取引所が、まだ消えてしまう可能性のあった1つの分岐を早々に信じてしまい、日本円での出金を行ってしまった点にある。ブロックがどの程度伸びたら信じてもよいか(消える心配がないか)という目安は仮想通貨ごとに異なり、また実際にどのタイミングで日本円やドルとの交換を確定させるかというのは、取引所ごとで独自に決めている。もし素早い取引を売りにする取引所を作りたかったら、まだブロックがそんなに伸びていない状態でも取引を確定させてしまうという方法もあるわけだが、このようなリスクも当然生じるのである。実際、犯人が目をつけた取引所は比較的短い長さで取引を確定していたのである。

 先に述べたように、取引所における日本円などとの交換というのは、完全に仮想通貨の仕組みの外の話であり、今回の例は仮想通貨自体の信用を落とすものではない。しかし、まだ仮想通貨が既存の通貨の代わりとなりきれていない以上、取引所の使用は不可避であり、我々はその最強の外側の存在に常に注意を払わなければならないのだ。

6. 「まとめ」〜さいきょうのつうか〜

 如何だっただろうか。ノートの落書きから始まった「さいきょうのつうか」であったが、実に立派なものになった。

 ここで紹介した仮想通貨はPoWを使ったものだったが、このPoWは、取引にかかる時間が長いことや、電力消費による環境への悪影響が指摘されている。ここまで読んだ読者ならそれが何故起こるのかを理解できるだろう。そこで、これに代わる方法としてPoS(Proof of Stake)やPoB(Proof of Believability)などの承認システムが提案されている。

 本当の意味で「さいきょうのつうか」を目指す戦いは、まだまだ始まったばかりなのだ。

 それでは、この「さいきょうのつうか」に対して想定される攻撃と、それが何故防げるのかを箇条書きにして、本ブログのまとめとしよう。

  • [考えられる攻撃]
    何故それを防げるのか
  • 取引内容の改ざん
    デジタル署名によって誰でも検証可能であり、改ざんを含む取引内容はマイナーに無視されるか、仮にチェーンに追加されても伸びないため自然に消える。
  • 取引内容の削除
    次のブロックのハッシュ値と食い違いが生じるため検出可能。そのようなチェーンは伸びなくなるため自然に消える。
  • 取引内容を削除し、後ろに続くブロックのハッシュ値も全て書き換える
    後ろに続く全てのブロックについてナンスを探し直さなければならないため、実行するためには全体の51%以上の計算資源を保有する必要がある。そんなことをするよりマイニングした方が確実だし、やったところで通貨の価値が下がってしまい旨味がないので誰もやらない。
  • ブロックチェーンをまるごと消してしまう
    P2Pに流しているため実質不可能。参加者全員のPCをハッキングするか物理的に破壊する必要がある。