Last active
January 21, 2022 05:33
-
-
Save mohitkh7/b2364b8703ae90f96539afd32ecfabcf to your computer and use it in GitHub Desktop.
Workshop on blockchain - Scipy 2021
This file contains 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
""" | |
Exercises: | |
Try to change difficulty level in proof of work algorithm and see how long does it takes to compute nonce. | |
Write a method to validate the chain. | |
Reward the mining node. | |
""" | |
# blockchain.py | |
import hashlib | |
import json | |
class Blockchain: | |
def __init__(self): | |
self.chain = [] | |
self.pending_transactions = [] | |
# create genesis block | |
self.add_new_block(0, 100) | |
def add_transaction(self, sender, receiver, amount): | |
transaction = { | |
"sender": sender, | |
"receiver": receiver, | |
"amount": amount | |
} | |
self.pending_transactions.append(transaction) | |
def add_new_block(self, previous_block_hash, nonce): | |
block = { | |
"transactions": self.pending_transactions, | |
"previous_hash": previous_block_hash, | |
"nonce": nonce | |
} | |
self.chain.append(block) | |
self.pending_transactions = [] | |
@staticmethod | |
def hash(block): | |
block_string = json.dumps(block, sort_keys=True) | |
block_bytes = block_string.encode() | |
hash_obj = hashlib.sha256(block_bytes) | |
return hash_obj.hexdigest() | |
@property | |
def last_block(self): | |
return self.chain[-1] | |
def proof_of_work(self, previous_block_hash): | |
""" | |
given a p, identify a value x such that hash has 4 leading zeros | |
""" | |
nonce = 0 | |
while True: | |
if self.valid(previous_block_hash, nonce): | |
break | |
nonce += 1 | |
return nonce | |
@staticmethod | |
def valid(previous_block_hash, nonce): | |
guess = f'{previous_block_hash}{nonce}'.encode() | |
hash_value = hashlib.sha256(guess).hexdigest() | |
return hash_value[:4] == "0000" | |
# app.py | |
from flask import Flask, jsonify, request | |
from blockchain import Blockchain | |
app = Flask(__name__) | |
blockchain = Blockchain() | |
@app.route('/chain') | |
def view_chain(): | |
return jsonify(blockchain.chain) | |
@app.route('/transaction') | |
def add_transaction(): | |
sender = request.args.get('sender') | |
receiver = request.args.get('receiver') | |
amount = request.args.get('amount') | |
blockchain.add_transaction(sender, receiver, amount) | |
return "Transaction is recorded, will be added soon to chain" | |
@app.route('/mine') | |
def add_new_block(): | |
# Get previous block | |
last_block = blockchain.last_block | |
# Need to compute its hash | |
previous_block_hash = blockchain.hash(last_block) | |
# I need to figure out nonce | |
nonce = blockchain.proof_of_work(previous_block_hash) | |
# mine the block | |
blockchain.add_new_block(previous_block_hash, nonce) | |
return "A new block is mined" | |
if __name__ == "__main__": | |
app.run(debug=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment