'Python bitcoin miner not letting me define variable after mine
I have been trying to create a python bitcoin miner, that ACTUALLY puts the coins somewhere, so thats the first part of my quesiton, and the second part is how do I fix this error?
This is all of my code:
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)).hexdigest()
# check if this is a valid result, below the target
if int(hash_result, 16) < target:
print ("Success with nonce %d" % nonce)
print ("Hash is %s" % hash_result)
return (hash_result,nonce)
print ("Failed after %d (max_nonce) tries" % nonce)
return nonce
if __name__ == '__main__':
nonce = 0
hash_result = ''
# difficulty from 0 to 31 bits
for difficulty_bits in range(32):
difficulty = 2 ** difficulty_bits
print ("Difficulty: %ld (%d bits)" % (difficulty, difficulty_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).hexdigest()
# checkpoint how long it took to find a result
end_time = time.time()
The line above this, The end_time seems to get an error, with no definition to what the error is. Please help.
Please note that I have tried a great deal of commenting out a bunch of things, changing code, and this is in python 3
Solution 1:[1]
I'm writing this as an answer because of the many issues.
First, hashllib requires byte strings. You would need
hash_result = hashlib.sha256((header+str(nonce)).encode('utf-8')).hexdigest()
Second, you're doing proof_of_work(...).hexdigest(), but that function isn't returning a hash object. You are already calling hexdigest. Your function either returns a 2-tuple, or a nonce. You want to remove the hexdigest call:
# find a valid nonce for the new block
(hash_result, nonce) = proof_of_work((new_block, difficulty_bits)
And, in the final line of proof_of_work change
return nonce
to
return (None, nonce)
Next, you are converting the nonce to decimal digits to tack it on to the block. That is completely wrong. The nonce needs to be a 4-byte value. Something like:
enonce = struct.pack('I', nonce)
hash_result = hashlib.sha256(header.encode('utf-8')+enonce).hexdigest()
Finally, this whole thing is silly. Have you timed that inner loop to see how long it takes? On my box, it takes about 500 microseconds per loop. To run that 4 billion times would require a month and a half. To repeat that for all 32 difficult values would make it take 4 years.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Tim Roberts |
