Help us understand the problem. What is going on with this article?

約60行でブロックチェーンを実装

はじめに

Udemyの講座でざっくりブロックチェーンの中身を理解したので実装してみました。講座の内容を基に自力で実装しています。
本講座ではシリコンバレーの現役エンジニアである酒井潤さんが教鞭をとっており、受講することで以下のようなプログラムであれば何も見ずとも作れるようになります。本投稿では実装していないwalletやproof_of_workの実装も行われていますので、興味を持たれた方は是非受講してみてください。同じく酒井潤さんのPython基礎講座もおすすめです。

ブロックチェーンの要素

各ブロック内の要素は以下のようになっています。

  • ブロック
    • previous_hash:前のブロックのハッシュ値
    • nonce:マイニングによって見つける値(未実装)
    • transaction:ブロック内で処理したトランザクション
    • timestamp:ブロックを作成した時間

チェーン上の全てのブロックはprevious_hashでつながっているため、チェーンの途中のブロックを改ざんしたい場合には、それ以降のすべてのハッシュ値を再計算しなければならず改ざんの防止につながります。

コード

nonceは雰囲気のために一応ついていますが、最小限の要素のみの構成としたかったため今回は機能していません。実際はhash値の先頭*文字(任意の文字数)が0になるようにnonceを計算します。

import hashlib
import time
import json


class BlockChain(object):

    # 最初のブロックを作成する
    def __init__(self):
        self.chain = []
        self.transaction_pool = []
        self.create_block(previous_hash='Initialize')

    # ブロックのハッシュ値を返す
    def hash(self, block):
        json_block = json.dumps(block)
        return hashlib.sha256(json_block.encode()).hexdigest()

    def create_block(self, previous_hash=None, nonce=0, transaction=None, timestamp=time.time()):
        block = {
            'previous_hash': previous_hash,
            'nonce': nonce,
            'transaction': transaction,
            'timestamp': timestamp
          }
        self.add_block_to_chain(block)

    def add_block_to_chain(self, block):
        self.chain.append(block)

    def mining(self):
        previous_hash = self.hash(self.chain[-1])
        nonce = 0
        transaction = self.transaction_pool
        self.transaction_pool = []
        timestamp = time.time()
        self.create_block(previous_hash, nonce, transaction, timestamp)

    # transaction_poolにtransactionを登録する
    def add_transaction(self, sender_name, reciever_name, value):
        transaction = {
            'Sender_name': sender_name,
            'Reciever_name': reciever_name,
            'Value': value
        }
        self.transaction_pool.append(transaction)

    def print_chain(self):
        for chain_index, block in enumerate(self.chain):
            print(f'{"="*40}Block {chain_index:3}')
            if block['transaction'] is None:
                print('Initialize')
                continue
            else:
                for key, value in block.items():
                    if key == 'transaction':
                        for transaction in value:
                            print(f'{"transaction":15}:')
                            for kk, vv in transaction.items():
                                print(f'\t{kk:15}:{vv}')
                    else:
                        print(f'{key:15}:{value}')


if __name__ == '__main__':
    # print('='*30 + 'Start' + '='*30)
    blockchain = BlockChain()
    blockchain.add_transaction(sender_name='Alice', reciever_name='Bob', value=100)
    blockchain.add_transaction(sender_name='Alice', reciever_name='Chris', value=1)
    blockchain.mining()
    blockchain.add_transaction(sender_name='Bob', reciever_name='Dave', value=100)
    blockchain.mining()
    blockchain.print_chain()

実行結果

========================================Block   0
Initialize
========================================Block   1
previous_hash  :54c72dc7390c09a6d2c00037c381057a7bd069e8d9c427585ce31bed16dfd0d8
nonce          :0
transaction    :
        Sender_name    :Alice
        Reciever_name  :Bob
        Value          :100
transaction    :
        Sender_name    :Alice
        Reciever_name  :Chris
        Value          :1
timestamp      :1578989130.9111161
========================================Block   2
previous_hash  :d4bb210d2e3ad304db53756e87a7513b2fca8672c6e757bef6db3fff8ff26bb1
nonce          :0
transaction    :
        Sender_name    :Bob
        Reciever_name  :Dave
        Value          :100
timestamp      :1578989132.9128711

最後に

少し前に流行って以降あまり名前を聞かなくなったブロックチェーンですが、ソニーが著作権の管理に使用していたりマイクロソフトが個人IDに使用していたりと活用事例はまだまだ増えていますので勉強しておいて損はないかと思います。
今後はdjangoと連携させたものを実装する予定です。

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
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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