Skip to content

Instantly share code, notes, and snippets.

@mohitkh7
Last active January 21, 2022 05:33
Show Gist options
  • Save mohitkh7/b2364b8703ae90f96539afd32ecfabcf to your computer and use it in GitHub Desktop.
Save mohitkh7/b2364b8703ae90f96539afd32ecfabcf to your computer and use it in GitHub Desktop.
Workshop on blockchain - Scipy 2021
"""
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