From 5f743a6b63b6b8196041dbcf76c01ec72ec6c947 Mon Sep 17 00:00:00 2001 From: Aurelien Rebourg Date: Thu, 27 Apr 2023 18:04:14 +0200 Subject: [PATCH] migrate python3 + add cri blocks specific data --- .gitignore | 1 + README.md | 37 ++++++-------- blockchain/chain.py | 90 ++++++++++++++++++++++++++++------ bscli.py | 103 +++++++++++++++++++++++++-------------- setup.py | 4 +- templates/blockdata.html | 68 +++++++++----------------- templates/blocks.html | 70 ++++++++------------------ templates/guide.html | 6 +-- web.py | 3 ++ 9 files changed, 207 insertions(+), 175 deletions(-) diff --git a/.gitignore b/.gitignore index fed61f6..eac7f72 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.pyc chain.txt venv/ +.venv/ build/ dist/ blockshell/ diff --git a/README.md b/README.md index 48b3a52..0a55bdc 100644 --- a/README.md +++ b/README.md @@ -23,41 +23,32 @@ Latest Mined Blocks | Block Details ![](https://preview.ibb.co/iZa5jG/Screen_Shot_2018_01_25_at_11_25_22_PM.png) | ![](https://preview.ibb.co/cDB0Jb/Screen_Shot_2018_01_25_at_11_25_35_PM.png) ## 📦 Installation -Step 1 - Create project directory -``` -mkdir && cd project_name -``` - -Step 2 - Create new virtual environment with python version 2.7. -``` -virtualenv venv -``` - -Step 3 - Activate virtual environment -``` -source venv/bin/activate -``` -or -``` -source venv/Scripts/activate -``` - -Step 4 - Clone this repo +Step 1 - Clone this repo ``` git clone https://github.com/daxeel/blockshell.git ``` -Step 5 - Change directory to cloned one +Step 2 - Change directory to cloned one ``` cd blockshell ``` -Step 6 - Install blockshell +Step 3 - Create virtualenv +``` +python3 -m venv .venv +``` + +Step 4 - Enable virtualenv +``` +source .venv/bin/activate +``` + +Step 5 - Install blockshell ``` pip install --editable . ``` -Step 7 - Try "blockshell" command and test installation! +Step 6 - Try "blockshell" command and test installation! ``` blockshell ``` diff --git a/blockchain/chain.py b/blockchain/chain.py index 894696e..1e8cf3f 100644 --- a/blockchain/chain.py +++ b/blockchain/chain.py @@ -12,12 +12,16 @@ __maintainer__ = "Daxeel Soni" # ================================================== # ================= IMPORT MODULES ================= # ================================================== +import os import hashlib import datetime import json from colorama import Fore, Back, Style import time import sys +import base64 +from numpy import random +from PIL import Image # ================================================== # =================== BLOCK CLASS ================== @@ -26,26 +30,52 @@ class Block: """ Create a new block in chain with metadata """ - def __init__(self, data, index=0): - self.index = index + def __init__(self): + self.index = -1 self.previousHash = "" - self.data = data + self.uid_epita = -1 + self.email_epita = "" + self.firstname = "" + self.lastname = "" + self.image = "" self.timestamp = str(datetime.datetime.now()) self.nonce = 0 self.hash = self.calculateHash() + @classmethod + def fromSave(cls, data): + block = cls() + + for key, value in data.items(): + setattr(block, key, value) + + return block + + @classmethod + def fromValues(cls, uid_epita, email_epita, firstname, lastname, index = 0): + block = cls() + + block.index = index + block.uid_epita = uid_epita + block.email_epita = email_epita + block.firstname = firstname + block.lastname = lastname + block.createRandomImage() + + return block + def calculateHash(self): """ Method to calculate hash from metadata """ - hashData = str(self.index) + str(self.data) + self.timestamp + self.previousHash + str(self.nonce) - return hashlib.sha256(hashData).hexdigest() + hashData = str(self.index) + str(self.previousHash) + str(self.uid_epita) + str(self.email_epita) + str(self.firstname) + str(self.lastname) + str(self.image) + str(self.timestamp) + str(self.nonce) + return hashlib.sha256(hashData.encode('utf-8')).hexdigest() def mineBlock(self, difficulty): """ Method for Proof of Work """ - print Back.RED + "\n[Status] Mining block (" + str(self.index) + ") with PoW ..." + print(Back.RED + "\n[Status] Mining block (" + str(self.index) + ") with PoW ...") startTime = time.time() while self.hash[:difficulty] != "0"*difficulty: @@ -53,9 +83,22 @@ class Block: self.hash = self.calculateHash() endTime = time.time() - print Back.BLUE + "[ Info ] Time Elapsed : " + str(endTime - startTime) + " seconds." - print Back.BLUE + "[ Info ] Mined Hash : " + self.hash - print Style.RESET_ALL + print(Back.BLUE + "[ Info ] Time Elapsed : " + str(endTime - startTime) + " seconds.") + print(Back.BLUE + "[ Info ] Mined Hash : " + self.hash) + print(Style.RESET_ALL) + + def createRandomImage(self): + """ + Method to create random image in base64 + """ + imgarray = random.rand(30, 30, 3) * 255 + image = Image.fromarray(imgarray.astype('uint8')).convert('RGB') + image.save('random.png') + with open("random.png", "rb") as imageFile: + self.image = str(base64.b64encode(imageFile.read())) + if os.path.exists("random.png"): + os.remove("random.png") + # ================================================== # ================ BLOCKCHAIN CLASS ================ @@ -72,7 +115,7 @@ class Blockchain: """ Method create genesis block """ - return Block("Genesis Block") + return Block.fromValues(-1, "init@epita.fr", "Genesis", "Block") def addBlock(self, newBlock): """ @@ -88,9 +131,24 @@ class Blockchain: """ Method to write new mined block to blockchain """ - dataFile = file("chain.txt", "w") - chainData = [] - for eachBlock in self.chain: - chainData.append(eachBlock.__dict__) - dataFile.write(json.dumps(chainData, indent=4)) - dataFile.close() + with open("chain.txt", "w") as dataFile: + chainData = [] + for eachBlock in self.chain: + chainData.append(eachBlock.__dict__) + dataFile.write(json.dumps(chainData, indent=4)) + + def loadBlocks(self, filename): + """ + Method to load existing blockchain from file + """ + try: + with open(filename, "r") as dataFile: + chainData = json.loads(dataFile.read()) + self.chain = [] + for eachBlock in chainData: + self.chain.append(Block.fromSave(eachBlock)) + except Exception as e: + print(Back.RED + "[Error] No existing blockchain found.") + print(Back.RED + "[Error] Creating new blockchain.") + print(Style.RESET_ALL) + self.writeBlocks() diff --git a/bscli.py b/bscli.py index ac512a5..5aea8be 100644 --- a/bscli.py +++ b/bscli.py @@ -16,6 +16,7 @@ import click import urllib import json from blockchain.chain import Block, Blockchain +from colorama import Fore, Back, Style # ================================================== # ===== SUPPORTED COMMANDS LIST IN BLOCKSHELL ====== @@ -27,6 +28,31 @@ SUPPORTED_COMMANDS = [ 'help' ] +def printLogo(): + print(""" + ____ _ _ _____ _ _ _ + | _ \ | | | | / ____| | | | | | | + | |_) | | | ___ ___ | | __ | (___ | |__ ___ | | | | + | _ < | | / _ \ / __| | |/ / \___ \ | '_ \ / _ \ | | | | + | |_) | | | | (_) | | (__ | < ____) | | | | | | __/ | | | | + |____/ |_| \___/ \___| |_|\_\ |_____/ |_| |_| \___| |_| |_| + + > A command line utility for learning Blockchain concepts. + > Type 'help' to see supported commands. + > Project by Daxeel Soni - https://daxeel.github.io + + """) + +def startShell(): + """ + Method to start Blockshell CLI + """ + printLogo() + # Start blockshell shell + while True: + cmd = input("[BlockShell] $ ") + processInput(cmd) + # Init blockchain coin = Blockchain() @@ -45,37 +71,39 @@ def cli(): @click.option("--difficulty", default=3, help="Define difficulty level of blockchain.") def init(difficulty): """Initialize local blockchain""" - print """ - ____ _ _ _____ _ _ _ - | _ \ | | | | / ____| | | | | | | - | |_) | | | ___ ___ | | __ | (___ | |__ ___ | | | | - | _ < | | / _ \ / __| | |/ / \___ \ | '_ \ / _ \ | | | | - | |_) | | | | (_) | | (__ | < ____) | | | | | | __/ | | | | - |____/ |_| \___/ \___| |_|\_\ |_____/ |_| |_| \___| |_| |_| - > A command line utility for learning Blockchain concepts. - > Type 'help' to see supported commands. - > Project by Daxeel Soni - https://daxeel.github.io + coin.writeBlocks() + # Set difficulty of blockchain + coin.difficulty = difficulty - """ + # Start blockshell shell + startShell() + +@cli.command() +@click.argument("filename", type=click.Path(exists=True)) +@click.option("--difficulty", default=3, help="Define difficulty level of blockchain.") +def load(filename, difficulty): + """Load blockchain from file""" + + # Load blockchain from file + coin.loadBlocks(filename) # Set difficulty of blockchain coin.difficulty = difficulty # Start blockshell shell - while True: - cmd = raw_input("[BlockShell] $ ") - processInput(cmd) + startShell() # Process input from Blockshell shell def processInput(cmd): """ Method to process user input from Blockshell CLI. """ - userCmd = cmd.split(" ")[0] - if len(cmd) > 0: + splitted = cmd.split(" ") + userCmd = splitted[0] + if len(splitted) and len(userCmd) > 0: if userCmd in SUPPORTED_COMMANDS: - globals()[userCmd](cmd) + globals()[userCmd](splitted[1:]) else: # error msg = "Command not found. Try help command for documentation" @@ -85,47 +113,50 @@ def processInput(cmd): # ================================================== # =========== BLOCKSHELL COMMAND METHODS =========== # ================================================== -def dotx(cmd): +def dotx(args): """ Do Transaction - Method to perform new transaction on blockchain. """ - txData = cmd.split("dotx ")[-1] - if "{" in txData: - txData = json.loads(txData) - print "Doing transaction..." - coin.addBlock(Block(data=txData)) + print("Doing transaction...") + coin.addBlock(Block.fromValues(int(args[0]), args[1], args[2], args[3])) def allblocks(cmd): """ Method to list all mined blocks. """ - print "" + print("") for eachBlock in coin.chain: - print eachBlock.hash - print "" + print(eachBlock.hash) + print("") -def getblock(cmd): +def getblock(args): """ Method to fetch the details of block for given hash. """ - blockHash = cmd.split(" ")[-1] + blockHash = args[0] for eachBlock in coin.chain: if eachBlock.hash == blockHash: - print "" - print eachBlock.__dict__ - print "" + print("") + print(eachBlock.__dict__) + print("") def help(cmd): """ Method to display supported commands in Blockshell """ - print "Commands:" - print " dotx Create new transaction" - print " allblocks Fetch all mined blocks in blockchain" - print " getblock Fetch information about particular block" + print("Commands:") + print(" dotx Create new transaction") + print(" allblocks Fetch all mined blocks in blockchain") + print(" getblock Fetch information about particular block") def throwError(msg): """ Method to throw an error from Blockshell. """ - print "Error : " + msg + print(f"{ Fore.RED }{ msg }{ Fore.RESET }") + +def printSuccess(msg): + """ + Method to print success message from Blockshell. + """ + print(f"{ Fore.GREEN }{ msg }{ Fore.RESET }") \ No newline at end of file diff --git a/setup.py b/setup.py index 92374f0..ea694f9 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,9 @@ setup( install_requires=[ 'Click', 'colorama', - 'flask' + 'flask', + 'numpy', + 'Pillow' ], entry_points=''' [console_scripts] diff --git a/templates/blockdata.html b/templates/blockdata.html index 611e005..b2d3c1c 100644 --- a/templates/blockdata.html +++ b/templates/blockdata.html @@ -7,7 +7,7 @@ Blockshell | Block Data - +