blockchain / app.py
kevin1911's picture
Create app.py
c56049d verified
raw
history blame
3.72 kB
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)