Created
April 13, 2020 16:54
-
-
Save VedantParanjape/88ccd9dc549985e6e30569c4e8fbd91c to your computer and use it in GitHub Desktop.
A basic block chain implementation | Learnt during FDP (Factulty development program) 2019 Blockchain
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from time import time | |
import hashlib | |
import json | |
from flask import Flask, jsonify, request | |
from uuid import uuid4 | |
class Blockchain: | |
def __init__(self): | |
self.current_transactions = [] | |
self.chain = [] | |
#genesis block | |
self.add_block(previous_hash = '1', proof = 12) | |
@staticmethod | |
def hash(block): | |
block_string = json.dumps(block, sort_keys=True).encode() | |
return hashlib.sha256(block_string).hexdigest() | |
@property | |
def last_block(self): | |
return self.chain[-1] | |
def new_transaction(self, sender, recipient, amount): | |
ts = { | |
'sender': sender, | |
'recipient': recipient, | |
'amount': amount | |
} | |
self.current_transactions.append(ts) | |
return self.last_block['index'] + 1 | |
def add_block(self, proof, previous_hash): | |
block = { | |
'index': len(self.chain) + 1, | |
'timestamp': time(), | |
'transactions': self.current_transactions, | |
'proof': proof, | |
'previous_hash': previous_hash or self.hash(self.chain[-1]) | |
} | |
self.current_transactions = [] | |
self.chain.append(block) | |
return block | |
@staticmethod | |
def validate(last_proof, proof, last_hash): | |
guess = f'{last_proof}{proof}{last_hash}'.encode() | |
guess_hash = hashlib.sha256(guess).hexdigest() | |
return guess_hash[:4] == '0000' | |
def proof_of_work(self, last_block): | |
last_proof = last_block['proof'] | |
last_hash = self.hash(last_block) | |
proof = 0 | |
while self.validate(last_proof, proof, last_hash) is False: | |
proof += 1 | |
return proof | |
app = Flask(__name__) | |
node_identifier = str(uuid4()).replace('-','') | |
blockchain = Blockchain() | |
@app.route('/mine') | |
def mine(): | |
last_block = blockchain.last_block | |
proof = blockchain.proof_of_work(last_block) | |
blockchain.new_transaction( | |
sender='0', | |
recipient=node_identifier, | |
amount=20 | |
) | |
previous_hash = blockchain.hash(last_block) | |
block = blockchain.add_block(proof, previous_hash) | |
response = { | |
'message': 'Block is created', | |
'index': block['index'], | |
'transactions': block['transactions'], | |
'proof': block['proof'], | |
'previous_hash': block['previous_hash'] | |
} | |
return jsonify(response), 200 | |
@app.route('/transaction/new', methods=['POST']) | |
def new_transaction(): | |
values = request.get_json() | |
required = ['sender', 'recipient', 'amount'] | |
if not all(k in values for k in required): | |
return 'Missing Values', 400 | |
sender = values['sender'] | |
recipient = values['recipient'] | |
amount = values['amount'] | |
index = blockchain.new_transaction(sender, recipient, amount) | |
response = { | |
'message': f'Block {index}' | |
} | |
return jsonify(response), 201 | |
@app.route('/chain', methods = ['GET']) | |
def full_chain(): | |
response = { | |
'chain': blockchain.chain, | |
'length': len(blockchain.chain) | |
} | |
return jsonify(response), 200 | |
@app.route('/nodes/register', methods = ['POST']) | |
def register_nodes(): | |
values = json.loads(request.data) | |
nodes = values.get('nodes') | |
if nodes is None: | |
return 'Error', 400 | |
for node in nodes: | |
blockchain.register_node( | |
'http://127.0.0.1:' + str(node) | |
) | |
response = { | |
'message': "Added new nodes", | |
'total_nodes': list(blockchain.nodes) | |
} | |
return jsonify(response), 201 | |
if __name__ == "__main__": | |
from argparse import ArgumentParser | |
parser = ArgumentParser() | |
parser.add_argument('-p', '--port', default=5000, type=int, help='port num') | |
args = parser.parse_args() | |
port = args.port | |
app.run(host='0.0.0.0', port=port, debug=True) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment