Blockchain 学習メモ

Blockchain および、代表的な実装である Bitcoin について学習したのでメモをまとめてみます。

Bitcoin 論文

まず Bitcoin の論文を読んでみます。

・原文
https://bitcoin.org/bitcoin.pdf

・日本語訳
https://coincheck.blog/292

概要を読んだところ信頼のおける第三者を通さないでも暗号化された証明に基づく電子システムのため直接取引ができるようです。 それからトランザクション(取引)について、コインの所有者は送金をする際にトランザクションに送信者のデジタル署名を追加することで受取人しかそのコインを使えないようにするようです。 次に Proof-Of-Work について、ブロック内には直前のブロックのハッシュが含まれているため、前のブロックを変更する場合は後続のブロックのハッシュの再計算が必要になるがこれは計算量が大きく現実的でないため改ざんに強いようです。

元の論文だけだと具体的なイメージが掴みづらいので次に Mastering Bitcoin を読んでみました。

Mastering Bitcoin

www.amazon.co.jp

トランザクション

論文だけでは具体的なトランザクションのデータ構造のイメージがつきづらかったのですが、具体的には以下になっているようです。支払人と受取人を明記した小切手のようなものというのがイメージがつかみやすいかと思います。

Transaction Data

トランザクションのデータ構造には以下のフィールドがある

  • Version: トランザクションがどのルールに従っているか指定
  • Input Counter: インプットの数
  • Inputs: 送金元、scriptSig
  • Output Couner: アウトプットの数
  • Outputs: 送金先、scriptPubKey
  • Locktime: Unix タイムスタンプ、またはブロック高

このように Inputs と Outputs は複数になっています。一人のアカウントが所持しているビットコインは一つ一つの(未使用の)トランザクションの合計となるので、Inputs は複数になるようです。また、Outputs が複数となるのは例えば 20 ビットコイン所持しているうちの 1 ビットコインを送金する場合、Input と Output のビットコインの差分がトランザクション手数料としてブロックチェーンを採掘するマイナーのものになるので、自分自身にも送金する必要があるようです(Input - Output のビットコインが 0 の場合は無効なトランザクションと判定されるので、手数料を払えるようにしておく必要があります。)

所持しているビットコインは受け取ったトランザクションの合計になるのですが、どのように未使用トランザクションを見つけているかについてですが、まずはビットコインアドレス、それからウォレットについて知っておく必要があります。

ビットコインアドレス

トランザクションを小切手に例えるとビットコインアドレスは小切手に書く名前のようなもの。アカウントには公開鍵/秘密鍵のキーペアを持っていてデジタル署名を行う際に使っているのですが、ビットコインアドレスは公開鍵を SHA256 や RIPEMD160 でハッシュ化したものになります。

ウォレット

ウォレット(SPV ノード型)はビットコインアドレスへの支払いを参照するために、マークルツリーというブロック内のトランザクションの要約情報による 2 分探索木を使い対象のトランザクションをダウンロードします。ウォレットには未使用のトランザクション(UTXO)のデータベースの機能があるので、ダウンロード後はネットワークにつながっていなくてもトランザクションの作成が行えるようになります。

Outputs に含まれる locking scrpit は scriptPubKey と呼ばれていて通常は公開鍵またはビットコインアドレスが含まれている。Inputs に含まれる unlocking script は locking script によるロックを解除できるスクリプトで、通常デジタル署名を含んでいる。

論文の図だとトランザクション同士が直接つながっていて一緒に同じブロックに入っているように感じたのですが、実際はビットコインアドレスなどによりブロック間をまたがってつながっています。

また、ビットコインアドレスから未使用のアウトプット参照としてビットコインネットワークでは以下の ページの unspent API が提供されています。

www.blockchain.com

ブロックチェーン

ノードの種類

ブロックチェーンは分散型台帳と言われていまして、ビットコインネットワーク上のノードには大きく 4 つの機能がありノードの役割によって必要な機能があります。 4 つの機能としてルーティング、データベース、マイニング、ウォレットがあります。フルノードはルーティング、データベース、マイニング、ウォレットの 4 つの機能が備わっていて、2009 年に作られた最初のブロック(Genesis Block)から今までのすべてのブロックの情報を持っています。新規でフルノードがネットワークに追加されたら、必要なブロックをダウンロードします。ビットコインネットワークに参加するにはルーティングの機能が必須で一部の機能しかないノードは SPV ノードまたは軽量ノードと呼ばれます。

