Skip to content

Instantly share code, notes, and snippets.

# jackschultz/bitcoin_block_difficulty_analysis.py Created Nov 12, 2017

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
to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.