kevin1911 commited on
Commit
c56049d
·
verified ·
1 Parent(s): 8e96d7f

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +125 -0
app.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import networkx as nx
3
+ import matplotlib.pyplot as plt
4
+ import hashlib
5
+ import time
6
+ import io
7
+ from PIL import Image
8
+
9
+ # ------------------- BLOCKCHAIN LOGIC -------------------- #
10
+
11
+ class Block:
12
+ def __init__(self, index, data, previous_hash="0"):
13
+ self.index = index
14
+ self.timestamp = time.time()
15
+ self.data = data
16
+ self.previous_hash = previous_hash
17
+ self.nonce = 0
18
+ self.hash = self.calculate_hash()
19
+
20
+ def calculate_hash(self):
21
+ block_string = (
22
+ str(self.index) +
23
+ str(self.timestamp) +
24
+ str(self.data) +
25
+ str(self.previous_hash) +
26
+ str(self.nonce)
27
+ )
28
+ return hashlib.sha256(block_string.encode()).hexdigest()
29
+
30
+ def mine_block(block, difficulty=1):
31
+ """
32
+ A quick "proof-of-work":
33
+ The block's hash must start with '0' * difficulty, e.g. '0' for difficulty=1.
34
+ If this is still slow for you, set difficulty=0 to skip "mining" entirely.
35
+ """
36
+ target_prefix = "0" * difficulty
37
+ while not block.hash.startswith(target_prefix):
38
+ block.nonce += 1
39
+ block.hash = block.calculate_hash()
40
+
41
+ def create_genesis_block():
42
+ genesis = Block(index=0, data="Genesis Block", previous_hash="0")
43
+ mine_block(genesis, difficulty=1)
44
+ return genesis
45
+
46
+ # The global chain
47
+ chain = []
48
+
49
+ # Initialize the chain with a genesis block if empty
50
+ if not chain:
51
+ chain.append(create_genesis_block())
52
+
53
+ def add_block_to_chain(data):
54
+ previous_block = chain[-1]
55
+ new_block = Block(
56
+ index=len(chain),
57
+ data=data,
58
+ previous_hash=previous_block.hash
59
+ )
60
+ mine_block(new_block, difficulty=1)
61
+ chain.append(new_block)
62
+
63
+ # ------------------- VISUALIZATION -------------------- #
64
+
65
+ def visualize_chain(chain):
66
+ """
67
+ Creates a LINEAR graph of the blockchain using NetworkX
68
+ and returns it as a PIL image.
69
+
70
+ We'll place blocks in a line (x=index, y=0) to avoid
71
+ expensive layout computations each time.
72
+ """
73
+ G = nx.DiGraph()
74
+
75
+ # Add nodes
76
+ for blk in chain:
77
+ # node label shows index + partial hash
78
+ node_label = f"Block {blk.index}\nHash: {blk.hash[:6]}..."
79
+ G.add_node(blk.index, label=node_label)
80
+
81
+ # Add edges
82
+ for i in range(len(chain) - 1):
83
+ G.add_edge(chain[i].index, chain[i+1].index)
84
+
85
+ # Fixed, linear layout: x = index, y = 0
86
+ pos = {blk.index: (blk.index, 0) for blk in chain}
87
+
88
+ # Draw the graph
89
+ plt.figure(figsize=(10, 3))
90
+ nx.draw_networkx_nodes(G, pos, node_color="lightblue", node_size=1500)
91
+ nx.draw_networkx_edges(G, pos, arrowstyle='->', arrowsize=20)
92
+ node_labels = nx.get_node_attributes(G, 'label')
93
+ nx.draw_networkx_labels(G, pos, labels=node_labels, font_size=8)
94
+
95
+ plt.title("Toy Blockchain Visualization (Linear Layout)")
96
+ plt.axis("off")
97
+
98
+ # Convert the Matplotlib figure to a PIL image
99
+ buf = io.BytesIO()
100
+ plt.savefig(buf, format='png', bbox_inches='tight')
101
+ buf.seek(0)
102
+ plt.close()
103
+ return Image.open(buf)
104
+
105
+ def add_and_visualize_block(data):
106
+ # Add a new block with user-provided data
107
+ add_block_to_chain(data)
108
+ # Generate the updated visualization
109
+ return visualize_chain(chain)
110
+
111
+ # ------------------- GRADIO INTERFACE -------------------- #
112
+
113
+ demo = gr.Interface(
114
+ fn=add_and_visualize_block,
115
+ inputs=gr.Textbox(lines=2, label="Data for New Block", placeholder="e.g. 'My transaction'"),
116
+ outputs="image",
117
+ title="Toy Blockchain Demo (Faster Visualization)",
118
+ description=(
119
+ "Enter any data to create a new block. "
120
+ "Mining difficulty is set to 1, so it should be fast. "
121
+ "Blocks are displayed in a linear chain."
122
+ ),
123
+ )
124
+
125
+ demo.launch(debug=True)