ブロックチェーンで Hello world! (Minimum Viable Block Chain)

# 0. はじめに

ブロックチェーンについては、ネットの記事を流し読んだ程度で、「ブロックがチェーン状につながっている」とか「中央集権的ではなく分散的」といったことはなんとなく聞きかじってはいたものの、ちゃんと理解してはいなかったので調べてみた。

本を読んで概念を表面的に理解するよりも、これ以上削ったらブロックチェーンとはいえないレベルの「最小限のブロックチェーン」を実際に作ってみたら楽しいのではないかと思い、ネットを漁ってみるとまさにうってつけの記事があった。

[実現可能な最小の Block chain のサンプルコード（未完成）](http://blog-ja.intransient.info/2016/03/block-chain.html)
([imsut/minimum-viable-block-chain](https://github.com/imsut/minimum-viable-block-chain))

これをPythonに翻訳して実行結果を眺めることで、以下の様なことを具体的なイメージを伴って理解できた(ような気になれた)。

- ブロックって何？
- ブロックがチェーン状に保持されるってどういうこと？
- 中央集権的ではなく分散的な信頼ネットワークが構築される？
- ビットコインの採掘(マイニング)って何？
- 過去データの改竄をどのように防いでいるの？

# 1. 登場するクラスの概要

ブロックチェーンとは何かを一言で言うと、「分散していながら、改竄が困難でデータの信頼性が担保された追記型の台帳」と理解している。
これは、User、Transaction、Verifier、Network、Blockという５つのクラスが、相互に作用することによって実現されている。

## User
ブロックチェーンネットワークの参加者を表すクラス。
他のUserとメッセージのやり取りをする。

([ソースコード](https://github.com/mas178/Fragments/tree/master/sample_blockchane/simplest/user.py))

## Transaction
User間のやり取りを表すクラス。

Transactionには下記の３種類がある。

- MessageTransaction: User間のメッセージのやり取りを表す
- FeeTransaction: User間の過去のメッセージのやり取りを認証するTransaction
- SignedTransaction: MessageTransactionにSignしたもの。普通はPKIなどで暗号化するらしいがここでは省略。

FeeTransactionでは、他のUser間のMessageTransactionを認証することによってFeeを得ることができる。(ビットコインで言うところのマイニング？)

([ソースコード](https://github.com/mas178/Fragments/tree/master/sample_blockchane/simplest/transaction.py))

## Verifier
- User間のやり取りを認証するクラス。
- UserはVerifierを継承しているので、全てのUserはVerifierでもある。
- 未認証のTransactionを保持し、Userの誰かがFeeTransactionを起こすとBlockを生成する。
- 属性`__last_block`としてブロックチェーンを保持する。

([ソースコード](https://github.com/mas178/Fragments/tree/master/sample_blockchane/simplest/verifier.py))

## Network
- ブロックチェーンネットワークそのもの。
- ネットワークに参加しているユーザーにトランザクションの発生をアナウンスする。

([ソースコード](https://github.com/mas178/Fragments/tree/master/sample_blockchane/simplest/network.py))

## Block
- 幾つかのTransactionをまとめたデータ。
- User(Verifier)が他のUserのTransactionを認証することによって生成される。
- Blockを生成するには、計算能力が必要なタスク(ここではcreate_id)をこなす必要がある。これがいわゆる`Proof of Work`。
- Blockは一つ前のBlockを指し示すprev_blockという属性を持ち、全Transactionデータはチェーン状に連なったBlockの集まりとして保持される。

([ソースコード](https://github.com/mas178/Fragments/tree/master/sample_blockchane/simplest/block.py))

# 2. 実験

例えば、下記の様にTransactionを実行し、全体の動きを観察する。

```python
from simplest.network import Network
from simplest.user import User

network = Network()

alice = User('Alice', network)
bob = User('Bob', network)
chris = User('Chris', network)
dan = User('Dan', network)

alice.send('Yo!', to=bob, fee=1.0)
bob.send('Ho!', to=chris, fee=2.0)
chris.send('Yo!Ho!', to=alice, fee=3.0)

alice.verify_message_trxs()
dan.verify_message_trxs()
chris.verify_message_trxs()
```

([ソースコード](https://github.com/mas178/Fragments/tree/master/sample_blockchane/simplest/main.py))

### 実行結果

※下記実行結果中の「↑」マークに続く行は筆者のコメント

```txt
~/Python35/bin/python ~/blockchain/simplest/main.py
[User.init] Alice: joining the block chain network
[User.init] Bob: joining the block chain network
[User.init] Chris: joining the block chain network
[User.init] Dan: joining the block chain network
↑
Userは生成されると同時にNetworkに参加する

[User.send] Alice: sending a message to Bob. (Yo!:1.0).
[Network.announce_signed_trx] announcing "Transaction signed by Alice (Message Transaction: "Yo!" to Bob with fee 1.0)"
↑
AliceがBobにメッセージを送ると、Network全体にそのことがアナウンスされる。

[Verifier.receive_signed_trx] Dan: unconfirmed transactions [<simplest.transaction.SignedTransaction object at 0x108f09828>]
[Verifier.receive_signed_trx] Chris: unconfirmed transactions [<simplest.transaction.SignedTransaction object at 0x108f09828>]
↑
Transactionに関わっていないUserはSignされたTransactionを受け取り、未確認Transactionとして保持する。

[Verifier.receive_signed_trx] Alice: not going to verify this transaction as I'm involved
[Verifier.receive_signed_trx] Bob: not going to verify this transaction as I'm involved
↑
Transactionの当事者(AliceとBob)は何もしない。

[User.send] Bob: sending a message to Chris. (Ho!:2.0).
[Network.announce_signed_trx] announcing "Transaction signed by Bob (Message Transaction: "Ho!" to Chris with fee 2.0)"
[Verifier.receive_signed_trx] Alice: unconfirmed transactions [<simplest.transaction.SignedTransaction object at 0x108f09c50>]
[Verifier.receive_signed_trx] Dan: unconfirmed transactions [<simplest.transaction.SignedTransaction object at 0x108f09828>, <simplest.transaction.SignedTransaction object at 0x108f09c50>]
[Verifier.receive_signed_trx] Chris: not going to verify this transaction as I'm involved
[Verifier.receive_signed_trx] Bob: not going to verify this transaction as I'm involved
↑
BobがChrisにメッセージを送ると、同様に、TransactionがNetwork全体にアナウンスされ、Transactionに関わっていないUserが未確認Transactionとして保持する。

[User.send] Chris: sending a message to Alice. (Yo!Ho!:3.0).
[Network.announce_signed_trx] announcing "Transaction signed by Chris (Message Transaction: "Yo!Ho!" to Alice with fee 3.0)"
[Verifier.receive_signed_trx] Alice: not going to verify this transaction as I'm involved
[Verifier.receive_signed_trx] Dan: unconfirmed transactions [<simplest.transaction.SignedTransaction object at 0x108f09828>, <simplest.transaction.SignedTransaction object at 0x108f09c50>, <simplest.transaction.SignedTransaction object at 0x108f09cc0>]
[Verifier.receive_signed_trx] Chris: not going to verify this transaction as I'm involved
[Verifier.receive_signed_trx] Bob: unconfirmed transactions [<simplest.transaction.SignedTransaction object at 0x108f09cc0>]
↑
同様

[Verifier.verify_message_trxs] Alice: created Transaction signed by Alice (Fee Transaction: Alice gets confirmation fee 2.0)
↑
AliceがこれまでのTransactionを認証(ビットコインで言うところのマイニング？)する。

[Block.init] trxs: [<simplest.transaction.SignedTransaction object at 0x108f09c50>, <simplest.transaction.SignedTransaction object at 0x108f09d30>], prev_block: None
↑
複数のTransactionをまとめたBlockが生成される。Aliceが関わっていない取引(Bob-Chris間取引)しか認証できないので、得られるFeeは2.0。

[Network.announce_block] announcing "Block of 2 transactions (Block Id: 0003430f7a84c5973edf31e42e9c25c0eed725af7e818adba62b0efe4d966188, Previous Block Id: None, secret: 27)"
↑
2つのトランザクション(1つのMessageTransactionと1つのFeeTransaction)を含むBlockが生成されたことがアナウンスされる。

[Verifier.receive_block] Alice: validated Block of 2 transactions (Block Id: 0003430f7a84c5973edf31e42e9c25c0eed725af7e818adba62b0efe4d966188, Previous Block Id: None, secret: 27) is valid
[Verifier.receive_block] Alice: my trx "Fee Transaction: Alice gets confirmation fee 2.0" is validated by network!
[Verifier.receive_block] Dan: validated Block of 2 transactions (Block Id: 0003430f7a84c5973edf31e42e9c25c0eed725af7e818adba62b0efe4d966188, Previous Block Id: None, secret: 27) is valid
[Verifier.receive_block] Chris: validated Block of 2 transactions (Block Id: 0003430f7a84c5973edf31e42e9c25c0eed725af7e818adba62b0efe4d966188, Previous Block Id: None, secret: 27) is valid
[Verifier.receive_block] Bob: validated Block of 2 transactions (Block Id: 0003430f7a84c5973edf31e42e9c25c0eed725af7e818adba62b0efe4d966188, Previous Block Id: None, secret: 27) is valid
[Verifier.receive_block] Bob: my trx "Message Transaction: "Ho!" to Chris with fee 2.0" is validated by network!

[Verifier.verify_message_trxs] Dan: created Transaction signed by Dan (Fee Transaction: Dan gets confirmation fee 4.0)
↑
続いてDanが残りのTransactionを認証する。DanはどのMessageTransactionにも関わっていないため、残りの全てのMessageTransactionを認証できるはず。

[Block.init] trxs: [<simplest.transaction.SignedTransaction object at 0x108f09828>, <simplest.transaction.SignedTransaction object at 0x108f09cc0>, <simplest.transaction.SignedTransaction object at 0x108f09da0>], prev_block: Block of 2 transactions (Block Id: 0003430f7a84c5973edf31e42e9c25c0eed725af7e818adba62b0efe4d966188, Previous Block Id: None, secret: 27)
↑
Aliceが承認していないTransactionを含むBlockが生成された。prev_blockとしてAliceが生成したブロックを持っている。（ブロックがチェーン状になってる！）

[Network.announce_block] announcing "Block of 3 transactions (Block Id: 000302fdb2b0a45e99e40675cce0299de96d227289d200210a0d774653a80b9a, Previous Block Id: 0003430f7a84c5973edf31e42e9c25c0eed725af7e818adba62b0efe4d966188, secret: 1545)"
[Verifier.receive_block] Alice: validated Block of 3 transactions (Block Id: 000302fdb2b0a45e99e40675cce0299de96d227289d200210a0d774653a80b9a, Previous Block Id: 0003430f7a84c5973edf31e42e9c25c0eed725af7e818adba62b0efe4d966188, secret: 1545) is valid
[Verifier.receive_block] Alice: my trx "Message Transaction: "Yo!" to Bob with fee 1.0" is validated by network!
[Verifier.receive_block] Dan: validated Block of 3 transactions (Block Id: 000302fdb2b0a45e99e40675cce0299de96d227289d200210a0d774653a80b9a, Previous Block Id: 0003430f7a84c5973edf31e42e9c25c0eed725af7e818adba62b0efe4d966188, secret: 1545) is valid
[Verifier.receive_block] Dan: my trx "Fee Transaction: Dan gets confirmation fee 4.0" is validated by network!
[Verifier.receive_block] Chris: validated Block of 3 transactions (Block Id: 000302fdb2b0a45e99e40675cce0299de96d227289d200210a0d774653a80b9a, Previous Block Id: 0003430f7a84c5973edf31e42e9c25c0eed725af7e818adba62b0efe4d966188, secret: 1545) is valid
[Verifier.receive_block] Chris: my trx "Message Transaction: "Yo!Ho!" to Alice with fee 3.0" is validated by network!
[Verifier.receive_block] Bob: validated Block of 3 transactions (Block Id: 000302fdb2b0a45e99e40675cce0299de96d227289d200210a0d774653a80b9a, Previous Block Id: 0003430f7a84c5973edf31e42e9c25c0eed725af7e818adba62b0efe4d966188, secret: 1545) is valid

[Verifier.verify_message_trxs] Chris: created Transaction signed by Chris (Fee Transaction: Chris gets confirmation fee 0)
↑
続いてChrisも認証しようとするが、Danが全て認証してしまった後なのでFeeは得られない。

[Block.init] trxs: [<simplest.transaction.SignedTransaction object at 0x108f2e0f0>], prev_block: Block of 3 transactions (Block Id: 000302fdb2b0a45e99e40675cce0299de96d227289d200210a0d774653a80b9a, Previous Block Id: 0003430f7a84c5973edf31e42e9c25c0eed725af7e818adba62b0efe4d966188, secret: 1545)
[Network.announce_block] announcing "Block of 1 transactions (Block Id: 0006a4dc569ff1a61c6c371980635341d39be3b0c23363030511501e76ac6536, Previous Block Id: 000302fdb2b0a45e99e40675cce0299de96d227289d200210a0d774653a80b9a, secret: 1062)"
[Verifier.receive_block] Alice: validated Block of 1 transactions (Block Id: 0006a4dc569ff1a61c6c371980635341d39be3b0c23363030511501e76ac6536, Previous Block Id: 000302fdb2b0a45e99e40675cce0299de96d227289d200210a0d774653a80b9a, secret: 1062) is valid
[Verifier.receive_block] Dan: validated Block of 1 transactions (Block Id: 0006a4dc569ff1a61c6c371980635341d39be3b0c23363030511501e76ac6536, Previous Block Id: 000302fdb2b0a45e99e40675cce0299de96d227289d200210a0d774653a80b9a, secret: 1062) is valid
[Verifier.receive_block] Chris: validated Block of 1 transactions (Block Id: 0006a4dc569ff1a61c6c371980635341d39be3b0c23363030511501e76ac6536, Previous Block Id: 000302fdb2b0a45e99e40675cce0299de96d227289d200210a0d774653a80b9a, secret: 1062) is valid
[Verifier.receive_block] Chris: my trx "Fee Transaction: Chris gets confirmation fee 0" is validated by network!
[Verifier.receive_block] Bob: validated Block of 1 transactions (Block Id: 0006a4dc569ff1a61c6c371980635341d39be3b0c23363030511501e76ac6536, Previous Block Id: 000302fdb2b0a45e99e40675cce0299de96d227289d200210a0d774653a80b9a, secret: 1062) is valid

Process finished with exit code 0
```

# 3. まとめ

はじめにで述べたような、ブロックチェーンに関する素朴な疑問について、単なる概念的説明だけではなく、具体的なソースコードのイメージを伴って理解することができた（ような気がする）。
一方、Proof of workに関しては、動きのイメージは掴めたが、その必要性やどの程度困難なタスクであれば良いのかが、いまいち分からなかったので、また時間があるときに調べてみたいと思う。


# 4. 参考にしたサイト

1. [Minimum Viable Block Chain](https://www.igvita.com/2014/05/05/minimum-viable-block-chain/)
	なぜブロックチェーンが今のような仕組みになっているのか解説した記事。

2. [ブロックチェーンをもう一段深く理解する](http://wazanova.jp/items/1314)
	1の日本語による解説。

3. [実現可能な最小の Block chain のサンプルコード（未完成）](http://blog-ja.intransient.info/2016/03/block-chain.html)
	 ([imsut/minimum-viable-block-chain](https://github.com/imsut/minimum-viable-block-chain))
	1のScalaによる実装。当記事の元ネタ。

4. [izqui/blockchain](https://github.com/izqui/blockchain)
	1のGolangによる実装

5. [わかりやすいブロックチェーン(blockchain)とは何か? の説明](http://qiita.com/hshimo/items/1881fba8957c2a6e17ca)
	Blockchainとは何か(概念的説明)

6. [そろそろ Blockchain について勉強を始めるか](http://www.baldanders.info/spiegel/log2/000827.shtml)
	Blockchainとは何か(概念的説明)

7. [TED: How the blockchain will radically transform the economy](https://www.ted.com/talks/bettina_warburg_how_the_blockchain_will_radically_transform_the_economy#t-447280)
	Blockchainとは何か(概念的説明)