Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Showing of Bitcoin's Proof of Work difficulty is calculated and changed.
import datetime
###################################################################
#
# Showing the way bits, difficulty, target, and hash work together.
#
###################################################################
print "Calculating target from bits, verifying the block's hash is valid, and verify the calculated difficulty."
def pad_leading_zeros(hex_str):
hex_num_chars = hex_str[2:-1]
num_zeros_needed = 64 - len(hex_num_chars)
padded_hex_str = '0x%s%s' % ('0' * num_zeros_needed, hex_num_chars)
return padded_hex_str
def run_difficulty_information(bits, block_difficulty, block_hash):
target = get_target_from_bits(bits)
padded_hex_target = pad_leading_zeros(hex(target))
#making sure that the block's hash is less than the target
block_hash_hex = '0x%s' % block_hash
block_hash_int = int(block_hash, 16)
assert block_hash_hex < padded_hex_target
assert block_hash_int < target
print 'Padded target hex: %s' % padded_hex_target
print 'Block hash in hex: %s' % block_hash_hex
calculated_difficulty = get_difficulty_from_bits(bits)
allowed_error = 0.01
assert abs(float(block_difficulty) - calculated_difficulty) <= allowed_error
print 'Difficulty: %s' % block_difficulty
print 'Calculated Difficulty: %s' % calculated_difficulty
print #print that new line
#genesis block
print 'Block 0'
difficulty = '1.0'
bits = '486604799'
block_hash = '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f'
run_difficulty_information(bits, difficulty, block_hash)
#first block with difficulty not 1.0
print 'Block 32256'
difficulty = '1.18'
bits = '486594666'
block_hash = '000000004f2886a170adb7204cb0c7a824217dd24d11a74423d564c4e0904967'
run_difficulty_information(bits, difficulty, block_hash)
#block 11138
print 'Block 111388'
difficulty = '55589.52'
bits = '453062093'
block_hash = '00000000000019c6573a179d385f6b15f4b0645764c4960ee02b33a3c7117d1e'
run_difficulty_information(bits, difficulty, block_hash)
#block 493955
print 'Block 493955'
difficulty = '1364422081125.15'
bits = '402705995'
block_hash = '000000000000000000af4c179fcd65679f659947b0af164433fc1b99a186ff48'
run_difficulty_information(bits, difficulty, block_hash)
################################################################
#
# Shows how difficulty is changed when BLOCK_NUMBER % 2016 == 0
#
################################################################
print "Adjusting difficulty after every 2016 blocks"
def get_target_from_bits(bits):
if type(bits) == str:
bits = int(bits)
shift = bits >> 24
value = bits & 0x007fffff
value <<= 8 * (shift - 3)
return value
def get_difficulty_from_bits(bits):
difficulty_one_target = 0x00ffff * 2 ** (8 * (0x1d - 3))
target = get_target_from_bits(bits)
calculated_difficulty = difficulty_one_target / float(target)
return calculated_difficulty
def get_bits_from_target(target):
bitlength = target.bit_length() + 1 #look on bitcoin cpp for info
size = (bitlength + 7) / 8
value = target >> 8 * (size - 3)
value |= size << 24 #shift size 24 bits to the left, and taks those on the front of compact
return value
TARGET_TIMESPAN = 1209600
def change_target(prev_bits, starting_time_secs, prev_time_secs):
old_target = get_target_from_bits(int(prev_bits))
time_span = prev_time_secs - starting_time_secs
time_span_seconds = int(time_span.total_seconds())
new_target = old_target
new_target *= time_span_seconds
new_target /= TARGET_TIMESPAN
return new_target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.