blockchain / app.py
kevin1911's picture
Create app.py
c56049d verified
import gradio as gr
import networkx as nx
import matplotlib.pyplot as plt
import hashlib
import time
import io
from PIL import Image
# ------------------- BLOCKCHAIN LOGIC -------------------- #
class Block:
def __init__(self, index, data, previous_hash="0"):
self.index = index
self.timestamp = time.time()
self.data = data
self.previous_hash = previous_hash
self.nonce = 0
self.hash = self.calculate_hash()
def calculate_hash(self):
block_string = (
str(self.index) +
str(self.timestamp) +
str(self.data) +
str(self.previous_hash) +
str(self.nonce)
)
return hashlib.sha256(block_string.encode()).hexdigest()
def mine_block(block, difficulty=1):
"""
A quick "proof-of-work":
The block's hash must start with '0' * difficulty, e.g. '0' for difficulty=1.
If this is still slow for you, set difficulty=0 to skip "mining" entirely.
"""
target_prefix = "0" * difficulty
while not block.hash.startswith(target_prefix):
block.nonce += 1
block.hash = block.calculate_hash()
def create_genesis_block():
genesis = Block(index=0, data="Genesis Block", previous_hash="0")
mine_block(genesis, difficulty=1)
return genesis
# The global chain
chain = []
# Initialize the chain with a genesis block if empty
if not chain:
chain.append(create_genesis_block())
def add_block_to_chain(data):
previous_block = chain[-1]
new_block = Block(
index=len(chain),
data=data,
previous_hash=previous_block.hash
)
mine_block(new_block, difficulty=1)
chain.append(new_block)
# ------------------- VISUALIZATION -------------------- #
def visualize_chain(chain):
"""
Creates a LINEAR graph of the blockchain using NetworkX
and returns it as a PIL image.
We'll place blocks in a line (x=index, y=0) to avoid
expensive layout computations each time.
"""
G = nx.DiGraph()
# Add nodes
for blk in chain:
# node label shows index + partial hash
node_label = f"Block {blk.index}\nHash: {blk.hash[:6]}..."
G.add_node(blk.index, label=node_label)
# Add edges
for i in range(len(chain) - 1):
G.add_edge(chain[i].index, chain[i+1].index)
# Fixed, linear layout: x = index, y = 0
pos = {blk.index: (blk.index, 0) for blk in chain}
# Draw the graph
plt.figure(figsize=(10, 3))
nx.draw_networkx_nodes(G, pos, node_color="lightblue", node_size=1500)
nx.draw_networkx_edges(G, pos, arrowstyle='->', arrowsize=20)
node_labels = nx.get_node_attributes(G, 'label')
nx.draw_networkx_labels(G, pos, labels=node_labels, font_size=8)
plt.title("Toy Blockchain Visualization (Linear Layout)")
plt.axis("off")
# Convert the Matplotlib figure to a PIL image
buf = io.BytesIO()
plt.savefig(buf, format='png', bbox_inches='tight')
buf.seek(0)
plt.close()
return Image.open(buf)
def add_and_visualize_block(data):
# Add a new block with user-provided data
add_block_to_chain(data)
# Generate the updated visualization
return visualize_chain(chain)
# ------------------- GRADIO INTERFACE -------------------- #
demo = gr.Interface(
fn=add_and_visualize_block,
inputs=gr.Textbox(lines=2, label="Data for New Block", placeholder="e.g. 'My transaction'"),
outputs="image",
title="Toy Blockchain Demo (Faster Visualization)",
description=(
"Enter any data to create a new block. "
"Mining difficulty is set to 1, so it should be fast. "
"Blocks are displayed in a linear chain."
),
)
demo.launch(debug=True)