0. はじめに
ブロックチェーンについては、ネットの記事を流し読んだ程度で、「ブロックがチェーン状につながっている」とか「中央集権的ではなく分散的」といったことはなんとなく聞きかじってはいたものの、ちゃんと理解してはいなかったので調べてみた。
本を読んで概念を表面的に理解するよりも、これ以上削ったらブロックチェーンとはいえないレベルの「最小限のブロックチェーン」を実際に作ってみたら楽しいのではないかと思い、ネットを漁ってみるとまさにうってつけの記事があった。
実現可能な最小の Block chain のサンプルコード(未完成)
(imsut/minimum-viable-block-chain)
これをPythonに翻訳して実行結果を眺めることで、以下の様なことを具体的なイメージを伴って理解できた(ような気になれた)。
- ブロックって何?
- ブロックがチェーン状に保持されるってどういうこと?
- 中央集権的ではなく分散的な信頼ネットワークが構築される?
- ビットコインの採掘(マイニング)って何?
- 過去データの改竄をどのように防いでいるの?
1. 登場するクラスの概要
ブロックチェーンとは何かを一言で言うと、「分散していながら、改竄が困難でデータの信頼性が担保された追記型の台帳」と理解している。
これは、User、Transaction、Verifier、Network、Blockという5つのクラスが、相互に作用することによって実現されている。
User
ブロックチェーンネットワークの参加者を表すクラス。
他のUserとメッセージのやり取りをする。
(ソースコード)
Transaction
User間のやり取りを表すクラス。
Transactionには下記の3種類がある。
- MessageTransaction: User間のメッセージのやり取りを表す
- FeeTransaction: User間の過去のメッセージのやり取りを認証するTransaction
- SignedTransaction: MessageTransactionにSignしたもの。普通はPKIなどで暗号化するらしいがここでは省略。
FeeTransactionでは、他のUser間のMessageTransactionを認証することによってFeeを得ることができる。(ビットコインで言うところのマイニング?)
(ソースコード)
Verifier
- User間のやり取りを認証するクラス。
- UserはVerifierを継承しているので、全てのUserはVerifierでもある。
- 未認証のTransactionを保持し、Userの誰かがFeeTransactionを起こすとBlockを生成する。
- 属性
__last_block
としてブロックチェーンを保持する。
(ソースコード)
Network
- ブロックチェーンネットワークそのもの。
- ネットワークに参加しているユーザーにトランザクションの発生をアナウンスする。
(ソースコード)
Block
- 幾つかのTransactionをまとめたデータ。
- User(Verifier)が他のUserのTransactionを認証することによって生成される。
- Blockを生成するには、計算能力が必要なタスク(ここではcreate_id)をこなす必要がある。これがいわゆる
Proof of Work
。 - Blockは一つ前のBlockを指し示すprev_blockという属性を持ち、全Transactionデータはチェーン状に連なったBlockの集まりとして保持される。
(ソースコード)
2. 実験
例えば、下記の様にTransactionを実行し、全体の動きを観察する。
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()
(ソースコード)
実行結果
※下記実行結果中の「↑」マークに続く行は筆者のコメント
~/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. 参考にしたサイト
-
Minimum Viable Block Chain
なぜブロックチェーンが今のような仕組みになっているのか解説した記事。 -
ブロックチェーンをもう一段深く理解する
1の日本語による解説。 -
実現可能な最小の Block chain のサンプルコード(未完成)
(imsut/minimum-viable-block-chain)
1のScalaによる実装。当記事の元ネタ。 -
izqui/blockchain
1のGolangによる実装 -
わかりやすいブロックチェーン(blockchain)とは何か? の説明
Blockchainとは何か(概念的説明) -
そろそろ Blockchain について勉強を始めるか
Blockchainとは何か(概念的説明) -
TED: How the blockchain will radically transform the economy
Blockchainとは何か(概念的説明)