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

  • 35
    いいね
  • 2
    コメント

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. 参考にしたサイト

  1. Minimum Viable Block Chain
    なぜブロックチェーンが今のような仕組みになっているのか解説した記事。

  2. ブロックチェーンをもう一段深く理解する
    1の日本語による解説。

  3. 実現可能な最小の Block chain のサンプルコード(未完成)
    (imsut/minimum-viable-block-chain)
    1のScalaによる実装。当記事の元ネタ。

  4. izqui/blockchain
    1のGolangによる実装

  5. わかりやすいブロックチェーン(blockchain)とは何か? の説明
    Blockchainとは何か(概念的説明)

  6. そろそろ Blockchain について勉強を始めるか
    Blockchainとは何か(概念的説明)

  7. TED: How the blockchain will radically transform the economy
    Blockchainとは何か(概念的説明)