Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 166 additions & 0 deletions app1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
from flask import Flask, render_template, jsonify, request, send_from_directory
from uuid import uuid4
from blockchain.blockchain import Blockchain
from flask_cors import CORS
import sys

# Configure Flask
app = Flask(__name__, static_folder='templates')
CORS(app, resources={r"/*": {"origins": "*"}})

# Unique Node Address
node_identifier = str(uuid4()).replace('-', '')

# Initialize Blockchain
blockchain = Blockchain()

# --- HELPER: Safe Transaction Getter ---
def get_pending_txs():
# Tries different common names for the transaction list to avoid 500 Errors
if hasattr(blockchain, 'current_transactions'):
return blockchain.current_transactions
elif hasattr(blockchain, 'pending_transactions'):
return blockchain.pending_transactions
elif hasattr(blockchain, 'transactions'):
return blockchain.transactions
else:
print("ERROR: Could not find transaction list in Blockchain class!")
return []

@app.route('/')
def index():
return render_template('index.html')

# --- Serve Local Static Files (Fixes "Elliptic" load error) ---
@app.route('/<path:filename>')
def serve_static(filename):
return send_from_directory('templates', filename)

@app.route('/transactions', methods=['GET'])
def get_transactions():
try:
txs = get_pending_txs()
return jsonify(txs), 200
except Exception as e:
print(f"ERROR in /transactions: {e}")
return jsonify({'error': str(e)}), 500

@app.route('/mine', methods=['GET'])
def mine():
try:
# 1. Run Proof of Work
last_block = blockchain.last_block
last_proof = last_block['proof']
proof = blockchain.proof_of_work(last_proof)

# 2. Reward the miner (Sender "0" means new coin)
blockchain.new_transaction(
sender="0",
recipient=node_identifier,
amount=1,
)

# 3. Forge the new Block
previous_hash = blockchain.hash(last_block)
block = blockchain.new_block(proof, previous_hash)

response = {
'message': "New Block Forged",
'index': block['index'],
'transactions': block['transactions'],
'proof': block['proof'],
'previous_hash': block['previous_hash'],
}
return jsonify(response), 200
except Exception as e:
print(f"ERROR in /mine: {e}")
return jsonify({'error': str(e)}), 500

@app.route('/transactions/new', methods=['POST'])
def new_transaction():
try:
values = request.get_json()
required = ['sender', 'recipient', 'amount']
if not all(k in values for k in required):
return 'Missing values', 400

index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])
response = {'message': f'Transaction will be added to Block {index}'}
return jsonify(response), 201
except Exception as e:
print(f"ERROR in /transactions/new: {e}")
return jsonify({'error': str(e)}), 500

@app.route('/chain', methods=['GET'])
def full_chain():
try:
response = {
'chain': blockchain.chain,
'length': len(blockchain.chain),
}
return jsonify(response), 200
except Exception as e:
print(f"ERROR in /chain: {e}")
return jsonify({'error': str(e)}), 500

@app.route('/wallet', methods=['GET'])
def get_wallet():
try:
balance = 0

# 1. Check confirmed blocks
for block in blockchain.chain:
# Handle different transaction structures (dict vs object)
txs = block.get('transactions', []) if isinstance(block, dict) else getattr(block, 'transactions', [])

for trans in txs:
# Safe access to sender/recipient
if isinstance(trans, dict):
r = trans.get('recipient')
s = trans.get('sender')
a = trans.get('amount', 0)
else:
r = getattr(trans, 'recipient', None)
s = getattr(trans, 'sender', None)
a = getattr(trans, 'amount', 0)

if r == node_identifier:
balance += a
if s == node_identifier:
balance -= a

# 2. Check pending pool
pending = get_pending_txs()
for trans in pending:
if isinstance(trans, dict):
s = trans.get('sender')
a = trans.get('amount', 0)
else:
s = getattr(trans, 'sender', None)
a = getattr(trans, 'amount', 0)

if s == node_identifier:
balance -= a

response = {
'node_id': node_identifier,
'balance': balance
}
return jsonify(response), 200
except Exception as e:
print(f"ERROR in /wallet: {e}")
return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
# Print what the server is finding to help debug
print("--- DEBUG INFO ---")
print(f"Blockchain initialized.")
if hasattr(blockchain, 'current_transactions'):
print("Using: blockchain.current_transactions")
elif hasattr(blockchain, 'pending_transactions'):
print("Using: blockchain.pending_transactions")
else:
print("WARNING: Could not find transaction list variable name!")
print("------------------")

app.run(host='0.0.0.0', port=5000, debug=True)
180 changes: 78 additions & 102 deletions blockchain/app.py
Original file line number Diff line number Diff line change
@@ -1,132 +1,108 @@
from flask import Flask, jsonify, request, render_template
from flask_cors import CORS

from flask import Flask, jsonify, request, send_from_directory, render_template
from uuid import uuid4
from blockchain.blockchain import Blockchain
from flask_cors import CORS

from .blockchain import Blockchain, MINING_REWARD, MINING_SENDER
# Instantiate the Node
app = Flask(__name__, static_folder='templates')

# Fix for "Status Offline": Allow all domains to access the API
CORS(app, resources={r"/*": {"origins": "*"}})

