blockchain/bitcoinに関する整理

##前書き

「ITの基礎知識はあるがblockchainはよく知らない」レベルの受講者向けに簡単な勉強会をやった際に調べた内容を纏めたもの。
bitcoinの仕組みの説明が主。最後にその他の様々なblockchainは何がトレードオフになっているのか、簡単に言及する。スマートコントラクトについても多少言及する。
「blockchain/bitcoinを技術的に理解したいが論文読むほどじゃない、でもビジネス向けの表面撫でた様な解説だと気持ち悪い」くらいの読者に役立てばいいな、というところ。

---

## bitcoin (狭義のblockchain)について

### bitcoinとは

* Satoshi Nakamotoなる謎の人物が提唱した暗号通貨である
* 信頼できる第三者(金融機関)を前提とせず、記録の保全が可能である点が注目された
* この技術を他のユースケースに応用できないか？という観点から流行りだした
* 狭義のblockchainの定義(日本ブロックチェーン協会)はオリジナルであるbitcoinの特性から策定されている

### よく言われるblockchainのメリット

* 可用性/対障害性(マスターノードが無い)
* 透明性(全ての取引記録が全ノードから参照可能)
* 改ざん耐性
* 非中央集権(第三者機関による保証が不要)

これらはbitcoinのメリットであり、広義のblockchainにおいては必ずしも当てはまらないことに注意が必要である。

### 送金の表現

bitcoinの最も基本的なデータ構造は送金トランザクション(**Tx**)である。
bitcoinはその仕様上、**残高をデータとして持たない**。全てがトランザクション(誰かから誰かへの送金記録)の累積によって記録される。(実際には実装の都合上、UTXOテーブルという事実上の残高テーブルが存在するが、割愛する。プロトコル上では規定されていないキャッシュのようなものである)
A→Bの送金を示すTxはざっくり下記のデータで構成される。なお、**公開鍵≒口座番号**と理解していい。

#### Txの構造(A→Bの送金)

1. X(誰か)からA宛てに送金された過去のTxのハッシュ値
2. 宛先を示すBの公開鍵
3. 送金金額
4. Aによる1～3に対する電子署名

##### 制約・補足

* 2・3のセットは一つのTxに複数含めることが可能であり、また自分自身を宛先に含めることも可能である(これにより、おつりの表現が可能になっている)
* 2・3のセットには一般にminerへの手数料支払額が含まれる(後述)
* 「1の金額」と「3の金額合計」は一致していなければならない(全て使い切らなければならない)

このTxの構造により、

* Aが過去にXから確かに送金を受け取っていることが証明できる
	* 望むのであればXの前は誰が持っていたのかも検証できる
* Aが送金元であることが証明できる

但し、これは過去にAがXから入金を受けた事実は証明しているが、Aがその入金額を複数回使用していないことを証明しておらず、残高確認としては不十分である。**二重支払が回避できない**。
なぜならば、Aは1(X→AのTxのハッシュ値)をコピー可能だからである。

### 二重支払

前項の送金表現だけでは、**AはX→AのTxを根拠に無尽蔵に送金を行える**(二重支払)ため、錬金が可能になってしまう。
これを検証可能にするためには、**X→AのTxが、送金根拠として過去に一度も使用されていない**ことの証明が必要になる。
bitcoinでは、**blockchainに過去発生した全てのTxを記録することで、あるTxの根拠となっているTxが過去に使用されていないかを検証可能にする。**
なお、ここで言うblockchainは、データ構造としてのblockchainを指している点に注意。

しかし実は、二重支払を検出したいだけの要件であれば、銀行システムのメインフレームの中に残高を記録すれば良いだけである。
「信頼できる第三者を前提とせずに取引基盤を成立させる」というbitcoinの目的ゆえ、後述するblockchainやPoWといった特殊な仕組みが求められたことを意識しておくべきである。

### ネットワークの構造・登場人物

bitcoinネットワークは、不特定多数で決済基盤を成立させるという要件から、**P2P**である。基本的に全ての処理は**非同期的**であり、各ノードは処理結果を隣接ノードへは流すものの、全ノードへ伝播したかは確認しない。処理結果は**”徐々に”**ネットワーク全体に伝播する。

ネットワーク上の登場人物は、大まかに非minerノード(Txの生成)・minerノード(Txの承認)の2種類である。
minerノードと非minerノードの違いはざっくり言えばminingを実行しているかどうかだけであり、仕組み上は誰でもminerになれる。(結構な計算リソースが要求されるが)

### Tx承認の流れ

blockchainにおいては、複数のTxをblockという単位でまとめて承認する。
ここでいう承認とは、**「二重支払でないこと、既に承認されていないこと(過去のblock内で使用されていないこと)」**があるminerにより確認されたことを指す。

Tx生成、承認の流れは大まかに下記のとおり。

1. ネットワーク上の誰かが新規Txを生成し、P2Pネットワーク上に流す
2. ネットワーク上のminerは伝播してきたTxを溜め込む
3. minerは溜まったTxをblockという単位にまとめて承認し、最新のblockとしてネットワークに流す
4. 伝播してきたblockを受け取ったminerはblockを検証し、妥当であれは最新と認める
5. なお、blockを生成したminerは報酬としてblockに含まれる各Txからの手数料収入を得る

流れから分かるとおり、blockもそれに含まれるTxも、全てのデータは最終的には全ノードに伝搬し参照可能となるし、全てのblock・全ての取引履歴は全minerが最終的には記録することになる。

こういった構造をとることにより、信頼性の低いネットワーク(インターネット)上にあり、かつ不特定多数で匿名の参加者を前提にしながら、耐障害性に優れた仕組みを実現している。

但し、これらはP2P上で非同期的に実行され、かつ不特定多数の匿名ノードを前提とするため、課題となる点が多数出てくる。

* 取引の順序性は担保されないし、ある時点で全minerに最新blockが伝播しているとも限らない。同時に同一のTxを複数のminerが
承認するといったことも起こりうる
* minerは匿名で誰でもなれるため、特定のminerが承認したといっても、そのminerが攻撃者でないとは限らない。改ざんや自分に都合のよいTxの自己承認などが行われうる

**blockchainは、非同期性・匿名性の問題を解決できる構造である必要がある**が、その点について補足していく。

### blockの構造

blockに含まれるデータのうち主要なものは下記。

1. 複数のTx(数百～2,000個くらい)
2. 直前のblockのハッシュ値
3. Nonce

#### blockの制約・補足(Proof of Work)

* 制約として、block全体に対するハッシュ値は上N桁が0でなければならない(Nは難易度としてネットワーク全体で調整される)
* Nonceはハッシュ値を調整するために任意の値を入れるためのフィールド
* minerはNonceを変えつつ計算を試行し、ハッシュ値の制約を満たすNonce値を見つける必要がある

#### blockchainの制約・補足

* 直前のblockのハッシュ値を持つことにより、chain構造を成している
* chainが分岐した場合(複数のminerが別々のblockを同時に繋げてしまった場合)は、最終的にchainが長いほうを正とする
* 短い方の分岐に含まれていたblockは無効となる
	* minerが受け取った手数料はなかったことになる(手数料収入を根拠とした送金は、同一分岐上の手数料を得たblockより後の
blockでしか承認されない為)
	* 含まれていたTxは他のblockへの取り込みを待つ状態となる(あるいは、長い方の分岐に既に取り込まれている)
	
Nonceを見つけblockを生成する作業を**mining**と呼び、CPUを浪費しなければNonceを見つけられないこの方式を**Proof of Work(PoW)**と呼ぶ。

### 非同期性・匿名性への対応

こまでで述べた構造によって、blockchainはP2Pでありながら、非同期性と匿名性の問題にある程度対応している。

* **chain分岐の問題**
	* 各minerは長い方のchainを正としてblockを繋げにいくため、最終的には一つのchainに収束する
	* 但し裏を返せば、blockに取り込まれても、分岐の結果として承認が無かったことになる可能性が残るということであり、決済において即時性・確定性がないという欠点になっている

* **自己承認の問題**
	* minerは誰でもなれるため、例えば自身が二重支払のTxを生成し、自身で承認するといったことが仕組み上可能である
	* 但し、他のノードが正当なblockと認めないため、攻撃者は自身の努力のみで最長となるようchainを繋げ続ける必要がある
	* このとき、Proof of Workによって一定の処理能力が求められるという制約により、攻撃者が他の全minerの処理能力合計の50%を上回らない限りにおいて、この攻撃は成立しない
	* そもそも、処理能力の50%を匿名の個人・組織により占有された決済インフラなど誰も使わないという話もありますが

* **改ざんの問題**
	* 取引履歴の改ざんは、blockがハッシュで繋がっているという構造、及びTxがハッシュで繋がっているという構造から困難となっている

Proof of Workは、見方を変えれば**「CPUパワーを投票権として、各minerが信じるchainに投票する多数決」**と捉えることができる。
多数決という合意形成手段によって、互いを信頼できない匿名集団が決済インフラを形成することを可能としている。
また、miningの報酬として手数料が得られる為、攻撃者になれるほどの処理能力を持つのであれば、真面目にminingした方が儲かるという構造になっている点も認識しておきたい。

### 最初の通貨はどこからくるのか

送金の表現から話を始めたが、当然ながら最初に誰かが残高を持っていないと取引が始まらない。
miningの報酬は実は手数料以外にもあり、それが最初の通貨を供給する。blockの生成毎にminerにはある金額のBTC(bitcoinの通貨単位)が新規発行される。この発行量はネットワーク全体で調整され、chainが長くなるほどに低減していき、いすれ0になる。
この性質により、Tx生成やminingが活発になるにつれ徐々に通貨総量が増えていき、どこかで上限に達し、インフレが止まるという流れとなる。

### bitcoinの特徴の整理

