2.9 PROOF OF WORK
EXERCISE 2.9 PROOF OF WORK
Write a program that feeds a counter in SHA-256, taking the output hash and converting it to an integer (we did this earlier before converting to binary). Have the program repeat until it finds a hash that is less than a target number. The target number should start out pretty big, like \(2^{255}\). To make this more like blockchain, include some arbitrary bytes to be combined with the counter.
# ex2_9.py
import hashlib
import secrets
def convert_to_decimal(number: str, base: int) -> int:
'''
Taken from https://github.com/noahabe/numrep/blob/master/numrep.py
Changes the first parameter (which is expected to be a hexadecimal number)
into a base 10 integer.
'''
########### [FOR HEXADECIMAL ONLY]############
if base == 16:
= {
convertion_table 'A': 10,
'B': 11,
'C': 12,
'D': 13,
'E': 14,
'F': 15,
}def CONVERT(x: str): return convertion_table[x.upper()]
#############################################
= 0
decimal = len(number)-1
position for single_digit in number:
if single_digit.isalpha():
= CONVERT(single_digit)
single_digit += int(single_digit) * base**position
decimal -= 1
position return decimal
def proof_of_work(random_block: bytes, target_number_exp: int) -> dict[str, str | bytes]:
= 0
counter = 2 ** target_number_exp
target_number try:
while True:
= hashlib.sha256()
h
h.update(random_block)str(counter).encode('utf-8'))
h.update(if convert_to_decimal(h.hexdigest(), 16) < target_number:
return {
"nonce": str(counter),
"hash": h.hexdigest(),
"random_block": random_block[0:3],
"target_number": f"2^{target_number_exp}"
}+= 1
counter except KeyboardInterrupt:
print("Exiting...")
exit()
def main(start_target_number_exponent: int = 255, end_target_number_exponent: int = 250):
# the random_block makes it look more like blockchain
= secrets.token_bytes(1000) # 1 Kilobyte of random bytes.
random_block for target_number_exp in range(start_target_number_exponent, end_target_number_exponent, -1):
= proof_of_work(random_block, target_number_exp)
retval print(retval)
if __name__ == '__main__':
= int(input("Start target number exponent: "))
start_target_number_exponent = int(input("End target number exponent: "))
end_target_number_exponent main(start_target_number_exponent, end_target_number_exponent)
The following video shows the execution of the above script: