changed changing previous has to recursive
This commit is contained in:
parent
c43218e0e3
commit
954bbbffb3
@ -1,100 +1,89 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""Block Integrity -> Tamper Proof Chain: Homework
|
"""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
|
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
|
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.
|
hash of the previous block in the chain and some other needed values for computation.
|
||||||
In this homework each block will hold:
|
In this homework each block will hold:
|
||||||
* a string message (data)
|
* a string message (data)
|
||||||
* its own block hash value
|
* its own block hash value
|
||||||
* hash value of the previous block
|
* hash value of the previous block
|
||||||
* nonce value which will be incremented when a block is mined
|
* nonce value which will be incremented when a block is mined
|
||||||
|
|
||||||
Your task is to:
|
Your task is to:
|
||||||
* locate the TODOs in this file
|
* locate the TODOs in this file
|
||||||
* complete the missing part from the code
|
* complete the missing part from the code
|
||||||
* run the test of this exercise located in same folder.
|
* run the test of this exercise located in same folder.
|
||||||
|
|
||||||
To test run 'Blockchain_t.py' in your command line
|
To test run 'Blockchain_t.py' in your command line
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
* do not change class structure or method signature to not break unit tests
|
* do not change class structure or method signature to not break unit tests
|
||||||
* visit this url for more information on this topic:
|
* visit this url for more information on this topic:
|
||||||
https://cryptography.io/en/latest/hazmat/primitives/cryptographic-hashes/
|
https://cryptography.io/en/latest/hazmat/primitives/cryptographic-hashes/
|
||||||
"""
|
"""
|
||||||
from cryptography.hazmat.backends import default_backend
|
from cryptography.hazmat.backends import default_backend
|
||||||
from cryptography.hazmat.primitives import hashes
|
from cryptography.hazmat.primitives import hashes
|
||||||
|
|
||||||
class CBlock:
|
class CBlock:
|
||||||
# TODO 1: Initialize the values of a block
|
# TODO 1: Initialize the values of a block
|
||||||
# Make sure you distinguish between the genesis block and other blocks
|
# Make sure you distinguish between the genesis block and other blocks
|
||||||
def __init__(self, data, previousBlock):
|
def __init__(self, data, previousBlock):
|
||||||
if previousBlock == None :
|
if previousBlock == None :
|
||||||
self.previousHash = None
|
self.previousHash = None
|
||||||
self.previousBlock = None
|
self.previousBlock = None
|
||||||
self.data = data
|
self.data = data
|
||||||
else:
|
else:
|
||||||
self.previousBlock = previousBlock
|
self.previousBlock = previousBlock
|
||||||
self.previousHash = self.previousBlock.computeHash()
|
self.previousHash = self.previousBlock.computeHash()
|
||||||
self.data = data
|
self.data = data
|
||||||
self.blockHash = None
|
self.blockHash = None
|
||||||
self.nonce = 0
|
self.nonce = 0
|
||||||
|
|
||||||
# TODO 2: Compute the cryptographic hash of the current block.
|
# TODO 2: Compute the cryptographic hash of the current block.
|
||||||
# Be sure which values must be considered to compute the hash properly.
|
# Be sure which values must be considered to compute the hash properly.
|
||||||
# return the digest value
|
# return the digest value
|
||||||
def computeHash(self):
|
def computeHash(self):
|
||||||
digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
|
digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
|
||||||
|
|
||||||
if self.previousHash != None:
|
if self.previousHash != None:
|
||||||
digest.update(self.previousHash)
|
digest.update(self.previousHash)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
digest.update(str(self.data).encode())
|
digest.update(str(self.data).encode())
|
||||||
except:
|
except:
|
||||||
digest.update(self.data)
|
digest.update(self.data)
|
||||||
|
|
||||||
digest.update(str(self.nonce).encode())
|
digest.update(str(self.nonce).encode())
|
||||||
return digest.finalize()
|
return digest.finalize()
|
||||||
|
|
||||||
# TODO 3: Mine the current value of a block
|
# TODO 3: Mine the current value of a block
|
||||||
# Calculates a digest based on required values from the block, such as:
|
# Calculates a digest based on required values from the block, such as:
|
||||||
# data, previousHash, nonce
|
# data, previousHash, nonce
|
||||||
# Make sure to compute the hash value of the current block and store it properly
|
# Make sure to compute the hash value of the current block and store it properly
|
||||||
def mine(self, leading_zeros):
|
def mine(self, leading_zeros):
|
||||||
self.nonce = 0
|
self.nonce = 0
|
||||||
|
|
||||||
if self.previousBlock:
|
while True:
|
||||||
self.previousHash = self.previousBlock.blockHash
|
digest = self.computeHash()
|
||||||
else:
|
|
||||||
self.previousHash = None
|
if digest[:leading_zeros] == b'\x00' * leading_zeros:
|
||||||
|
self.blockHash = digest
|
||||||
while True:
|
print(self.nonce) # Output.txt file has printed nonce values
|
||||||
digest = self.computeHash()
|
break
|
||||||
|
|
||||||
if digest[:leading_zeros] == b'\x00' * leading_zeros:
|
self.nonce += 1
|
||||||
self.blockHash = digest
|
|
||||||
print(self.nonce) # Output.txt file has printed nonce values
|
# TODO 4: Check if the current block contains valid hash digest values
|
||||||
break
|
# Make sure to distinguish between the genesis block and other blocks
|
||||||
|
# Make sure to compare both hash digest values:
|
||||||
self.nonce += 1
|
# The computed digest of the current block
|
||||||
|
# The stored digest of the previous block
|
||||||
# TODO 4: Check if the current block contains valid hash digest values
|
# return the result of all comparisons as a boolean value
|
||||||
# Make sure to distinguish between the genesis block and other blocks
|
def is_valid_hash(self):
|
||||||
# Make sure to compare both hash digest values:
|
if(self.previousBlock == None):
|
||||||
# The computed digest of the current block
|
return True
|
||||||
# The stored digest of the previous block
|
|
||||||
# return the result of all comparisons as a boolean value
|
if(self.computeHash() != self.blockHash or self.previousBlock.blockHash != self.previousBlock.computeHash()):
|
||||||
# def is_valid_hash(self):
|
return False
|
||||||
# if(self.previousBlock == None):
|
return self.previousBlock.is_valid_hash()
|
||||||
# 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
|
|
Loading…
x
Reference in New Issue
Block a user