ex and hw of week 4
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
#!/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
|
||||
|
||||
return self.computeHash() == self.blockHash
|
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
This test case will verify if the provided homework solution by a student for Blockchain.py is correct.
|
||||
"""
|
||||
from BlockChain import *
|
||||
|
||||
leading_zero = 2
|
||||
|
||||
dataG = 'Root'
|
||||
data1 = 'It is B1'
|
||||
data2 = 'It is B2'
|
||||
data3 = 'It is B3'
|
||||
data4 = 'It is B4'
|
||||
data5 = 'It is B5'
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# Instantiate different blocks to be added to the chain
|
||||
Gn = CBlock(dataG, None)
|
||||
B1 = CBlock(data1, Gn)
|
||||
B2 = CBlock(data2, B1)
|
||||
B3 = CBlock(data3, B2)
|
||||
B4 = CBlock(data4, B3)
|
||||
|
||||
print('\n--- Blocks are created --- Hashes and Nonces should not match!')
|
||||
|
||||
# Check if hashes and nonces of each block are valid
|
||||
for b, name in [(B1, 'B1'), (B2, 'B2'), (B3, 'B3'), (B4, 'B4')]:
|
||||
if b.is_valid_hash():
|
||||
print("Success! "+name+" hash matches")
|
||||
else:
|
||||
print("Fail! " +name+" hash does not match")
|
||||
|
||||
# Mine each block
|
||||
for b, name in [(Gn, 'Gn'), (B1, 'B1'), (B2, 'B2'), (B3, 'B3'), (B4, 'B4')]:
|
||||
print(f'\nMining {name} ...')
|
||||
b.mine(leading_zero)
|
||||
|
||||
print('\n--- Blocks are mined --- Hashes and Nonces must match!')
|
||||
# Check if hashes and nonces of each block are valid
|
||||
# Check if block are linked correctly
|
||||
for b, name in [(B1, 'B1'), (B2, 'B2'), (B3, 'B3'), (B4, 'B4')]:
|
||||
if b.is_valid_hash():
|
||||
print("Success! "+name+" hash matches")
|
||||
else:
|
||||
print("Fail! " +name+" hash does not match")
|
||||
|
||||
# Temper the value of a blok
|
||||
data3t = 'It is B3t'
|
||||
B3.data = data3t
|
||||
|
||||
print('\n--- Block3 is tampered --- Hashes and Nonces of blocks after B3 should not match!')
|
||||
# Check if tempering of block B3 can be detected.
|
||||
# Hashes and Nonces of its block must not match
|
||||
for b, name in [(B1, 'B1'), (B2, 'B2'), (B3, 'B3'), (B4, 'B4')]:
|
||||
if b.is_valid_hash():
|
||||
print("Success! "+name+" hash matches")
|
||||
else:
|
||||
print("Fail! " +name+" hash does not match")
|
||||
|
||||
# Mine the blockchain again
|
||||
for b, name in [(Gn, 'Gn'), (B1, 'B1'), (B2, 'B2'), (B3, 'B3'), (B4, 'B4')]:
|
||||
print(f'\nMining {name} ...')
|
||||
b.mine(leading_zero)
|
||||
|
||||
print('\n--- Blocks are mined again --- Hashes and Nonces must match again!')
|
||||
# Mine the blockchain again
|
||||
# Hashes and Nonces must match again
|
||||
for b, name in [(B1, 'B1'), (B2, 'B2'), (B3, 'B3'), (B4, 'B4')]:
|
||||
if b.is_valid_hash():
|
||||
print("Success! "+name+" hash matches")
|
||||
else:
|
||||
print("Fail! " +name+" hash does not match")
|
@@ -0,0 +1,43 @@
|
||||
--- Blocks are created --- Hashes and Nonces should not match!
|
||||
Fail! B1 hash does not match
|
||||
Fail! B2 hash does not match
|
||||
Fail! B3 hash does not match
|
||||
Fail! B4 hash does not match
|
||||
|
||||
Mining Gn ...
|
||||
11724
|
||||
Mining B1 ...
|
||||
21751
|
||||
Mining B2 ...
|
||||
83579
|
||||
Mining B3 ...
|
||||
209059
|
||||
Mining B4 ...
|
||||
67743
|
||||
--- Blocks are mined --- Hashes and Nonces must match!
|
||||
Success! B1 hash matches
|
||||
Success! B2 hash matches
|
||||
Success! B3 hash matches
|
||||
Success! B4 hash matches
|
||||
|
||||
--- Block3 is tampered --- Hashes and Nonces of blocks after B3 should not match!
|
||||
Success! B1 hash matches
|
||||
Success! B2 hash matches
|
||||
Fail! B3 hash does not match
|
||||
Fail! B4 hash does not match
|
||||
|
||||
Mining Gn ...
|
||||
11724
|
||||
Mining B1 ...
|
||||
21751
|
||||
Mining B2 ...
|
||||
83579
|
||||
Mining B3 ...
|
||||
143719
|
||||
Mining B4 ...
|
||||
67743
|
||||
--- Blocks are mined again --- Hashes and Nonces must match again!
|
||||
Success! B1 hash matches
|
||||
Success! B2 hash matches
|
||||
Success! B3 hash matches
|
||||
Success! B4 hash matches
|
Reference in New Issue
Block a user