Last active
November 30, 2023 15:41
-
-
Save scharton/102100f39fa9c8a9b55330a507a5590f to your computer and use it in GitHub Desktop.
Python proof of work example from Mastering Bitcoin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import hashlib | |
import time | |
max_nonce = 2 ** 32 # 4 billion | |
def proof_of_work(header, difficulty_bits): | |
# calculate the difficulty target | |
target = 2 ** (256-difficulty_bits) | |
for nonce in range(max_nonce): | |
hash_result = hashlib.sha256( | |
(str(header)+str(nonce)).encode() | |
).hexdigest() | |
# check if this is a valid result, below the target | |
if int(hash_result, 16) < target: | |
print(f"Success with nonce {nonce}") | |
print(f"Hash is {hash_result}") | |
return (hash_result,nonce) | |
print(f"Failed after {nonce} (max_nonce) tries") | |
return nonce | |
if __name__ == "__main__": | |
nonce = 0 | |
hash_result = '' | |
# difficulty from 0 to 31 bits | |
original_max_range = 32 | |
test_range = 3 | |
for difficulty_bits in range(test_range): | |
difficulty = 2 ** difficulty_bits | |
print(f"\nDifficulty: {difficulty} ({difficulty_bits} bits)") | |
print("Starting search...") | |
# checkpoint the current time | |
start_time = time.time() | |
# make a new block which includes the hash from the previous block | |
# we fake a block of transactions - just a string | |
new_block = "test block with transactions" + hash_result | |
# find a valid nonce for the new block | |
(hash_result, nonce) = proof_of_work(new_block, difficulty_bits) | |
# checkpoint how long it took to find a result | |
end_time = time.time() | |
elapsed_time = end_time - start_time | |
print(f"Elapsed Time: {elapsed_time:4f} seconds") | |
if elapsed_time > 0: | |
# estimate the hashes per second | |
hash_power = float(int(nonce)/elapsed_time) | |
print(f"Hashing Power: {hash_power} hashes per second") |
Python 3 version:
import hashlib
import time
max_nonce = 2 ** 32 # 4 billion
def proof_of_work(header, difficulty_bits):
# calculate the difficulty target
target = 2 ** (256-difficulty_bits)
for nonce in range(max_nonce):
hash_result = hashlib.sha256(
(str(header)+str(nonce)).encode()
).hexdigest()
# check if this is a valid result, below the target
if int(hash_result, 16) < target:
print(f"Success with nonce {nonce}")
print(f"Hash is {hash_result}")
return (hash_result,nonce)
print(f"Failed after {nonce} (max_nonce) tries")
return nonce
if __name__ == "__main__":
nonce = 0
hash_result = ''
# difficulty from 0 to 31 bits
original_max_range = 32
test_range = 32
for difficulty_bits in range(test_range):
difficulty = 2 ** difficulty_bits
print(f"\nDifficulty: {difficulty} ({difficulty_bits} bits)")
print("Starting search...")
# checkpoint the current time
start_time = time.time()
# make a new block which includes the hash from the previous block
# we fake a block of transactions - just a string
new_block = "test block with transactions" + hash_result
# find a valid nonce for the new block
(hash_result, nonce) = proof_of_work(new_block, difficulty_bits)
# checkpoint how long it took to find a result
end_time = time.time()
elapsed_time = end_time - start_time
print(f"Elapsed Time: {elapsed_time:4f} seconds")
if elapsed_time > 0:
# estimate the hashes per second
hash_power = float(int(nonce)/elapsed_time)
print(f"Hashing Power: {hash_power} hashes per second")
I forgot I posted this. Thanks for the update.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What is the difficulty bits imply ?