# Initialize Flask app
app = Flask(__name__)
CORS(app)
# Generate a globally unique address for this node
node_identifier = str(uuid4()).replace('-', '')

# Define blockchain Variables
# Instantiate the Blockchain
blockchain = Blockchain()
node_identifier = str(uuid4()).replace("-", "")


@app.route("/")
@app.route('/')
def index():
return render_template("index.html")

return render_template('index.html')

@app.route("/configure")
def configure():
return render_template("configure.html")
# Allow the browser to load the local crypto library
@app.route('/<path:filename>')
def serve_static(filename):
return send_from_directory('templates', filename)


@app.route("/transactions/new", methods=["POST"])
def new_transaction():
values = request.form

required = ["sender_address", "recipient_address", "amount", "signature"]
if not all(k in values for k in required):
return "Missing values", 400

transaction_result = blockchain.submit_transaction(
values["sender_address"],
values["recipient_address"],
values["amount"],
values["signature"],
@app.route('/mine', methods=['GET'])
def mine():
# 1. Add the Mining Reward Transaction BEFORE calculating proof
# If we add it after, the proof will be invalid for the block content.
blockchain.new_transaction(
sender="0",
recipient=node_identifier,
amount=1,
)

if not transaction_result:
response = {"message": "Invalid Transaction!"}
return jsonify(response), 406
else:
response = {
"message": "Transaction will be added to Block " + str(transaction_result)
}
return jsonify(response), 201


@app.route("/transactions/get", methods=["GET"])
def get_transactions():
transactions = blockchain.transactions

response = {"transactions": transactions}
return jsonify(response), 200
# 2. Run the Proof of Work algorithm to get the next proof
# We do NOT pass arguments because blockchain.py uses self.transactions
proof = blockchain.proof_of_work()

# 3. Forge the new Block by adding it to the chain
previous_hash = blockchain.hash(blockchain.last_block)
block = blockchain.new_block(proof, previous_hash)

@app.route("/chain", methods=["GET"])
def full_chain():
response = {
"chain": blockchain.chain,
"length": len(blockchain.chain),
'message': "New Block Forged",
'index': block['index'],
'transactions': block['transactions'],
'proof': block['proof'],
'previous_hash': block['previous_hash'],
}
return jsonify(response), 200

@app.route('/transactions/new', methods=['POST'])
def new_transaction():
values = request.get_json()

@app.route("/mine", methods=["GET"])
def mine():
# We run the proof of work algorithm to get the next proof...
last_block = blockchain.chain[-1]
nonce = blockchain.proof_of_work()
print(last_block)

# We must receive a reward for finding the proof.
blockchain.submit_transaction(
sender_address=MINING_SENDER,
recipient_address=blockchain.node_id,
value=MINING_REWARD,
signature="",
)
# Check that the required fields are in the POST'ed data
required = ['sender', 'recipient', 'amount']
if not all(k in values for k in required):
return 'Missing values', 400

# Forge the new Block by adding it to the chain
previous_hash = blockchain.hash(last_block)
block = blockchain.new_block(nonce, previous_hash)
# Create a new Transaction
index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])

response = {'message': f'Transaction will be added to Block {index}'}
return jsonify(response), 201

@app.route('/chain', methods=['GET'])
def full_chain():
response = {
"message": "New Block Forged",
"block_number": block["index"],
"transactions": block["transactions"],
"nonce": block["nonce"],
"previous_hash": block["previous_hash"],
'chain': blockchain.chain,
'length': len(blockchain.chain),
}
return jsonify(response), 200

@app.route('/transactions', methods=['GET'])
def get_transactions():
return jsonify(blockchain.transactions), 200

@app.route("/nodes/register", methods=["POST"])
def register_nodes():
values = request.form
nodes = values.get("nodes").replace(" ", "").split(",")

if nodes is None:
return "Error: Please supply a valid list of nodes", 400

for node in nodes:
blockchain.register_node(node)

@app.route('/wallet', methods=['GET'])
def get_wallet():
balance = calculate_balance(node_identifier)
response = {
"message": "New nodes have been added",
"total_nodes": [node for node in blockchain.nodes],
'node_id': node_identifier,
'balance': balance
}
return jsonify(response), 201


@app.route("/nodes/resolve", methods=["GET"])
def consensus():
replaced = blockchain.resolve_conflicts()

if replaced:
response = {"message": "Our chain was replaced", "new_chain": blockchain.chain}
else:
response = {"message": "Our chain is authoritative", "chain": blockchain.chain}
return jsonify(response), 200


@app.route("/nodes/get", methods=["GET"])
def get_nodes():
nodes = list(blockchain.nodes)
response = {"nodes": nodes}
return jsonify(response), 200
def calculate_balance(node_address):
balance = 0
# 1. Check confirmed blocks
for block in blockchain.chain:
for trans in block['transactions']:
if trans['recipient'] == node_address:
balance += trans['amount']
if trans['sender'] == node_address:
balance -= trans['amount']

# 2. Check pending pool
for trans in blockchain.transactions:
if trans['sender'] == node_address:
balance -= trans['amount']

return balance

if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
Loading