bitcoinの仕組みの説明はここまで。あえて説明していない部分もあるが、根幹の説明としてはずれていないものと思う。以下に特徴とメリデメを整理する。
bitcoin以外のblockchain実装は、概ねここに記載のメリデメのトレードオフをしていると捉えると理解しやすいと思う。

|特徴|利点|欠点|
|:---|:---|:---|
|blockchain(ハッシュ値による連鎖的構造)|●悪意ある参加者への耐性●改ざん困難|●データの単調増加|
|Proof of Work|●悪意ある参加者への耐性|●処理能力に限界がある●決済が確率的●無駄に電力を食う|
|mining報酬によるインセンティブ|●悪意ある参加者への耐性●参加者によるリソースコストの分担|●通貨以外のユースケースに適用しにくい|
|ネットワーク全体でのデータ共有|●耐障害性が高い|●アクセス制御ができない|
|非同期的なデータ共有|●信頼性の低いネットワークで多数のノードが参加可能|●決済が確率的|

#### 実際の運用

実際のサービスとしてのBitcoinにおいて、上述の弱点はどのようにカバーされているのか。

* データの単調増加
	* メモリ容量の方がより速く進歩するので問題ない(はず)という割り切り(対策なし)

* 決済が確率的
	* Txが取り込まれたblockの後に6chain繋がると慣例的に確定と看做す

* 処理能力に限界がある
	* 6Tx/秒程度が限界とされているが、なんとかなっているらしい。なおクレジットカード決済と比べると非常に非力

その他の弱点はbitcoinのユースケースにおいては問題とならないので割愛。

---

## bitcoin以外のblockchain

主要なblockchain実装についてbitcoinと比べつつ簡単に記載する。

### Ethereum

bitcoinにできてEthereumにできないことはほぼ無い。機能拡張を加えた正統進化と呼べる実装。その分実装は複雑なので安定性の面で不安が残る。

#### 残高の管理

Ethereumにおいては後述のスマートコントラクトで残高以外にも多数の情報を記録する都合上、トランザクションの累積(取引べース)ではなく、**残高べース**で情報を記録する。ざっくりな理解としては残高(＋α)テーブルがまるごとblockに承認される。

Ethereumのデータ構造についてはこちらの記事を推奨。
[全人類の口座残高を管理する――(2) Ethereumの場合――](https://qiita.com/yanagisawa-kentaro/items/bfdbb5564d1751c3d2ea)

#### スマートコントラクト

Ethereumにおいてはソースコード(コントラクトコード)をTxとしてminerに承認してもらうことができる。
承認されたコントラクトコードはアドレス(公開鍵≒口座番号)が割り当てられ、アドレスに対して送金しつつパラメタ(引数)を渡すことで、minerが手数料を取りつつそのコントラクトコードを実行してくれる。

デブロイされたコントラクトコードはそれ自体が口座であるため、送金された金額を溜め込むことができ、またコード内の処理で特定のアドレスに送金することも可能。

またコントラクトコード内で残高以外の情報を任意に記録可能である。記録した情報はblockchain上に永続化される。
但し制約としてblockchain内にある情報しか操作できないため、コントラクトから外部サービスを呼ひ出す等はできない。
なおコントラクトコードはチューリング完全であり、一般的なプログラム言語と表現能力は同等である。

説明しやすい活用例としては寄付。
コントラクトで一定期間寄付の送金を募り、一定期間後に寄付先のアドレスに自動送金する。
blockchainでこれをやる意味は、コード内容が完全公開、かつ製作者にもデブロイ後の改ざんが不可能という特性から、製作者が誰であろうとコードの内容どおりに寄付の処理が間違いなく実行されることが保証される点にある。

### Hyperledger Fabric

不特定多数の匿名参加者を前提としないタイプのblockchain。スマートコントラクトも実装されている。
ノード間合意形成はPBFTと呼ばれる単純な多数決アルゴリズムにより行われ、bitcoin等と比べ速く確定的。

### R3 Corda

不特定多数の匿名参加者を前提としないタイプのblockchain。スマートコントラクトも実装されている。
**アクセス制御**の実装が特徴的。取引情報へのアクセスを取引の当事者とスーパーノード以外に許可しない。その為、当然ながら合意形成・承認、記録も当事者とスーパーノードのみで行う。ノード間で契約等の情報を交換しつつ、スーパーノードが監視・承認するようなユースケースが設計上想定されている。仕組み上当然ながら障害耐性は低くなる。

---

## 所見

bitcoinの新規性は、信頼できない多数の参加者を前提として、信頼できる記録の仕組みを実現したことにある。一方でデータ構造自体は単純で、スタンドアロンであれば誰でも実装できるレベルのものである。

その点から、信頼できる参加者という前提に立つプライベート型のblockchainは、根本的にbitcoinとは別物と捉えるべきで、個人的には、その前提を置いたら最早何でもいいのでは、という気がしている。
実は普通のRDBMSの方が楽に実現できませんか？という視点を持っておくべきと思う。