Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import hashlib | |
| import time | |
| import json | |
| from datetime import datetime | |
| import pytz | |
| # Blockchain Classes | |
| class Block: | |
| def __init__(self, index, timestamp, transactions, previous_hash): | |
| self.index = index | |
| self.timestamp = self.get_pakistan_time(timestamp) | |
| self.transactions = transactions | |
| self.previous_hash = previous_hash | |
| self.hash = self.calculate_hash() | |
| def get_pakistan_time(self, utc_time): | |
| """Convert UTC time to Pakistan Standard Time.""" | |
| pst_timezone = pytz.timezone("Asia/Karachi") | |
| local_time = datetime.fromtimestamp(utc_time, pytz.utc).astimezone(pst_timezone) | |
| return local_time.strftime("%a %b %d %H:%M:%S %Y") # Human-readable format | |
| def calculate_hash(self): | |
| block_content = json.dumps({ | |
| "index": self.index, | |
| "timestamp": self.timestamp, | |
| "transactions": self.transactions, | |
| "previous_hash": self.previous_hash | |
| }, sort_keys=True).encode() | |
| return hashlib.sha256(block_content).hexdigest() | |
| class Blockchain: | |
| def __init__(self): | |
| self.chain = [self.create_genesis_block()] | |
| self.pending_transactions = [] | |
| def create_genesis_block(self): | |
| return Block(0, time.time(), [], "0") | |
| def get_latest_block(self): | |
| return self.chain[-1] | |
| def add_transaction(self, transaction): | |
| self.pending_transactions.append(transaction) | |
| def mine_block(self): | |
| if not self.pending_transactions: | |
| return None | |
| new_block = Block( | |
| index=len(self.chain), | |
| timestamp=time.time(), | |
| transactions=self.pending_transactions, | |
| previous_hash=self.get_latest_block().hash | |
| ) | |
| self.chain.append(new_block) | |
| self.pending_transactions = [] # Clear pending transactions | |
| return new_block | |
| def is_chain_valid(self): | |
| for i in range(1, len(self.chain)): | |
| current_block = self.chain[i] | |
| previous_block = self.chain[i - 1] | |
| if current_block.hash != current_block.calculate_hash(): | |
| return False | |
| if current_block.previous_hash != previous_block.hash: | |
| return False | |
| return True | |
| # Streamlit App | |
| st.title("Simple Blockchain Demo") | |
| st.sidebar.header("Add a Transaction") | |
| # Initialize Blockchain | |
| if "blockchain" not in st.session_state: | |
| st.session_state.blockchain = Blockchain() | |
| blockchain = st.session_state.blockchain | |
| # Add a Transaction | |
| sender = st.sidebar.text_input("Sender") | |
| recipient = st.sidebar.text_input("Recipient") | |
| amount = st.sidebar.number_input("Amount", min_value=0.01, step=0.01) | |
| if st.sidebar.button("Add Transaction"): | |
| if sender and recipient and amount: | |
| blockchain.add_transaction({"from": sender, "to": recipient, "amount": amount}) | |
| st.sidebar.success("Transaction added to the pool!") | |
| else: | |
| st.sidebar.error("Please provide valid transaction details.") | |
| # Mine a Block | |
| if st.button("Mine a Block"): | |
| new_block = blockchain.mine_block() | |
| if new_block: | |
| st.success(f"Block {new_block.index} mined successfully!") | |
| else: | |
| st.error("No transactions to mine.") | |
| # Display Blockchain | |
| st.subheader("Blockchain Ledger") | |
| for block in blockchain.chain: | |
| st.write({ | |
| "Index": block.index, | |
| "Timestamp": block.timestamp, # Already in PST format | |
| "Transactions": block.transactions, | |
| "Previous Hash": block.previous_hash, | |
| "Hash": block.hash, | |
| }) | |
| # Validate Blockchain | |
| if st.button("Validate Blockchain"): | |
| if blockchain.is_chain_valid(): | |
| st.success("Blockchain is valid!") | |
| else: | |
| st.error("Blockchain is invalid!") | |