Blockchain is a shared, immutable ledger that simplifies the method of recording transactions and tracking assets in a network. It’s a constantly growing list of records known as a block. These blocks are connected, creating a chain known as a blockchain.
The fundamental feature of blockchain :
-
Immutable and Unhackable records
-
Distributed ledger technology
-
Persistent in storing data (no loss of data)
Setting up Virtualenv & Installing Dependencies
create a virtualenv, using python’s built-in module called venv. Here env is the name of the environment.
python3 -m venv envpython3 -m venv envpython3 -m venv env
Enter fullscreen mode Exit fullscreen mode
for activating this virtualenv, we need to source it.
source ./env/bin/activatesource ./env/bin/activatesource ./env/bin/activate
Enter fullscreen mode Exit fullscreen mode
Installing Dependencies
we need flask as a dependency for serving our blockchain
pip install Flask==2.2.2pip install Flask==2.2.2pip install Flask==2.2.2
Enter fullscreen mode Exit fullscreen mode
Setting up Folder Structure
-
create a base folder, and name it blockchain
-
inside this folder create a file called blockchain.py which will hold our blockchain code.
-
create another file called server.py this will contain our server code, to server our blockchain.
Creating a Blockchain
Import Dependencies
import datetimeimport jsonimport hashlibimport timeimport datetime import json import hashlib import timeimport datetime import json import hashlib import time
Enter fullscreen mode Exit fullscreen mode
Now, create a class called blockchain , which will hold all our logic and chain itself. Inside this blockchain class, we will have some functions.
- init : initialize the blockchain, and creates a Genius Block
def __init__ (self) -> None:"""initialize the blockchain"""self.chain = []# create the genesis blockself.create_block(proof=1, previous_hash="0")def __init__ (self) -> None: """ initialize the blockchain """ self.chain = [] # create the genesis block self.create_block(proof=1, previous_hash="0")def __init__ (self) -> None: """ initialize the blockchain """ self.chain = [] # create the genesis block self.create_block(proof=1, previous_hash="0")
Enter fullscreen mode Exit fullscreen mode
- create_block : this function creates a new block and adds it to the blockchain, it takes proof and the previous hash as an argument
def create_block(self, proof, previous_hash):"""add a new block to the blockchain"""block = {}block["index"] = len(self.chain) + 1block["timestamp"] = str(datetime.datetime.now())block["proof"] = proofblock["previous_hash"] = previous_hashself.chain.append(block)return blockdef create_block(self, proof, previous_hash): """ add a new block to the blockchain """ block = {} block["index"] = len(self.chain) + 1 block["timestamp"] = str(datetime.datetime.now()) block["proof"] = proof block["previous_hash"] = previous_hash self.chain.append(block) return blockdef create_block(self, proof, previous_hash): """ add a new block to the blockchain """ block = {} block["index"] = len(self.chain) + 1 block["timestamp"] = str(datetime.datetime.now()) block["proof"] = proof block["previous_hash"] = previous_hash self.chain.append(block) return block
Enter fullscreen mode Exit fullscreen mode
- get_previous_block : This function gets the previous block, which is added to the blockchain
def get_previous_block(self):"""get the previous block"""return self.chain[-1]def get_previous_block(self): """ get the previous block """ return self.chain[-1]def get_previous_block(self): """ get the previous block """ return self.chain[-1]
Enter fullscreen mode Exit fullscreen mode
- proof_of_work : proof of work is a Consensus Protocol in blockchain used to define finding a number such that the hash of the number, is hard to find because it takes a lot of time, and computing power.
def proof_of_work(self, previous_proof):start_time = time.time()new_proof = 1check_proof = Falsewhile check_proof is False:hash_operation = hashlib.sha256(str(new_proof **2 - previous_proof** 2).encode()).hexdigest()if hash_operation[:4] == "0000":check_proof = Trueelse:new_proof += 1elapsed = time.time() - start_timeprint(' time take to get new_proof using pow : ', elapsed)return new_proofdef proof_of_work(self, previous_proof): start_time = time.time() new_proof = 1 check_proof = False while check_proof is False: hash_operation = hashlib.sha256( str(new_proof **2 - previous_proof** 2).encode() ).hexdigest() if hash_operation[:4] == "0000": check_proof = True else: new_proof += 1 elapsed = time.time() - start_time print(' time take to get new_proof using pow : ', elapsed) return new_proofdef proof_of_work(self, previous_proof): start_time = time.time() new_proof = 1 check_proof = False while check_proof is False: hash_operation = hashlib.sha256( str(new_proof **2 - previous_proof** 2).encode() ).hexdigest() if hash_operation[:4] == "0000": check_proof = True else: new_proof += 1 elapsed = time.time() - start_time print(' time take to get new_proof using pow : ', elapsed) return new_proof
Enter fullscreen mode Exit fullscreen mode
- hash : hash function takes a block and converts it into hash using sha256 , and returns the hash
def hash(self, block) -> str:"""hash the block using sha256, and return the hash"""encoded_block = str(json.dumps(block, sort_keys=True)).encode('utf-8')hash = hashlib.sha256(encoded_block).hexdigest()return hashdef hash(self, block) -> str: """ hash the block using sha256, and return the hash """ encoded_block = str(json.dumps(block, sort_keys=True)).encode('utf-8') hash = hashlib.sha256(encoded_block).hexdigest() return hashdef hash(self, block) -> str: """ hash the block using sha256, and return the hash """ encoded_block = str(json.dumps(block, sort_keys=True)).encode('utf-8') hash = hashlib.sha256(encoded_block).hexdigest() return hash
Enter fullscreen mode Exit fullscreen mode
- is_chain_valid : check if the blockchain is valid
def is_chain_valid(self, chain):"""check if the blockchain is valid"""if chain == [] or chain == None:# if the chain is empty or None, then the chain is not passed as a parameterchain = self.chainprevious_block = chain[0]block_index = 1while block_index < len(chain):block = chain[block_index]if block["previous_hash"] != self.hash(previous_block):return Falseprevious_proof = previous_block["proof"]proof = block["proof"]hash_operation = hashlib.sha256(str(proof **2 - previous_proof** 2).encode()).hexdigest()if hash_operation[:4] != "0000":return Falseprevious_block = blockblock_index += 1return Truedef is_chain_valid(self, chain): """ check if the blockchain is valid """ if chain == [] or chain == None: # if the chain is empty or None, then the chain is not passed as a parameter chain = self.chain previous_block = chain[0] block_index = 1 while block_index < len(chain): block = chain[block_index] if block["previous_hash"] != self.hash(previous_block): return False previous_proof = previous_block["proof"] proof = block["proof"] hash_operation = hashlib.sha256( str(proof **2 - previous_proof** 2).encode() ).hexdigest() if hash_operation[:4] != "0000": return False previous_block = block block_index += 1 return Truedef is_chain_valid(self, chain): """ check if the blockchain is valid """ if chain == [] or chain == None: # if the chain is empty or None, then the chain is not passed as a parameter chain = self.chain previous_block = chain[0] block_index = 1 while block_index < len(chain): block = chain[block_index] if block["previous_hash"] != self.hash(previous_block): return False previous_proof = previous_block["proof"] proof = block["proof"] hash_operation = hashlib.sha256( str(proof **2 - previous_proof** 2).encode() ).hexdigest() if hash_operation[:4] != "0000": return False previous_block = block block_index += 1 return True
Enter fullscreen mode Exit fullscreen mode
Creating a web server
Creating a Flask web server
import osfrom flask import Flask, jsonify# envPORT = os.getenv('PORT', 8080)DEBUG = os.getenv('DEBUG', True)app = Flask( __name__ )@app.route('/', methods=['GET'])def home():return "<h1>Welcome to the Blockchain</h1>", 200if __name__ == " __main__":app.run(host="0.0.0.0", port=PORT, debug=DEBUG)import os from flask import Flask, jsonify # env PORT = os.getenv('PORT', 8080) DEBUG = os.getenv('DEBUG', True) app = Flask( __name__ ) @app.route('/', methods=['GET']) def home(): return "<h1>Welcome to the Blockchain</h1>", 200 if __name__ == " __main__": app.run(host="0.0.0.0", port=PORT, debug=DEBUG)import os from flask import Flask, jsonify # env PORT = os.getenv('PORT', 8080) DEBUG = os.getenv('DEBUG', True) app = Flask( __name__ ) @app.route('/', methods=['GET']) def home(): return "<h1>Welcome to the Blockchain</h1>", 200 if __name__ == " __main__": app.run(host="0.0.0.0", port=PORT, debug=DEBUG)
Enter fullscreen mode Exit fullscreen mode
Importing our blockchain
importing and initializing blockchain will create Genius Block
from blockchain import Blockchainblockchain = Blockchain()from blockchain import Blockchain blockchain = Blockchain()from blockchain import Blockchain blockchain = Blockchain()
Enter fullscreen mode Exit fullscreen mode
Adding mine_block function
This mine_block function helps used to mine a block in a given blockchain
@app.route('/mine_block', methods=['GET'])def mine_block():previous_block = blockchain.get_previous_block()previous_proof = previous_block['proof']proof = blockchain.proof_of_work(previous_proof)previous_hash = blockchain.hash(previous_block)block = blockchain.create_block(proof, previous_hash)response = {}response['message'] = "Blocked is just mined !!"response['index'] = block['index']response['timestamp'] = block['timestamp']response['previous_hash'] = block['previous_hash']response['proof'] = block['proof']return jsonify(response), 201@app.route('/mine_block', methods=['GET']) def mine_block(): previous_block = blockchain.get_previous_block() previous_proof = previous_block['proof'] proof = blockchain.proof_of_work(previous_proof) previous_hash = blockchain.hash(previous_block) block = blockchain.create_block(proof, previous_hash) response = {} response['message'] = "Blocked is just mined !!" response['index'] = block['index'] response['timestamp'] = block['timestamp'] response['previous_hash'] = block['previous_hash'] response['proof'] = block['proof'] return jsonify(response), 201@app.route('/mine_block', methods=['GET']) def mine_block(): previous_block = blockchain.get_previous_block() previous_proof = previous_block['proof'] proof = blockchain.proof_of_work(previous_proof) previous_hash = blockchain.hash(previous_block) block = blockchain.create_block(proof, previous_hash) response = {} response['message'] = "Blocked is just mined !!" response['index'] = block['index'] response['timestamp'] = block['timestamp'] response['previous_hash'] = block['previous_hash'] response['proof'] = block['proof'] return jsonify(response), 201
Enter fullscreen mode Exit fullscreen mode
Adding get_chain function
This get_chain function will return a JSON list of blocks and its attribute.
@app.route('/get_chain', methods=['GET'])def get_chain():blockchain_clone = blockchain.get_chain()return jsonify(blockchain_clone), 200@app.route('/get_chain', methods=['GET']) def get_chain(): blockchain_clone = blockchain.get_chain() return jsonify(blockchain_clone), 200@app.route('/get_chain', methods=['GET']) def get_chain(): blockchain_clone = blockchain.get_chain() return jsonify(blockchain_clone), 200
Enter fullscreen mode Exit fullscreen mode
Adding is_valid function
This function checks if the current blockchain Is valid or not
@app.route('/is_valid', methods=['GET'])def is_valid():is_valid = blockchain.is_chain_valid(blockchain.chain)if is_valid:response = {}response['message'] = "Blockchain is valid"return jsonify(response), 200else:response = {}response['message'] = "Blockchain is not valid"return jsonify(response), 200@app.route('/is_valid', methods=['GET']) def is_valid(): is_valid = blockchain.is_chain_valid(blockchain.chain) if is_valid: response = {} response['message'] = "Blockchain is valid" return jsonify(response), 200 else: response = {} response['message'] = "Blockchain is not valid" return jsonify(response), 200@app.route('/is_valid', methods=['GET']) def is_valid(): is_valid = blockchain.is_chain_valid(blockchain.chain) if is_valid: response = {} response['message'] = "Blockchain is valid" return jsonify(response), 200 else: response = {} response['message'] = "Blockchain is not valid" return jsonify(response), 200
Enter fullscreen mode Exit fullscreen mode
Starting webserver
To start the web server, we will execute the server.py
python3 server.pypython3 server.pypython3 server.py
Enter fullscreen mode Exit fullscreen mode
暂无评论内容