import hashlib
import time
class Block:
def __init__(self, index, data, previous_hash, timestamp=None):
self.index = index
self.timestamp = timestamp or time.time()
self.data = data
self.previous_hash = previous_hash
self.nonce = 0
self.hash = self.compute_proof_of_work()
def compute_hash(self):
content = f"{self.index}{self.timestamp}{self.data}{self.previous_hash}{self.nonce}"
return hashlib.sha256(content.encode()).hexdigest()
def compute_proof_of_work(self, difficulty=3):
prefix = '0' * difficulty
while True:
hash_result = self.compute_hash()
if hash_result.startswith(prefix):
return hash_result
self.nonce += 1
class Blockchain:
def __init__(self):
self.chain = [self.create_genesis_block()]
self.difficulty = 3
def create_genesis_block(self):
return Block(0, "Genesis Block", "0")
def add_block(self, data):
previous = self.chain[-1]
new_block = Block(len(self.chain), data, previous.hash)
self.chain.append(new_block)
def is_valid_chain(self, chain):
for i in range(1, len(chain)):
current = chain[i]
previous = chain[i - 1]
if current.previous_hash != previous.hash or \
current.hash != current.compute_hash():
return False
return True
def replace_chain(self, other_chains):
longest_chain = self.chain
for chain in other_chains:
if len(chain) > len(longest_chain) and self.is_valid_chain(chain):
longest_chain = chain
self.chain = longest_chain
def display(self):
for block in self.chain:
print(f"Block {block.index} | Hash: {block.hash}")
print(f" Data: {block.data}")
print(f" Nonce: {block.nonce}")
print(f" Previous Hash: {block.previous_hash}\n")
# --- Simulate Multiple Nodes and Consensus ---
if __name__ == "__main__":
# Create multiple blockchains (nodes)
node_A = Blockchain()
node_B = Blockchain()
node_C = Blockchain()
# Each node adds blocks
node_A.add_block("A1")
node_A.add_block("A2")
node_B.add_block("B1")
node_C.add_block("C1")
node_C.add_block("C2")
node_C.add_block("C3")
print("\nBefore Consensus:")
print("Node A Chain Length:", len(node_A.chain))
print("Node B Chain Length:", len(node_B.chain))
print("Node C Chain Length:", len(node_C.chain))
# Apply consensus: Node A syncs with longest chain (Node C)
node_A.replace_chain([node_B.chain, node_C.chain])
print("\nAfter Consensus (Node A):")
node_A.display()