マイナーのノードはブロックを採掘することにより、以下 2 種類の報酬が得られます。 ・新しいブロックを作った際に発行されたビットコイン ・ブロックに含まれている全トランザクションから得られるトランザクション手数料 新規のビットコインの供給はマイニングを通して行われ、これは造幣局による発行と似ている。マイニングを通して新たに作られるビットコインの量は 4 年ごとで半減するようになっており、2009 年 1 月から始まり 2012 年 11 月に半減期が来てそれから 2016 年、2020 年と半減期が来ています。新規のビットコインの発行は 2140 年ごろまで指数関数的に減少していき 2140 年以降は新たなビットコインは発行されません。

ブロックの構造

Block - Bitcoin Wiki

ブロックの構造は以下になっています。

  • Block Size: Block Size 以降のフィールドのデータサイズ
  • Block Header: nonce などいくつかのフィールドが含まれる
  • Transaction Counter: ブロックに含まれるトランザクション
  • Transactions: ブロックに記録されるトランザクションのリスト

Block hashing algorithm - Bitcoin Wiki

それから、ブロックのヘッダーは以下になっています。

  • Version: ソフトウェア/プロトコルバージョン番号
  • previous Block Hash: 親ブロックのハッシュ値
  • Markle Root: ブロックの全トランザクションに対するマークルツリーのルートハッシュ
  • Timestamp: ブロックの生成時刻
  • Difficulty Target: ブロック生成時の proof of work の difficulty
  • Nonce: proof of work で用いるカウンタ

親ブロックのハッシュはブロックのヘッダーに含まれていることが確認できる。ブロックのマイニングでは 1 つのパラメータに対して解が見つかるまで繰り返しハッシュ化する。具体的にはブロックヘッダの Nonce を変更していきブロックのハッシュの先頭が 0 の連続となるものを探す(何桁連続するかは difficulty で調整する)。 ビットコインは 10 分間に 1 回ブロックが追加されるよう調整されているが、これはマイナーの計算能力の推移に合わせて difficulty を調整することで実現している。

たしかに、10 分間に 1 回ブロックが追加されるよう調整されているのであれば、過去のトランザクションを改ざんするのが困難だと理解できます。

また、ヘッダーにトランザクションの要約であるマークルツリーのルートが含まれており、Proof-Of-Workで取引内容が考慮されるため取引内容の改ざんに強いと言えます。

分散化コンセンサス

ビットコインネットワーク上のノードが独立して新規のブロック、トランザクションを検証するため以下 4 つのプロセスが発生します。

独立したトランザクション検証

トランザクションの構文とデータ構造は正しいか、各インプットにある unlocking scrpit は対応したアウトブットの locking script を開錠できるかなど

ブロックへのトランザクション集積

トランザクション検証後メモリプール(トランザクションプール)にそのトランザクションを追加する。トランザクションはブロックに含められるまでこのプールで待機している。 マイニングでブロックに追加するトランザクショントランザクション年齢、手数料、トランザクション優先度を考慮して選ばれる。

新しいブロックの検証

マイニングされたブロックがビットコインネットワークに送られたとき、ビットコインノードはブロックを他のピアに送信する前にブロックが有効か確認する。具体的にはブロックのデータ構造が構文的に有効か、ブロックヘッダハッシュが target difficulty よりも小さいか、ブロック内のトランザクションの検証が正しく行われているかなどを確認する。

ブロックチェーンの組み立てと選択

ビットコインノードは 3 種類のブロックセットを持っていて、一つはメインのブロックチェーンに紐づけられたブロック、もう一つはメインのブロックチェーンから枝分かれしたブロック、最後に既知の親がないブロック。メインチェーンは累積 difficulty が最も多くなっているチェーンになる。ほとんどの状況下では最も多くのブロックを持っているチェーンということになる。