Pythonでなんちゃってブロックチェーンを作る!簡単なチュートリアル(教育用)
今回は、Pythonを使って、シンプルなブロックチェーンを作る方法について説明します。
「ブロックチェーンって何?」と疑問に思う方もいるでしょう。ブロックチェーンとは、その名の通り、情報(トランザクション)が格納された「ブロック」が連鎖的につながっているものを指します。この技術は、ビットコインなどの仮想通貨や、その他様々な分野で広く活用されています。それでは早速、コードを見てみましょう。
import hashlib
import time
class Block:
def __init__(self, index, previous_hash, transactions):
self.index = index
self.timestamp = time.time()
self.previous_hash = previous_hash
self.transactions = transactions
self.nonce = 0
self.hash = self.calculate_hash()
def calculate_hash(self):
data = str(self.index) + str(self.timestamp) + str(self.previous_hash) + str(self.transactions) + str(self.nonce)
return hashlib.sha256(data.encode('utf-8')).hexdigest()
class Blockchain:
def __init__(self):
self.blocks = [self.create_genesis_block()]
def create_genesis_block(self):
return Block(0, '0000000000000000000000000000000000000000000000000000000000000000', ['Genesis Block'])
def add_block(self, transactions):
index = len(self.blocks)
previous_hash = self.blocks[-1].hash
new_block = Block(index, previous_hash, transactions)
self.blocks.append(new_block)
def print_blockchain(blockchain, account_name):
for block in blockchain.blocks:
print(f"\n{'*' * 30} Blockchain {block.index} {'*' * 30}")
for i, transaction in enumerate(block.transactions):
print(f"\nTransaction {i+1}: {transaction}")
print(f"Account name: {account_name}")
print(f"Hash: {block.hash}")
print(f"Nonce: {block.nonce}")
print(f"Timestamp: {time.ctime(block.timestamp)}")
print(f"Previous Hash: {block.previous_hash}")
print(f"{'*' * 68}\n")
def main():
account_name = input('Enter account name: ')
transactions = input('Enter transactions (separated by commas): ').split(',')
transactions = [transaction.strip() for transaction in transactions]
blockchain = Blockchain()
for i in range(0, len(transactions), 3):
transactions_chunk = transactions[i:i+3]
blockchain.add_block(transactions_chunk)
print_blockchain(blockchain, account_name)
if __name__ == '__main__':
main()
サンプル入力とその出力
このコードを実行すると、以下のような出力が得られます(アカウント名とトランザクションはユーザーが入力した例を使用します):
ユーザー入力:
Enter account name: Alice
Enter transactions (separated by commas): Send 10 coins to Bob, Receive 5 coins from Charlie, Send 2 coins to Bob, Receive 3 coins from Charlie
コード実行結果:
**************************** Blockchain 0 ****************************
Transaction 1: Genesis Block
Account name: Alice
Hash: [初期ブロックのハッシュ値]
Nonce: 0
Timestamp: [初期ブロックのタイムスタンプ]
Previous Hash: 0000000000000000000000000000000000000000000000000000000000000000
********************************************************************
**************************** Blockchain 1 ****************************
Transaction 1: Send 10 coins to Bob
Account name: Alice
Hash: [第1ブロックのハッシュ値]
Nonce: 0
Timestamp: [第1ブロックのタイムスタンプ]
Previous Hash: [初期ブロックのハッシュ値]
Transaction 2: Receive 5 coins from Charlie
Account name: Alice
Hash: [第1ブロックのハッシュ値]
Nonce: 0
Timestamp: [第1ブロックのタイムスタンプ]
Previous Hash: [初期ブロックのハッシュ値]
Transaction 3: Send 2 coins to Bob
Account name: Alice
Hash: [第1ブロックのハッシュ値]
Nonce: 0
Timestamp: [第1ブロックのタイムスタンプ]
Previous Hash: [初期ブロックのハッシュ値]
********************************************************************
**************************** Blockchain 2 ****************************
Transaction 1: Receive 3 coins from Charlie
Account name: Alice
Hash: [第2ブロックのハッシュ値]
Nonce: 0
Timestamp: [第2ブロックのタイムスタンプ]
Previous Hash: [第1ブロックのハッシュ値]
********************************************************************
上記の出力では、それぞれのブロックについて以下の情報が表示されています:
- ブロック内の各トランザクション
- アカウント名
- ブロックのハッシュ値
- ノンス(このシンプルなコードでは、常に0)
- ブロックが生成された時間(タイムスタンプ)
- 前のブロックのハッシュ値
これにより、ユーザーはブロックチェーンの各ブロックがどのような情報を持っているか、またそれぞれのブロックが前のブロックとどのように連結しているかを視覚的に理解することができます。
まずは、2つのクラスBlock
とBlockchain
に注目してみましょう。Block
クラスはブロックを表現し、Blockchain
クラスはブロックをつなげてチェーンにする役割を果たします。それぞれのクラスについてもっと詳しく見てみましょう。
Blockクラス
このクラスでは、各ブロックの基本的な情報を保持しています。これらの情報には、以下のものがあります。
-
index
: ブロックがブロックチェーンの何番目に位置しているかを示す数値。 -
timestamp
: ブロックが作成された時間(エポック時間)。 -
previous_hash
: 一つ前のブロックのハッシュ値。これによりブロックチェーンが繋がっている。 -
transactions
: そのブロックに含まれるトランザクションのリスト。 -
nonce
: ブロック生成時に使用する一時的な数値。今回のプログラムでは特に利用はされていませんが、実際のブロックチェーン(例えばビットコイン)では、ブロックのハッシュ値を計算する際に重要な役割を果たします。 -
hash
: ブロックのハッシュ値。これはブロックの情報(インデックス、タイムスタンプ、前のハッシュ、トランザクション、ノンス)を一つの文字列にまとめ、それをsha256
ハッシュ関数でハッシュ化したものです。
Blockchainクラス
次に、Blockchain
クラスはブロックをまとめて一つのブロックチェーンを形成します。このクラスの役割は主に以下の二つです。
- ジェネシスブロック(最初のブロック)を作成する。
- 新しいブロックをチェーンに追加する。
ジェネシスブロックは、特定の初期値を持つブロックで、全てのブロックチェーンはジェネシスブロックから始まります。ジェネシスブロックはcreate_genesis_block
メソッドで作成され、その前のハッシュ値は予め定義した固定値(この場合は0の文字列)を使用します。
新しいブロックの追加はadd_block
メソッドで行われます。このメソッドでは、まずブロックチェーンの長さ(index
)と一つ前のブロックのハッシュ値(previous_hash
)を取得します。その上で、これらの値
と新たに追加されるトランザクションを使用して新しいブロックを作成し、ブロックチェーンに追加します。
このブロックチェーンを使って、実際に取引を模擬するメインの関数がmain
です。この関数では、アカウント名と取引リストを入力として受け取り、その情報を基にブロックチェーンを構築します。取引は3つずつまとめてブロックに追加され、完成したブロックチェーンはprint_blockchain
関数で出力されます。
以上が、このシンプルなブロックチェーンプログラムの概要です。ブロックチェーンは、情報の改ざん防止や分散台帳としての役割が注目されている技術です。このチュートリアルを通じて、その基本的な構造や動作原理を理解し、更なる探求の一歩として頂ければ幸いです。
注意書き
この教育用のコードは基本的なブロックチェーンの概念を理解するために作られていますが、実際のブロックチェーンシステムとは以下のような重要な点で異なります:
-
マイニング: 実際のブロックチェーンシステム(特にプルーフ・オブ・ワーク(PoW)を採用しているもの)では、新しいブロックが追加される前にマイニングというプロセスが必要です。マイニングは、特定の条件を満たすハッシュ値を見つけ出すために、ある数値(ノンス)を変更しながらハッシュ計算を繰り返す作業です。しかし、この教育用のコードではマイニングは行われておらず、ノンスは単に0として設定されています。
-
取引の検証: このコードでは、ブロックに追加する取引(トランザクション)が検証されることはありません。しかし、実際のブロックチェーンでは、取引が有効かどうか(例えば、送金者が必要な額を所有しているか)を確認する検証プロセスがあります。
-
P2Pネットワーク: 実際のブロックチェーンは、ピアツーピア(P2P)ネットワーク上で動作します。各ノード(参加者)は、ブロックチェーンの全てのコピーを持ち、新たなブロックが追加されるときはその情報をネットワーク上の他のノードと共有します。この教育用のコードでは、そのようなネットワーク機能は実装されていません。
-
コンセンサスアルゴリズム: ブロックチェーンネットワークでは、通常、コンセンサスアルゴリズム(合意形成アルゴリズム)が利用されています。これは、ネットワーク上のノードが同じブロックチェーンのコピーを保持していることを確認し、一貫性を維持するためのものです。このコードでは、単一ユーザーがすべてを制御しているため、コンセンサスアルゴリズムは不要です。
-
セキュリティ: このコードは、ブロックチェーンの基本的な概念を理解するためのものであり、実際のブロックチェーンのセキュリティ要件を満たしていません。例えば、実際のブロックチェーンでは、プライベートキーとパブリックキーのペアを使用して、取引を署名し検証します。
以上のように、実際のブロックチェーンとは様々な点で異なりますが、このコードはその基本概念を理解する上で非常に役立ちます。それでは、さらなる探求の一歩として頂ければ幸いです。