128 lines
2.7 KiB
Python
128 lines
2.7 KiB
Python
#! /usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
# vim:fenc=utf-8
|
|
|
|
from decimal import Decimal
|
|
from uuid import uuid4
|
|
|
|
from flask import Blueprint, request
|
|
|
|
from .blockchain import Blockchain
|
|
from .utils import jsonify
|
|
|
|
|
|
app = Blueprint('app', __name__)
|
|
identifier = str(uuid4()).replace('-', '')
|
|
blockchain = Blockchain()
|
|
|
|
|
|
@app.route('/mine', methods=['POST'])
|
|
def mine():
|
|
# We run the proof of work algorithm to get the next proof...
|
|
last_block = blockchain.last_block
|
|
proof = blockchain.proof_of_work(last_block)
|
|
|
|
# We must receive a reward for finding the proof.
|
|
# The sender is '0' to signify that this node has mined a new coin.
|
|
blockchain.new_transaction(
|
|
sender='0',
|
|
recipient=identifier,
|
|
amount=Decimal(1),
|
|
)
|
|
|
|
previous_hash = blockchain.hash(last_block)
|
|
block = blockchain.new_block(proof, previous_hash)
|
|
|
|
return jsonify({
|
|
'msg': 'New Block Forged',
|
|
'index': block['index'],
|
|
'transactions': block['transactions'],
|
|
'proof': block['proof'],
|
|
'previous_hash': block['previous_hash'],
|
|
}), 200
|
|
|
|
|
|
@app.route('/transactions', methods=['POST'])
|
|
def create_transaction():
|
|
sender = request.json.get('sender')
|
|
recipient = request.json.get('recipient')
|
|
amount = request.json.get('amount')
|
|
if None in (sender, recipient, amount):
|
|
return {'msg': 'Missing parameter'}, 400
|
|
|
|
index = blockchain.new_transaction(
|
|
sender,
|
|
recipient,
|
|
Decimal(amount),
|
|
)
|
|
|
|
return jsonify({
|
|
'msg': f'Transaction will be added to Block {index}'
|
|
}), 201
|
|
|
|
|
|
@app.route('/chain', methods=['GET'])
|
|
def full_chain():
|
|
return jsonify({
|
|
'chain': blockchain.chain,
|
|
'length': len(blockchain.chain),
|
|
}), 200
|
|
|
|
|
|
@app.route('/identifier', methods=['GET'])
|
|
def get_identifier():
|
|
return jsonify({
|
|
'identifier': identifier
|
|
})
|
|
|
|
|
|
@app.route('/nodes', methods=['GET'])
|
|
def get_nodes():
|
|
return jsonify({
|
|
'nodes': list(blockchain.nodes),
|
|
}), 200
|
|
|
|
|
|
@app.route('/nodes/<identifier>/balance', methods=['GET'])
|
|
def get_balance(identifier):
|
|
balance = blockchain.get_balance(identifier)
|
|
if balance is None:
|
|
return jsonify({
|
|
'msg': 'Chain is not valid',
|
|
}), 500
|
|
|
|
return jsonify({
|
|
'identifier': identifier,
|
|
'balance': balance,
|
|
}), 200
|
|
|
|
|
|
@app.route('/nodes/register', methods=['POST'])
|
|
def register_nodes():
|
|
nodes = request.json.get('nodes')
|
|
if None in (nodes,):
|
|
return {'msg': 'No valid list of nodes'}, 400
|
|
|
|
for node in nodes:
|
|
blockchain.register_node(node)
|
|
|
|
return jsonify({
|
|
'msg': 'New nodes have been added',
|
|
'total_nodes': list(blockchain.nodes),
|
|
}), 201
|
|
|
|
|
|
@app.route('/nodes/resolve', methods=['POST'])
|
|
def consensus():
|
|
replaced = blockchain.resolve_conflicts()
|
|
|
|
if replaced:
|
|
message = 'Our chain was replaced'
|
|
else:
|
|
message = 'Our chain is authoritative'
|
|
|
|
return jsonify({
|
|
'msg': message,
|
|
'chain': blockchain.chain,
|
|
}), 200
|