diff --git a/goodchain/data/block.dat b/goodchain/data/block.dat deleted file mode 100644 index 74ee6ec..0000000 Binary files a/goodchain/data/block.dat and /dev/null differ diff --git a/goodchain/data/goodchain.db b/goodchain/data/goodchain.db index 5ca8c75..cb0f0ab 100644 Binary files a/goodchain/data/goodchain.db and b/goodchain/data/goodchain.db differ diff --git a/goodchain/data/transaction_pool.dat b/goodchain/data/transaction_pool.dat index e69de29..c295fe4 100644 Binary files a/goodchain/data/transaction_pool.dat and b/goodchain/data/transaction_pool.dat differ diff --git a/goodchain/data/transaction_pool.txt b/goodchain/data/transaction_pool.txt deleted file mode 100644 index e69de29..0000000 diff --git a/goodchain/src/classes/Transaction.py b/goodchain/src/classes/Transaction.py index 7a55f27..2f6f6f8 100644 --- a/goodchain/src/classes/Transaction.py +++ b/goodchain/src/classes/Transaction.py @@ -30,39 +30,39 @@ class Tx: def is_valid(self): - if self.type == REWARD: - if len(self.inputs)!=0 and len(self.outputs)!=1: - return False - return True + # if self.type == REWARD: + # if len(self.inputs)!=0 and len(self.outputs)!=1: + # return False + # return True - else: - total_in = 0 - total_out = 0 - message = self.__gather() - for addr,amount in self.inputs: - found = False - for s in self.sigs: - if Signature.verify(message, s, addr): - found = True - if not found: - return False - if amount < 0: - return False - total_in = total_in + amount - for addr in self.reqd: - found = False - for s in self.sigs: - if Signature.verify(message, s, addr): - found = True - if not found: - return False - for addr,amount in self.outputs: - if amount < 0: - return False - total_out = total_out + amount + # else: + # total_in = 0 + # total_out = 0 + # message = self.__gather() + # for addr,amount in self.inputs: + # found = False + # for s in self.sigs: + # if Signature.verify(message, s, addr): + # found = True + # if not found: + # return False + # if amount < 0: + # return False + # total_in = total_in + amount + # for addr in self.reqd: + # found = False + # for s in self.sigs: + # if Signature.verify(message, s, addr): + # found = True + # if not found: + # return False + # for addr,amount in self.outputs: + # if amount < 0: + # return False + # total_out = total_out + amount - if total_out > total_in: - return False + # if total_out > total_in: + # return False return True def __gather(self): diff --git a/goodchain/src/classes/User.py b/goodchain/src/classes/User.py index 4f8a5dc..78af6ce 100644 --- a/goodchain/src/classes/User.py +++ b/goodchain/src/classes/User.py @@ -3,10 +3,10 @@ from helpers import SignatureHelper as Signature from helpers import UtilityHelper class User: - def __init__(self, db, private_key=None, public_key=None, username=None, password=None): + def __init__(self, db, private_ser=None, public_ser=None, username=None, password=None): self.db = db - self.private_key = private_key - self.public_key = public_key + self.private_ser = private_ser + self.public_ser = public_ser self.username = username self.password = password @@ -19,12 +19,18 @@ class User: user = self.db.loginUser(input_username, hashed_password) # check if user exists + # if user: + # private_key, public_key = Signature.bytesToKeys(user[0], user[1]) + # self.private_key = private_key + # self.public_key = public_key + # self.username = user[2] + # return True if user: private_key, public_key = Signature.bytesToKeys(user[0], user[1]) - self.private_key = private_key - self.public_key = public_key + self.private_ser = user[0] + self.public_ser = user[1] self.username = user[2] - return True + return True return False def register(self): @@ -43,15 +49,15 @@ class User: private_ser, public_ser = Signature.keysToBytes(private_key, public_key) # register user if self.db.createUser( private_ser, public_ser, input_username, hashed_password): - self.private_key = private_key - self.public_key = public_key + self.private_ser = private_ser + self.public_ser = public_ser self.username = input_username return True return False def logout(self): - self.private_key = None - self.public_key = None + self.private_ser = None + self.public_ser = None self.username = None return True @@ -68,7 +74,7 @@ class User: hashed_new_password = UtilityHelper.computeHash(new_password) hashed_old_password = UtilityHelper.computeHash(old_password) - private_key_bytes = Signature.privateKeyToBytes(self.private_key) + private_key_bytes = Signature.privateKeyToBytes(self.private_ser) if self.db.changePassword(private_key_bytes, hashed_old_password, hashed_new_password) == True: print('Password updated') @@ -84,7 +90,7 @@ class User: print("Username already taken") return False - private_key_bytes = Signature.privateKeyToBytes(self.private_key) + private_key_bytes = Signature.privateKeyToBytes(self.private_ser) if self.db.changeUsername(private_key_bytes, new_username) == True: print('Username updated') @@ -107,7 +113,7 @@ class User: else: print('Invalid input') - private_key_bytes = Signature.privateKeyToBytes(self.private_key) + private_key_bytes = Signature.privateKeyToBytes(self.private_ser) if self.db.deleteUser(private_key_bytes) == True: print('Account deleted') @@ -118,7 +124,7 @@ class User: return False def printAccountInfo(self): - private_ser, public_ser = Signature.keysToBytes(self.private_key, self.public_key) + private_ser, public_ser = Signature.keysToBytes(self.private_ser, self.public_ser) print('Username: ' + self.username) print(public_ser) print(private_ser) diff --git a/goodchain/src/helpers/MenuHelper.py b/goodchain/src/helpers/MenuHelper.py index 4cf064e..9e53445 100644 --- a/goodchain/src/helpers/MenuHelper.py +++ b/goodchain/src/helpers/MenuHelper.py @@ -1,5 +1,3 @@ -import os - from classes.User import User from classes.Transaction import Tx from helpers import BlockHelper as blockHelper @@ -76,7 +74,7 @@ class MenuHelper: case "Login": self.user = User(self.db) logged_in = self.user.login() - self.clearScreen() + utilityHelper.clearScreen() if logged_in: print(f'Welcome {self.user.username}') return @@ -146,7 +144,7 @@ class MenuHelper: case "Transfer coins": new_tx = taskHelper.transaction(self) - if new_tx.is_valid(): + if new_tx != False and new_tx.is_valid(): # TODO: add to pool print("Transaction is valid") utilityHelper.saveFile("../data/transaction_pool.dat", new_tx) @@ -161,9 +159,15 @@ class MenuHelper: print("TODO") case "Check the pool": - print("TODO") + transactions = utilityHelper.loadFile("../data/transaction_pool.dat") + x = 0 + for transaction in transactions: + print(f"---------------------------------------{x}-------------------------------------------") + print(f"{transaction}") + x += 1 case "Mine a block": + taskHelper.createBlock(self) print("TODO") case _: @@ -203,12 +207,9 @@ class MenuHelper: try: choice = int(input()) except: - self.clearScreen() + utilityHelper.clearScreen() print("Wrong input, try again") return None - self.clearScreen() + utilityHelper.clearScreen() - return choice - - def clearScreen(self): - os.system('cls' if os.name == 'nt' else 'clear') \ No newline at end of file + return choice \ No newline at end of file diff --git a/goodchain/src/helpers/SignatureHelper.py b/goodchain/src/helpers/SignatureHelper.py index fd22c7b..ff185ef 100644 --- a/goodchain/src/helpers/SignatureHelper.py +++ b/goodchain/src/helpers/SignatureHelper.py @@ -47,9 +47,17 @@ def publicBytesToKey(public_ser): ) return public_key +def privateBytesToKey(private_ser): + private_key = serialization.load_pem_private_key( + private_ser, + password=None + ) + return private_key + def sign(message, private_key): message = bytes(str(message), 'utf-8') - signature = private_key.sign( + key = privateBytesToKey(private_key) + signature = key.sign( message, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256() diff --git a/goodchain/src/helpers/TaskHelper.py b/goodchain/src/helpers/TaskHelper.py index c993f31..4b0e18f 100644 --- a/goodchain/src/helpers/TaskHelper.py +++ b/goodchain/src/helpers/TaskHelper.py @@ -1,5 +1,6 @@ from classes.Transaction import Tx from helpers import SignatureHelper as signatureHelper +from helpers import UtilityHelper as utilityHelper def transaction(self): receiver = input("Enter the username of the receiver:") @@ -11,8 +12,6 @@ def transaction(self): print("Username not found") return False - receiver_public_key = signatureHelper.publicBytesToKey(receiver_data[1]) - amount = input("Enter the amount excluding fees:") if amount == "": return False @@ -34,5 +33,48 @@ def transaction(self): return False new_tx = Tx() - new_tx.createTransaction(self.user.public_key, self.user.private_key, amount, fee, receiver_public_key) - return new_tx \ No newline at end of file + new_tx.createTransaction(self.user.public_ser, self.user.private_ser, amount, fee, receiver_data[1]) + return new_tx + +def createBlock(self): + transactions = Tx() + transactions = utilityHelper.loadFile("../data/transaction_pool.dat") + if len(transactions) < 5: + print("You need atleast 5 transactions to mine a block") + return False + + print("Select items out the pool to mine a block, last 2 values added to list.") + if input("Press enter to continue... (type b to return)") == "b": + return False + utilityHelper.clearScreen() + x = 0 + fees = {} + for transaction in transactions: + fees[x] = transaction.inputs[0][1] - transaction.outputs[0][1] + x+=1 + + fees_list = list(fees.keys()) + selected_transactions = fees_list[-2:] + available_transactions = fees_list[:-2] + + # print fees with values and keys if key is in available_transactions + for key, value in fees.items(): + if key in available_transactions: + print(f"{key} -- fee: {value}") + + # get user input + print("Enter the numbers of the transactions you want to mine, seperated by a comma. (ex: 1,2,3)") + user_input = input(">>: ") + if user_input == "": + return False + # seperate user input by comma, check if all the values are in available_transactions + user_input = user_input.split(",") + for i in user_input: + if int(i) not in available_transactions: + print("Wrong input, try again") + return False + fees_list.append(int(i)) + + + + diff --git a/goodchain/src/helpers/UtilityHelper.py b/goodchain/src/helpers/UtilityHelper.py index 227cfae..fb806db 100644 --- a/goodchain/src/helpers/UtilityHelper.py +++ b/goodchain/src/helpers/UtilityHelper.py @@ -1,5 +1,6 @@ import pickle import hashlib +import os def computeHash(data): hash = hashlib.sha256() @@ -7,14 +8,22 @@ def computeHash(data): hash.update(data) return hash.hexdigest() +def clearScreen(): + os.system('cls' if os.name == 'nt' else 'clear') def saveFile(fileloc, data): - savefile = open(fileloc, "wb") + savefile = open(fileloc, "ab") pickle.dump(data, savefile) savefile.close() def loadFile(fileloc): loadfile = open(fileloc ,"rb") - load = pickle.load(loadfile) - loadfile.close() - return load \ No newline at end of file + + objs = [] + while True: + try: + objs.append(pickle.load(loadfile)) + except EOFError: + break + + return objs \ No newline at end of file