周回遅れでIT業界デビューしたエンジニアのブログ

就職氷河期にモロにぶち当たり、人生で混迷を極めた末にIT業界に安寧を見出そうとしているアラフォーのお勉強日記です。

Pythonでブロックチェーンに入門。コードを書いてみた

あけましておめでとうございます。
今年もよろしくお願いいたします!

f:id:sionff:20180119162019j:plain

ブロックチェーンに入門

なんだかスゴいらしい!と前から気になってはいたものの、実際にどんなものかはよく知らなかったので、手を動かしてみることにしました。

まずは事前のインプット。ブロックチェーンに関する説明スライドがあり、分かりやすいです。
mayonez.jp

つまりはハッシュコードの数珠繋ぎなのですねー。ふむふむ。
「前のブロックのハッシュコードを次のブロックに渡す」を延々と繰り返すので、もし途中で割り込んだり改ざんするとつじつまが合わなくなってドカーン。納得。

コードを書いてみよう

今回の教科書はこちらです。ありがとうございます!
qiita.com

ブロックを定義&ハッシュ生成

# cryptocurrency_block.py

import hashlib

class Block():
    def __init__(self, index, timestamp, data, previous_hash):
        self.index = index
        self.timestamp = timestamp
        self.data = data
        self.previous_hash = previous_hash
        self.hash = self.hash_block()

    def hash_block(self):
        """
        generates a cryptographic hash of the block's index,
        timestamp, data, and the hash of the previous block's hash.
        """
        sha = hashlib.sha3_256()
        sha.update((str(self.index) +
                    str(self.timestamp) +
                    str(self.data) +
                    str(self.previous_hash)).encode('utf-8'))
        return sha.hexdigest()

hash_block()のshaは「Secure Hash Algorithm」の意味で、

暗号学的ハッシュ関数であり、アメリカ国立標準技術研究所(NIST)によって標準のハッシュ関数Secure Hash Standardに指定されている

とかなんとか。最新はSHA3です。

上でインポートしているhashlibがハッシュオブジェクトを作ってくれるライブラリで、例えば「SHA1」のハッシュオブジェクトを作るには 「sha1()」とする、という寸法です。hashlibではこれらのアルゴリズムを提供していて、下に行くほど強度が上がります。

  • md5()
  • sha1()
  • sha224()
  • sha256()
  • sha384()
  • sha512()

ちなみに大昔のMD2は、今もRSA暗号といっしょに公開鍵証明書を発行する公開鍵基盤として使われ続けているとか。

1個目のブロックを生成

# cryptocurrency_genesis.py

from cryptocurrency_block import *
import datetime as date

def create_genesis_block():
    return Block(0, date.datetime.now(), "Genesis Block", 0)

で1個目のブロックを生成します。やることはいたってシンプル。

2個目以降のブロックを生成

# cryptocurrency_new_block.py

import datetime as date
from cryptocurrency_block import *

def next_block(last_block):
    this_index = last_block.index + 1
    this_timestamp = date.datetime.now()
    this_data = "Hey! I'm block " + str(this_index)
    this_hash = last_block.hash
    return Block(this_index, this_timestamp, this_data, this_hash)

前のブロックのハッシュ値を受け取って、新しいブロックを生成します。

ブロックチェーンを生成

# cryptocurrency_blockchain.py

from cryptocurrency_genesis import *
from cryptocurrency_new_block import *

blockchain = [create_genesis_block()]
previous_block = blockchain[0]

num_of_blocks_to_add = 20

for _ in range(0, num_of_blocks_to_add):
    blocks_to_add = next_block(previous_block)
    blockchain.append(blocks_to_add)
    previous_block = blocks_to_add
    print("Block {} has been added to the blockchain.".format(blocks_to_add.index))
    print("Hash: {}\n".format(blocks_to_add.hash))

指定した数だけブロックを作りブロックチェーンを形成します。
リストのblockchainにぽこぽこ入っていく感じですね。

では動かしてみましょう

上のコードを実行すると……

Block 1 has been added to the blockchain.
Hash: ca0c12b49fc89333cd1014583a82848ec82830c478c1900c9014f9ea3c978ffa

Block 2 has been added to the blockchain.
Hash: 7e4a495e4968e18e68f6bd4654077f676aaf7a9e246706e5a53eaa42ae3ad14b

Block 3 has been added to the blockchain.
Hash: 39b78c338c6de63e966c6fd27fab7dc9776c634e83daab06dbc5467f9cc6e028

Block 4 has been added to the blockchain.
Hash: 8aca7ff98f5c06f24aa2fb93ff41ef6dc18bda1afdca830292e20a558f310c7f

...

Block 20 has been added to the blockchain.
Hash: 37beeb24777c466273c5f2c9062d303ec3dee37d2eef2c87be72e46c9782e8fb

と、めでたくブロックチェーンが作られます。もう出来ちゃった!


ちなみに、blockchainの中をのぞくと……

print(blockchain)

[<__main__.Block object at 0x0000020BA7F62C18>, ... , <__main__.Block object at 0x0000020BA7F4D630>]

最初のブロックを含めて、21個分のオブジェクトのリストができています。


これらのオブジェクトのハッシュ値を表示すると、

print(blockchain[0].previous_hash)
print(blockchain[0].hash)
print(blockchain[1].previous_hash)
print(blockchain[1].hash)
print(blockchain[2].previous_hash)
print(blockchain[2].hash)
print(blockchain[3].previous_hash)
print(blockchain[3].hash)
print(blockchain[4].previous_hash)
print(blockchain[4].hash)

0 # [0]の前のブロックのハッシュ値(存在しないので設定した0が入っている)
dea7d8146b5243f8ec31530a8d2f7a74d62c03da38ec1d8bccec3ff6026b33a8 # [0]のハッシュ値
dea7d8146b5243f8ec31530a8d2f7a74d62c03da38ec1d8bccec3ff6026b33a8 # [1]の前のブロックのハッシュ値
ca0c12b49fc89333cd1014583a82848ec82830c478c1900c9014f9ea3c978ffa # [1]のハッシュ値
ca0c12b49fc89333cd1014583a82848ec82830c478c1900c9014f9ea3c978ffa # [2]の前のブロックのハッシュ値
7e4a495e4968e18e68f6bd4654077f676aaf7a9e246706e5a53eaa42ae3ad14b # [2]のハッシュ値
7e4a495e4968e18e68f6bd4654077f676aaf7a9e246706e5a53eaa42ae3ad14b # [3]の前のブロックのハッシュ値
39b78c338c6de63e966c6fd27fab7dc9776c634e83daab06dbc5467f9cc6e028 # [3]のハッシュ値
39b78c338c6de63e966c6fd27fab7dc9776c634e83daab06dbc5467f9cc6e028 # [4]の前のブロックのハッシュ値
8aca7ff98f5c06f24aa2fb93ff41ef6dc18bda1afdca830292e20a558f310c7f # [4]のハッシュ値

となり、ハッシュ値が次のブロックに渡されていることが分かります。

あわせて読みたい


これでブロックチェーンの基本的な仕組みを理解することができました。実際にはこれに色々乗っかってくると思うのですけれど……自分で手を動かしてみると面白いですね!