From 954bbbffb370b4e4306e954336681ae6cf005113 Mon Sep 17 00:00:00 2001 From: Ryan Bakkes Date: Mon, 2 Oct 2023 15:19:33 +0200 Subject: [PATCH] changed changing previous has to recursive --- .../405_HW3_Tamper-Proof_Chain/BlockChain.py | 189 +++++++++--------- 1 file changed, 89 insertions(+), 100 deletions(-) diff --git a/period_1/04-blockchain_class/405_HW3_Tamper-Proof_Chain/BlockChain.py b/period_1/04-blockchain_class/405_HW3_Tamper-Proof_Chain/BlockChain.py index fd1287c..ba487fe 100644 --- a/period_1/04-blockchain_class/405_HW3_Tamper-Proof_Chain/BlockChain.py +++ b/period_1/04-blockchain_class/405_HW3_Tamper-Proof_Chain/BlockChain.py @@ -1,100 +1,89 @@ -#!/usr/bin/env python3 -"""Block Integrity -> Tamper Proof Chain: Homework - -The goal of this homework is to extend the behavior of a block to created a chain and securely link -them together using cryptography. In general, each block is used to hold a batch of transactions. In addition a cryptographic -hash of the previous block in the chain and some other needed values for computation. -In this homework each block will hold: - * a string message (data) - * its own block hash value - * hash value of the previous block - * nonce value which will be incremented when a block is mined - -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 'Blockchain_t.py' in your command line - -Notes: - * do not change class structure or method signature to not break unit tests - * visit this url for more information on this topic: - https://cryptography.io/en/latest/hazmat/primitives/cryptographic-hashes/ -""" -from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives import hashes - -class CBlock: - # TODO 1: Initialize the values of a block - # Make sure you distinguish between the genesis block and other blocks - def __init__(self, data, previousBlock): - if previousBlock == None : - self.previousHash = None - self.previousBlock = None - self.data = data - else: - self.previousBlock = previousBlock - self.previousHash = self.previousBlock.computeHash() - self.data = data - self.blockHash = None - self.nonce = 0 - - # TODO 2: Compute the cryptographic hash of the current block. - # Be sure which values must be considered to compute the hash properly. - # return the digest value - def computeHash(self): - digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) - - if self.previousHash != None: - digest.update(self.previousHash) - - try: - digest.update(str(self.data).encode()) - except: - digest.update(self.data) - - digest.update(str(self.nonce).encode()) - return digest.finalize() - - # TODO 3: Mine the current value of a block - # Calculates a digest based on required values from the block, such as: - # data, previousHash, nonce - # Make sure to compute the hash value of the current block and store it properly - def mine(self, leading_zeros): - self.nonce = 0 - - if self.previousBlock: - self.previousHash = self.previousBlock.blockHash - else: - self.previousHash = None - - while True: - digest = self.computeHash() - - if digest[:leading_zeros] == b'\x00' * leading_zeros: - self.blockHash = digest - print(self.nonce) # Output.txt file has printed nonce values - break - - self.nonce += 1 - - # TODO 4: Check if the current block contains valid hash digest values - # Make sure to distinguish between the genesis block and other blocks - # Make sure to compare both hash digest values: - # The computed digest of the current block - # The stored digest of the previous block - # return the result of all comparisons as a boolean value - # def is_valid_hash(self): - # if(self.previousBlock == None): - # return True - - # if(self.computeHash() != self.blockHash or self.previousBlock.blockHash != self.previousBlock.computeHash()): - # return False - # return self.previousBlock.is_valid_hash() - - def is_valid_hash(self): - if self.previousBlock: - self.previousHash = self.previousBlock.computeHash() - - return self.computeHash() == self.blockHash \ No newline at end of file +#!/usr/bin/env python3 +"""Block Integrity -> Tamper Proof Chain: Homework + +The goal of this homework is to extend the behavior of a block to created a chain and securely link +them together using cryptography. In general, each block is used to hold a batch of transactions. In addition a cryptographic +hash of the previous block in the chain and some other needed values for computation. +In this homework each block will hold: + * a string message (data) + * its own block hash value + * hash value of the previous block + * nonce value which will be incremented when a block is mined + +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 'Blockchain_t.py' in your command line + +Notes: + * do not change class structure or method signature to not break unit tests + * visit this url for more information on this topic: + https://cryptography.io/en/latest/hazmat/primitives/cryptographic-hashes/ +""" +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import hashes + +class CBlock: + # TODO 1: Initialize the values of a block + # Make sure you distinguish between the genesis block and other blocks + def __init__(self, data, previousBlock): + if previousBlock == None : + self.previousHash = None + self.previousBlock = None + self.data = data + else: + self.previousBlock = previousBlock + self.previousHash = self.previousBlock.computeHash() + self.data = data + self.blockHash = None + self.nonce = 0 + + # TODO 2: Compute the cryptographic hash of the current block. + # Be sure which values must be considered to compute the hash properly. + # return the digest value + def computeHash(self): + digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) + + if self.previousHash != None: + digest.update(self.previousHash) + + try: + digest.update(str(self.data).encode()) + except: + digest.update(self.data) + + digest.update(str(self.nonce).encode()) + return digest.finalize() + + # TODO 3: Mine the current value of a block + # Calculates a digest based on required values from the block, such as: + # data, previousHash, nonce + # Make sure to compute the hash value of the current block and store it properly + def mine(self, leading_zeros): + self.nonce = 0 + + while True: + digest = self.computeHash() + + if digest[:leading_zeros] == b'\x00' * leading_zeros: + self.blockHash = digest + print(self.nonce) # Output.txt file has printed nonce values + break + + self.nonce += 1 + + # TODO 4: Check if the current block contains valid hash digest values + # Make sure to distinguish between the genesis block and other blocks + # Make sure to compare both hash digest values: + # The computed digest of the current block + # The stored digest of the previous block + # return the result of all comparisons as a boolean value + def is_valid_hash(self): + if(self.previousBlock == None): + return True + + if(self.computeHash() != self.blockHash or self.previousBlock.blockHash != self.previousBlock.computeHash()): + return False + return self.previousBlock.is_valid_hash() \ No newline at end of file