Mastering Bitcoin自分用メモ、Bitcoinにおける興味深い点です。
かなり冗長に書いてます(+_+)
普通のデータベース(RDB)になれた人間的にいうと
ユーザーマスタや事前認証が無くても、トランザクションを発行しても問題にないようになっている
ということだと理解しています。
既存データベースでのトランザクション
通常のデータベースを使ったシステム(たとえばポイントシステム)においては、
ユーザーと、そのユーザーがどれくらいポイントを持っているかという情報( ユーザーマスタ )を持っていることが多いと思います。
その情報を参照することで、このユーザーがどれくらいポイントが使えるかどうかを判断し、トランザクションのデータを登録しているかと思います。
そしてECサイトなどでは、事前にログイン(認証)することでなりすましを防いでいますね。
ブロックチェーンでのトランザクション
ブロックチェーンにおいてはトランザクションのデータしかなく、
トランザクションの発行元(To)発行先(From)ユーザーのID(アドレス)をもとに残高を計算して
ユーザーがどれくらいポイントを使えるか判断します。
なるほどトランザクションのテーブルだけあるイメージなんですね
じゃーそのユーザーID(アドレス)はどんな感じで作るのでしょうか
ブロックチェーンでのユーザーID
ID(アドレス)に必要な要素とはなんでしょうか。ユニークであることですね。
通常のデータベースの場合、ユーザーIDはどのような形であれ、記録されているデータベースを参照し、重複しないようにして作成されます。
(連番でMAX値を利用するなどします)
ブロックチェーンにおいては、ユーザーID(以降ユーザーアドレス)は数学的な処理によって算出されます。
手順は下記です。
1.暗号学論的に安全な乱数を取得してそれを種とする
(具体的にいうと、/dev/urandom/などの暗号学論的に安全な疑似乱数生成器を使用)
2.種から秘密鍵を算出し、秘密鍵に対応した公開鍵を算出する
3.公開鍵に対して計算処理を実施し、結果をユーザーアドレスとする
**暗号学論的に安全な疑似乱数だから重複しないでしょ?**という理屈なんですね。
なぜ秘密鍵、公開鍵を作ったりしたのか?
ただランダムなユーザーアドレスがほしいなら必要ないはずです。
Bitcoinにおいては、このアドレスと鍵を使うことでトランザクションの有効性チェックを実施できるようにしています。
有効なトランザクションとは
トランザクションを発行するためには、何が必要なのでしょうか
まずユーザーが残高を持っていなければなりません。
たとえば、AさんからBさんに50コイン送った後のことを考えましょう。
BさんからCさんに50コインを送るには、どのようにすれば良いでしょうか
間違いなく、自分(Bさん)が残高を持っているんだということを証明する必要があります。
つまりBさんに対してすでに誰かが50コイン送っているということを証明する必要があります。
また間違いなくBさん自身がこのコインを使おうとしているということも証明する必要があります。
(普通のデータベースでもトランザクションのテーブルをサマリーすることで、ユーザーの残高は算出可能ですが、その場合ユーザーアドレスを知っていると誰でも残高の算出自体ができてしまうので、残高の算出ができるだけで支払いができるというのはダメですね)
残高はUTXOの束
Bitcoinでは、支払いたいコインの量に相当する、自分あての送金トランザクションをこれから発行するトランザクションに含める必要があります。
Bさんの場合、Aさんからの送金トランザクションをCさん宛のトランザクションデータに含めることになります。
このようなAさんから送金されてまだ使われていないトランザクションを**未使用のトランザクションアウトプット(UTXO)**と呼びます。
このようにしてBさんが50コイン使えることを証明しているんですね。
でも間違いなくBさんが使おうとしているのでしょうか、誰かが成りすましていないのでしょうか
間違いなくBさんであることを証明する必要があります。
Bさんだけが知っているパスワード
実はAさんからBさんに発行されたトランザクションには、Bさんだけが解除できるパズルが仕込まれています。
これはlocking scriptと言われ、パズルというものの実際はBさんしか知らないパスワードを入力すれば解けるようなものです。
このようにして間違いなくBさんが50コイン使おうとしていることを証明しているんですね。
Bitcoin的な表現(?):未使用のトランザクションアウトプット(UTXO)のlocking scriptに対して、発行者がunlocking script(=パスワード)を結合する
ここで一つの疑問がでてきます。
「Bさんしか知らないようなパスワードが答えとなるようなパズルを なぜAさんが作ることができるのだろう?」
不思議ですね。答えを知っているから問題を作れるのではないでしょうか。
ここで秘密鍵と公開鍵が必要になってきます。
公開鍵に対応した秘密鍵でパズルを解く
AさんはBさんに送金するので、Bさんのアドレスがわかっています。
このアドレスは、Bさんの公開鍵から作成されました。
もっと正確にいうと公開鍵をハッシュ化した公開鍵ハッシュをBase58Checkエンコードして作成しました。
ということは、Aさんはデコードすることで公開鍵ハッシュがわかります。
公開鍵から秘密鍵の算出は数学的に難しいですが(離散対数問題)、Base58Checkデコードは難しくありません。
公開鍵と秘密鍵は数学的に対応しているので、Aさんのトランザクションに含まれる公開鍵(=Bさんの公開鍵)に対応した秘密鍵をもった人(=Bさん)だけが、Aさんが送ったコインの持ち主であることを証明できるのです。
実際には、下記のような処理を実施してチェックしています。
unlocking script | locking script |
---|---|
[signature] [public key] | OP_DUP OP_HASH [public key hash] OP_EQUAL OP_CHECKSIG |
(Pay-to-Public-Key-Hashよばれる標準トランザクションの一つです。signatureが秘密鍵から作成された署名です。)
実際の処理は割愛しますが、左から順番に処理を実行するスクリプトです。
最後にOP_CHECKSIGを実行することになり、秘密鍵と公開鍵が対応しているかチェックしています。
アドレスが数学的に作られているので、とても不思議な性質をもっていますね。
つまり、あるユーザーが勝手にアドレス(A)を作り、そのアドレス(A)を宛先に使ってトランザクションを発行できることがわかります。
そしてその後、アドレス(A)からほかのアドレス(B)に向けて再度トランザクションを発行できるのです!
(もちろん秘密鍵が漏れていたり、秘密鍵の種自体が完全にランダムでない場合、実用できるものにはなりませんが、、)
中央システムに許可をもらわずともユーザーが作成、存在でき、そのユーザーを使って取引を実施でき、そしてそれが信頼できるということなのです!
(上数行が書きたくてこの記事を書いたら妙に長くなってしまった、、、。
たくさん言われていることなんですが、多分この興味深さはあまり理解されていない気がする。)
もう一回端的にいうと、**勝手に作ったユーザー(しかもこのユーザーの情報自体はデータベースに無くてもよい!)で取引できる!かつ信用できる!**ですね
実際に取引所ではこの性質を使いコールドウォレットと呼ばれる、ネットワークにはアドレス(つまり公開鍵)しか流れていないウォレットでビットコインを保存しているようです。
秘密鍵の情報は一切ネットワークに流れていないので、失われることがなくて安全ということですね。
さらにWebブラウザのjavascriptのみでアドレスを作成して、作成したアドレスを紙に印刷するペーパーウォレットというようなものもあります。
(少し理解がごっちゃになったのでいったん、打消し)
まさに攻殻機動隊、笑男事件に出てくる「ネットワーク内にある電子データは改ざん可能であるため、紙媒体が重要」というのと同じですね!
トランザクションが有効かどうかの実際のチェックはまた別のお話し、、