Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
54
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

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

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とは何か(概念的説明)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
54
Help us understand the problem. What are the problem?