From fb8a7d5b69e719df2e4841d7d7a973457c53453f Mon Sep 17 00:00:00 2001 From: Spekulaas <“ryan@aterve.nl”> Date: Tue, 3 Oct 2023 13:57:03 +0200 Subject: [PATCH] finished HW and EX --- .../BlockChain.py | 24 ++++ .../Signature.py | 41 ++++++ .../Transaction.py | 66 +++++++++ .../605_EX5_A04_TxBlock_Validation/TxBlock.py | 57 ++++++++ .../TxBlock_t.py | 110 +++++++++++++++ .../605_EX5_A04_TxBlock_Validation/output.txt | 7 + .../BlockChain.py | 24 ++++ .../606_HW5_A05_TxBlock_LoadSave/Signature.py | 41 ++++++ .../Transaction.py | 104 ++++++++++++++ .../606_HW5_A05_TxBlock_LoadSave/TxBlock.py | 57 ++++++++ .../606_HW5_A05_TxBlock_LoadSave/TxBlock_t.py | 129 ++++++++++++++++++ .../606_HW5_A05_TxBlock_LoadSave/output.txt | 29 ++++ 12 files changed, 689 insertions(+) create mode 100644 period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/BlockChain.py create mode 100644 period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/Signature.py create mode 100644 period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/Transaction.py create mode 100644 period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/TxBlock.py create mode 100644 period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/TxBlock_t.py create mode 100644 period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/output.txt create mode 100644 period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/BlockChain.py create mode 100644 period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/Signature.py create mode 100644 period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/Transaction.py create mode 100644 period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/TxBlock.py create mode 100644 period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/TxBlock_t.py create mode 100644 period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/output.txt diff --git a/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/BlockChain.py b/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/BlockChain.py new file mode 100644 index 0000000..d3879c9 --- /dev/null +++ b/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/BlockChain.py @@ -0,0 +1,24 @@ +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import hashes + +class CBlock: + + data = None + previousHash = None + previousBlock = None + def __init__(self, data, previousBlock): + self.data = data + self.previousBlock = previousBlock + if previousBlock != None: + self.previousHash = previousBlock.computeHash() + + def computeHash(self): + digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) + digest.update(bytes(str(self.data),'utf8')) + digest.update(bytes(str(self.previousHash),'utf8')) + return digest.finalize() + + def is_valid(self): + if self.previousBlock == None: + return True + return self.previousBlock.computeHash() == self.previousHash \ No newline at end of file diff --git a/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/Signature.py b/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/Signature.py new file mode 100644 index 0000000..740ee1a --- /dev/null +++ b/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/Signature.py @@ -0,0 +1,41 @@ +from cryptography.exceptions import * +from cryptography.hazmat.primitives.asymmetric import rsa +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import padding +from cryptography.hazmat.primitives import serialization + +def generate_keys(): + private_key = rsa.generate_private_key(public_exponent=65537,key_size=2048) + public_key = private_key.public_key() + + pbc_ser = public_key.public_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PublicFormat.SubjectPublicKeyInfo) + return private_key, pbc_ser + +def sign(message, private_key): + message = bytes(str(message), 'utf-8') + signature = private_key.sign( + message, + padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), + hashes.SHA256() + ) + return signature + +def verify(message, signature, pbc_ser): + message = bytes(str(message), 'utf-8') + public_key = serialization.load_pem_public_key(pbc_ser) + try: + public_key.verify( + signature, + message, + padding.PSS(mgf=padding.MGF1(hashes.SHA256()), + salt_length=padding.PSS.MAX_LENGTH), + hashes.SHA256() + ) + return True + except InvalidSignature: + return False + except: + print("Error executing 'public_key.verify'") + return False \ No newline at end of file diff --git a/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/Transaction.py b/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/Transaction.py new file mode 100644 index 0000000..fbc2ed5 --- /dev/null +++ b/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/Transaction.py @@ -0,0 +1,66 @@ +from Signature import * + +class Tx: + inputs = None + outputs =None + sigs = None + reqd = None + def __init__(self): + self.inputs = [] + self.outputs = [] + self.sigs = [] + self.reqd = [] + + def add_input(self, from_addr, amount): + self.inputs.append((from_addr, amount)) + + def add_output(self, to_addr, amount): + self.outputs.append((to_addr, amount)) + + def add_reqd(self, addr): + self.reqd.append(addr) + + def sign(self, private): + message = self.__gather() + newsig = sign(message, private) + self.sigs.append(newsig) + + def is_valid(self): + total_in = 0 + total_out = 0 + message = self.__gather() + for addr,amount in self.inputs: + found = False + for s in self.sigs: + if verify(message, s, addr): + found = True + if not found: + # print ("No good sig found for " + str(message)) + 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 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: + # print("Outputs exceed inputs") + return False + + return True + + def __gather(self): + data=[] + data.append(self.inputs) + data.append(self.outputs) + data.append(self.reqd) + return data diff --git a/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/TxBlock.py b/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/TxBlock.py new file mode 100644 index 0000000..00625f0 --- /dev/null +++ b/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/TxBlock.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +"""Transactions -> Ledger (Block Validation): Exercise + +The goal of this exercise is to learn how a blockchain for the transactions is implemented. +In this scenario the implementation of the block is extended with a validation function for the block. +Each block contains his own hash value, transaction data and the hash value of previous block. +Check the provided code in both files, Signature.py, Transaction.py and Blockchain.py. +In Blockchain.py the is_valid() method is provided to check the validity of the block, +rebuild the Block module to satisfy our testing scenario. +The testing scenario here covers tempering the data of one block. +This tempering should be detectable. + +Your task is to: + * locate the TODOs in this file + * complete the missing part from the code + * run the test of this exercise located in same folder. + +To test run 'TxBlock_t.py' in your command line + +Notes: + * do not change class structure or method signature to not break unit tests + * Check previous tutorials for more information on this topic +""" +from BlockChain import CBlock +from Signature import generate_keys, sign, verify +from Transaction import Tx + +class TxBlock (CBlock): + previousHash = None + previousBlock = None + data = None + # TODO 1: Init + # TODO 1: Initialize the block + # Each block contains a list for the data and a hash value to previous block + def __init__(self, previousBlock): + # TODO 1: Initialize the block + # Each block contains a list for the data and a hash value to previous block + self.previousBlock = previousBlock + self.data = [] + if previousBlock != None: + self.previousHash = previousBlock.computeHash() + + def addTx(self, Tx_in): + self.data.append(Tx_in) + + + # TODO 3: Check the validity of each transaction in the data list + # and check the validity of other blocks in the chain to make the cchain tamper-proof + # Expected return value is true or false + def is_valid(self): + if self.previousBlock != None: + if self.previousBlock.computeHash() != self.previousHash: + return False + for t in self.data: + if Tx.is_valid(t) == False: + return False + return True \ No newline at end of file diff --git a/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/TxBlock_t.py b/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/TxBlock_t.py new file mode 100644 index 0000000..2fbdd75 --- /dev/null +++ b/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/TxBlock_t.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +""" +This test case will verify if the provided solution by a student for TxBlock.py is correct. +In this test scenario 6 blocks will be created (1 genesis and 5 child blocks). +A total of 8 transactions will be created. +Tempering the data on block b1 by adding a valid transaction to it should be detected. +""" +from BlockChain import CBlock +from Signature import generate_keys, sign, verify +from Transaction import Tx +import pickle +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.backends import default_backend + +from TxBlock import * + +if __name__ == "__main__": + alex_prv, alex_pbc = generate_keys() + mike_prv, mike_pbc = generate_keys() + rose_prv, rose_pbc = generate_keys() + mara_prv, mara_pbc = generate_keys() + + # Valid Blocks + #################### + # Create 2 valid transactions Tx1 and Tx2 + Tx1 = Tx() + Tx1.add_input(alex_pbc, 1) + Tx1.add_output(rose_pbc, 1) + Tx1.sign(alex_prv) + + Tx2 = Tx() + Tx2.add_input(mike_pbc,1.1) + Tx2.add_output(rose_pbc, 1) + Tx2.sign(mike_prv) + + # Add Tx1 and Tx2 to the first block (genesis block) + root = TxBlock(None) + root.addTx(Tx1) + root.addTx(Tx2) + + # Create 2 more valid transactions Tx3 and Tx4 + Tx3 = Tx() + Tx3.add_input(rose_pbc,1.1) + Tx3.add_output(alex_pbc, 1) + Tx3.sign(rose_prv) + + Tx4 = Tx() + Tx4.add_input(mike_pbc,1) + Tx4.add_output(mara_pbc, 1) + Tx4.add_reqd(rose_pbc) + Tx4.sign(mike_prv) + Tx4.sign(rose_prv) + + # Add Tx3 and Tx4 to the second block (the child of the genesis block) + B1 = TxBlock(root) + B1.addTx(Tx3) + B1.addTx(Tx4) + + # Creat new valid transaction Tx5 + Tx5 = Tx() + Tx5.add_input(rose_pbc, 2.3) + Tx5.add_output(mike_pbc, 2.3) + Tx5.sign(rose_prv) + # Create a new block (a child of the block B1), and the transaction Tx5 to the block + B2 = TxBlock(B1) + B2.addTx(Tx5) + + for b in [root, B1, B2]: + if b.is_valid(): + print ("Success! Valid block is verified.") + else: + print ("Error! Valid block is not verified.") + + + # Invalid Blocks + ###################### + # Creat an invalid transaction Tx6 + Tx6 = Tx() + Tx6.add_input(mara_pbc, 2.0) + Tx6.add_output(rose_pbc, 15.3) + Tx6.sign(mara_prv) + B3 = TxBlock(B2) + B3.addTx(Tx6) + + # Creat an invalid transaction Tx7 + Tx7 = Tx() + Tx7.add_input(rose_pbc, 2.3) + Tx7.add_output(mike_pbc, 2.3) + Tx7.sign(mike_prv) + B4 = TxBlock(B3) + B4.addTx(Tx7) + + # Creat an invalid transaction Tx8 + Tx8 = Tx() + Tx8.add_input(mike_pbc, 0.9) + Tx8.add_output(mara_pbc, 0.8) + Tx8.add_reqd(rose_pbc) + Tx8.sign(mike_prv) + B5 = TxBlock(B4) + B5.addTx(Tx8) + + # Tamper the block before B1 by adding a valid transaction to it + # This will make the block B1 (the block after the tampered block) invalid + B2.previousBlock.addTx(Tx4) + + for b in [B2, B3, B4, B5]: + if b.is_valid(): + print ("Error! Invalid block is verified.") + else: + print ("Success! Invalid blocks is detected.") diff --git a/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/output.txt b/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/output.txt new file mode 100644 index 0000000..d5a6b1e --- /dev/null +++ b/period_1/06-transaction_block/605_EX5_A04_TxBlock_Validation/output.txt @@ -0,0 +1,7 @@ +Success! Valid block is verified. +Success! Valid block is verified. +Success! Valid block is verified. +Success! Invalid blocks is detected. +Success! Invalid blocks is detected. +Success! Invalid blocks is detected. +Success! Invalid blocks is detected. \ No newline at end of file diff --git a/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/BlockChain.py b/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/BlockChain.py new file mode 100644 index 0000000..d3879c9 --- /dev/null +++ b/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/BlockChain.py @@ -0,0 +1,24 @@ +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import hashes + +class CBlock: + + data = None + previousHash = None + previousBlock = None + def __init__(self, data, previousBlock): + self.data = data + self.previousBlock = previousBlock + if previousBlock != None: + self.previousHash = previousBlock.computeHash() + + def computeHash(self): + digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) + digest.update(bytes(str(self.data),'utf8')) + digest.update(bytes(str(self.previousHash),'utf8')) + return digest.finalize() + + def is_valid(self): + if self.previousBlock == None: + return True + return self.previousBlock.computeHash() == self.previousHash \ No newline at end of file diff --git a/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/Signature.py b/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/Signature.py new file mode 100644 index 0000000..740ee1a --- /dev/null +++ b/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/Signature.py @@ -0,0 +1,41 @@ +from cryptography.exceptions import * +from cryptography.hazmat.primitives.asymmetric import rsa +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import padding +from cryptography.hazmat.primitives import serialization + +def generate_keys(): + private_key = rsa.generate_private_key(public_exponent=65537,key_size=2048) + public_key = private_key.public_key() + + pbc_ser = public_key.public_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PublicFormat.SubjectPublicKeyInfo) + return private_key, pbc_ser + +def sign(message, private_key): + message = bytes(str(message), 'utf-8') + signature = private_key.sign( + message, + padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), + hashes.SHA256() + ) + return signature + +def verify(message, signature, pbc_ser): + message = bytes(str(message), 'utf-8') + public_key = serialization.load_pem_public_key(pbc_ser) + try: + public_key.verify( + signature, + message, + padding.PSS(mgf=padding.MGF1(hashes.SHA256()), + salt_length=padding.PSS.MAX_LENGTH), + hashes.SHA256() + ) + return True + except InvalidSignature: + return False + except: + print("Error executing 'public_key.verify'") + return False \ No newline at end of file diff --git a/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/Transaction.py b/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/Transaction.py new file mode 100644 index 0000000..fcc601f --- /dev/null +++ b/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/Transaction.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +""" +The goal of this exercise is to complete the transaction module. +In this exercise you need to add a __repr__() function that will be used +to show the details of transaction. + +Your task is to: + * locate the TODOs in this file + * complete the missing part from the code + * run the test of this exercise located in same folder. + +To test run 'TxBlock_t.py' in your command line + +Notes: + * do not change class structure or method signature to not break unit tests + * Check previous tutorials for more information on this topic +""" + +from Signature import * + +class Tx: + inputs = None + outputs =None + sigs = None + reqd = None + def __init__(self): + self.inputs = [] + self.outputs = [] + self.sigs = [] + self.reqd = [] + + def add_input(self, from_addr, amount): + self.inputs.append((from_addr, amount)) + + def add_output(self, to_addr, amount): + self.outputs.append((to_addr, amount)) + + def add_reqd(self, addr): + self.reqd.append(addr) + + def sign(self, private): + message = self.__gather() + newsig = sign(message, private) + self.sigs.append(newsig) + + def is_valid(self): + total_in = 0 + total_out = 0 + message = self.__gather() + for addr,amount in self.inputs: + found = False + for s in self.sigs: + if verify(message, s, addr): + found = True + if not found: + # print ("No good sig found for " + str(message)) + 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 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: + # print("Outputs exceed inputs") + return False + + return True + + def __gather(self): + data=[] + data.append(self.inputs) + data.append(self.outputs) + data.append(self.reqd) + return data + + # TODO : + # Complete __repr__() method. + # for the desired format, check the 'output.txt' file. + + def __repr__(self): + repr = "" + repr += "INPUTS:\n" + for addr, amount in self.inputs: + repr += str(amount) + " from " + str(addr) + "\n" + repr += "OUTPUTS:\n" + for addr, amount in self.outputs: + repr += str(amount) + " to " + str(addr) + "\n" + repr += "REQD:\n" + for addr in self.reqd: + repr += str(addr) + "\n" + repr += "SIGS:\n" + for sig in self.sigs: + repr += str(sig) + "\n" + return repr \ No newline at end of file diff --git a/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/TxBlock.py b/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/TxBlock.py new file mode 100644 index 0000000..67dba0c --- /dev/null +++ b/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/TxBlock.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +""" +The goal of this exercise is to complete the TXBlock class. We want be able to correctly store and +load a block on disk. You have already completed every required modules seperately in the previous tutorials. +In this exercise, you have to integrate all the previously created modules, and ensure +all components are properly working together. + +In addition, we would also like to see details of a transaction. For this part, check the assignment +for Transaction.py file + +Your task is to: + * locate the TODOs in this file + * complete the missing part from the code + * run the test of this exercise located in same folder. + +To test run 'TxBlock_t.py' in your command line + +Notes: + * do not change class structure or method signature to not break unit tests + * Check previous tutorials for more information on this topic +""" + +from BlockChain import CBlock +from Signature import generate_keys, sign, verify + +from Transaction import Tx + +class TxBlock (CBlock): + previousHash = None + previousBlock = None + data = None + # TODO 1: Init + # TODO 1: Initialize the block + # Each block contains a list for the data and a hash value to previous block + def __init__(self, previousBlock): + # TODO 1: Initialize the block + # Each block contains a list for the data and a hash value to previous block + self.previousBlock = previousBlock + self.data = [] + if previousBlock != None: + self.previousHash = previousBlock.computeHash() + + def addTx(self, Tx_in): + self.data.append(Tx_in) + + + # TODO 3: Check the validity of each transaction in the data list + # and check the validity of other blocks in the chain to make the cchain tamper-proof + # Expected return value is true or false + def is_valid(self): + if self.previousBlock != None: + if self.previousBlock.computeHash() != self.previousHash: + return False + for t in self.data: + if Tx.is_valid(t) == False: + return False + return True \ No newline at end of file diff --git a/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/TxBlock_t.py b/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/TxBlock_t.py new file mode 100644 index 0000000..be8e450 --- /dev/null +++ b/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/TxBlock_t.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python3 +""" +This test case will verify if the provided solution by a student for TxBlock.py is correct. +In this test scenario 6 blocks will be created (1 genesis and 5 child blocks). +A total of 8 transactions will be created. +Tempering the data on block b1 by adding a valid transaction to it should be detected. +In addition, Transaction should be printed formmated and human-readable. You shoud add a method +to transaction file to represent a transaction in the desired format. + +For the correct format check the 'output.txt' file. +""" + +from BlockChain import CBlock +from Signature import generate_keys, sign, verify +import pickle +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.backends import default_backend + +# from Transaction import Tx + +from TxBlock import * + + +if __name__ == "__main__": + alex_prv, alex_pbc = generate_keys() + mike_prv, mike_pbc = generate_keys() + rose_prv, rose_pbc = generate_keys() + mara_prv, mara_pbc = generate_keys() + + # Valid Blocks + #################### + # Create 2 valid transactions Tx1 and Tx2 + Tx1 = Tx() + Tx1.add_input(alex_pbc, 1) + Tx1.add_output(rose_pbc, 1) + Tx1.sign(alex_prv) + + Tx2 = Tx() + Tx2.add_input(mike_pbc,1.1) + Tx2.add_output(rose_pbc, 1) + Tx2.sign(mike_prv) + + # Add Tx1 and Tx2 to the first block (genesis block) + root = TxBlock(None) + root.addTx(Tx1) + root.addTx(Tx2) + + # Create 2 more valid transactions Tx3 and Tx4 + Tx3 = Tx() + Tx3.add_input(rose_pbc,1.1) + Tx3.add_output(alex_pbc, 1) + Tx3.sign(rose_prv) + + Tx4 = Tx() + Tx4.add_input(mike_pbc,1) + Tx4.add_output(mara_pbc, 1) + Tx4.add_reqd(rose_pbc) + Tx4.sign(mike_prv) + Tx4.sign(rose_prv) + + # Add Tx3 and Tx4 to the second block (the child of the genesis block) + B1 = TxBlock(root) + B1.addTx(Tx3) + B1.addTx(Tx4) + + # Save the block B1 on the disk + savefile = open("block.dat", "wb") + pickle.dump(B1, savefile) + savefile.close() + + # Creat new valid transaction Tx5 + Tx5 = Tx() + Tx5.add_input(rose_pbc, 2.3) + Tx5.add_output(mike_pbc, 2.3) + Tx5.sign(rose_prv) + # Create a new block (a child of the block B1), and the transaction Tx5 to the block + B2 = TxBlock(B1) + B2.addTx(Tx5) + + # Load the block B1 from the disk + loadfile = open("block.dat" ,"rb") + load_B1 = pickle.load(loadfile) + loadfile.close() + + for b in [root, B1, B2, load_B1]: + if b.is_valid(): + print ("Success! Valid block is verified.") + else: + print ("Error! Valid block is not verified.") + + # Invalid Blocks + ###################### + # Creat an invalid transaction Tx6 + Tx6 = Tx() + Tx6.add_input(mara_pbc, 2.0) + Tx6.add_output(rose_pbc, 15.3) + Tx6.sign(mara_prv) + B3 = TxBlock(B2) + B3.addTx(Tx6) + + # Creat an invalid transaction Tx7 + Tx7 = Tx() + Tx7.add_input(rose_pbc, 2.3) + Tx7.add_output(mike_pbc, 2.3) + Tx7.sign(mike_prv) + B4 = TxBlock(B3) + B4.addTx(Tx7) + + # Creat an invalid transaction Tx8 + Tx8 = Tx() + Tx8.add_input(mike_pbc, 0.9) + Tx8.add_output(mara_pbc, 0.8) + Tx8.add_reqd(rose_pbc) + Tx8.sign(mike_prv) + B5 = TxBlock(B4) + B5.addTx(Tx8) + + # Tamper the block before B1 by adding a valid transaction to it + # This will make the block B1 (the block after the tampered block) invlaid + B1.previousBlock.addTx(Tx4) + + for b in [B1, B3, B4, B5]: + if b.is_valid(): + print("Error! Invalid block is verified.") + else: + print("Success! Invalid blocks is detected.") + + print('Tx4\n', Tx4) + print('Tx5\n', Tx5) diff --git a/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/output.txt b/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/output.txt new file mode 100644 index 0000000..a4884f1 --- /dev/null +++ b/period_1/06-transaction_block/606_HW5_A05_TxBlock_LoadSave/output.txt @@ -0,0 +1,29 @@ +Success! Valid block is verified. +Success! Valid block is verified. +Success! Valid block is verified. +Success! Valid block is verified. +Success! Invalid blocks is detected. +Success! Invalid blocks is detected. +Success! Invalid blocks is detected. +Success! Invalid blocks is detected. +Tx4 + INPUTS: +1 from b'-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA17Qc21PHEjqP7CLg1v1l\nYaSRy4gu5MXWcjbflmInox6IbMD/7P37kuvWRw/ruVCidoy8JmwasDGDv6Z9vRfN\nYSIssLziMcbhWUdEMLlI5Qu1Vf1eUzAxUEhQ4SBUi21BYX5uKoZm+rzd/idTi00W\nLI9c3/mKx5+i8pUBNFOXAijlqr5akxmqox2CN5cynKt2YK3ADOJPY8+hFT7s99Vd\np/3EWf4hyFWXWSnMTCs+n42pYf5ZA3/kRFzMI8x070zfNNqjgseXQuyc0br4U1Jt\nnAJaE4OzKez4rEF1tyZ9YBxX+D1ZshZpozdLxIyO4JUa4913zHFlz6CcIMH3a1hI\nVQIDAQAB\n-----END PUBLIC KEY-----\n' +OUTPUTS: +1 to b'-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxGLdr2pV+nnQBH7oDP/9\nnBx5rc8zQJAsXSyL/HQAb+x3bhxRditCqsrShEIZpix7OZmMy8R8C8R+M6OAmeMy\nKGXxGD80WINSJgzSy2SZwAbKVNCzFEPVg/5tNgAzZBkeAZ8ddgrFzago2eeJwjyr\nthcdfnlJzw+LIXkIbG0AmU9XGRE3HpxlY0k5BJZ1LoWVezq+ip/nAO2i0Ht/rGxN\njmJvvDjGkawaHbeNIGdhEqIJp2/sKCJg0OyU7r1QbAwlbF61fEyzCVEH+PrqHmlI\nnCrP/qkxr/7bcWADbM2rX1sB8ueSAu70EIPeFtdGCDr+vzc7qphelFnzK8ekwiFD\nYQIDAQAB\n-----END PUBLIC KEY-----\n' +EXTRA REQUIRED SIGNATURES: +b'-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1HKkpz+xIVe4B7oT7I+V\nx6FYBlT0H9BRUdOnYHKaUVNdR8WnlJBFzdl5oDOOfpzvtJdQtM6RD1lKPdKhvelE\nlemnTqBKT4aeZtSrbmTHhbJgS7cgyVTi3w2Ct7ye/ypyMPoFZlLCI7L7UGyzLKlQ\npnOJTouYzwgN7m7T3IaAYYwrRwCMczq+IKARPPfA8wMcdb1/tM7voqGmiSb5Z0fz\nHsd/MWcKuL3ZGBkx3lT2QEXuTT3OO6V8LdVWMU0kEaM0lS30KzVIT7CNmbyBe7kc\nsBnZ0Q79GlQaLnsDphPUrbndsr3jp4Wmx0H9JzLNNnJrvmOnWKTgHi5BTylVxMe7\nWQIDAQAB\n-----END PUBLIC KEY-----\n' +SIGNATURES: +b'G\xcb\xc0\xf4ULc|~4#{\xc7\xf2\x8f:\xa7\xef\xb5H@&\xaaQ,K/\x9b\x92\xaa\xbd\xa7\xe66\xf5q\xf1\x90XD\xf5>AO\x19\x11\x9f\x89\x0b\xcc\xb9]Zu\xf0x\xe8k&\x8b\xb6k\xeb9\x81\x9a\x0b\xf7\\yl\xdcc7\xfbP\xd5W\xb5\xa2\x1bY\x1a\\d\xfe\xe8.\xf9\xecG%\xc9\xcb\x1ab\xee