If you are wondering why this are part 4.1 instead of Part 4, and why I ' m not talking about continuing to builds the local JB C, it's because explaining Bitcoin ' s Proof of Work difficulty at a somewhat level lower a takes of spaces. So unlike what this title says, this post in the Part 4 are not how to build a blockchain. It ' s about how a existing blockchain is built.
My main goal of the "Part 4 post is to have one section on the Bitcoin PoW," Next on Ethereum ' s PoW, and finally talk a Bout how JBC are going to run and validate proof or work. After writing all of the Part 1 to explain how Bitcoin's PoW difficulty, it wasn ' t going to fit in a single section. People, me included, tend get bored in middle reading a long post and don ' t finish.
So part 4.1 'll be going through Bitcoin ' PoW difficulty. Part 4.2 would be going through Ethereum ' PoW calculations. and then part 4.3 'll is me deciding how I want the JBC PoW to being as so as doing time calculations to Mining would take.
The sections of this post are:calculate target from Bits determining if a Hash is less than the Target calculating diffic Ulty how and when blocks difficulty is updated full code Final Questions tl;dr
The overall term of difficulty refers to how much work has to being done for a-node to find a hash this is smaller than t He target. There is one value stored in a blocks that talks about Difficulty- bits. In order to calculate the target value this hash, when converted to a hex value has to is less than, we use The bits field and run it through a equation that returns the target. We then use The target to calculate difficulty, Where difficulty is only a number for a human to Understand how difficult the proof of work are for this block.
If you read in, I go through how the blockchain determines what target number the mined blocks ' hash needs to be less than To being valid, and how the target is calculated. Other Posts in this Series Part 1-creating, storing, Syncing, displaying, Mining, and proving Work part 2-syncing chains to different Par T 3-nodes that Mine part 4.2-ethereum Proof of Work Difficulty explained Calculate Target from Bits
In through Bitcoin's PoW, I need to use the values on actual blocks and explain the calculations, so a reader Can verify all this code themselves. To-Start, I ' m going to grab a random blocks number to work with and go through of using that.
>>>import random >>> random.randint (0, 493928) 111388
Block number 11138 It is! Back into March of We go.
We ' re going to-start with assigning variables with the bits and difficulty values from the blocks, as as the hash, so We can test its validity in the end.
>>> bits = ' 453062093 ' >>> difficulty = float (' 55,589.52 '. Replace (', ', ')) >>> Block_hash = ' 00000000000019c6573a179d385f6b15f4b0645764c4960ee02b33a3c7117d1e '
Next part shows I to the "bits" field to the target. There are at least two different ways to do this-the A-I-involves-string manipulation and string to-integer conversion , and the other uses bit manipulation.
For the "the", "manipulation part," We convert the bits string to an integer and then to a hex string. The two characters of the hex_bits string are in one variable, which I call shift, and the remaining six are The value. From there, we use those values into the integer equation that would calculate the integer value of the target, which we can Convert to a hex string to look in how pretty it is!
Note this ' L ' on the ' the ' and ' the ' ' of the target ' and hex (target) are only Python telling your that numbexr are too long to be stor Ed as a int, and that it ' s stored as a long.
>>> hex_bits = hex (int (bits)) >>> hex_bits ' 0X1B012DCD ' >>> shift = ' 0x%s '% hex _bits[2:4] >>> shift ' 0x1b ' >>> shift_int = int (exponent,) >>> Value = ' 0x%s '% hex_bits[4:] >>> value ' 0X012DCD ' >>> value_int = int (coefficient, 16) c11/>77261 >>> target = value_int * 2 * * (8 * (shift_int-3)) >>> target 484975157177710 342494716926626447514974484083994735770500857856L >>> hex_target = Hex (target) >>> hex _target ' 0x12dcd000000000000000000000000000000000000000000000000l '
It seems a little fake when we slice a string to calculate the target like we do above. When looking through the C + + Bitcoin implementation, it shows the other, more technical, main method of using BITS to Calc Ulate Target. Here ' s the Python implementation.
I ' ll go through the lines and print values are here to show a little better what ' s going on. One thing to know before reading was that a character in a hex string represents 4 bits. So then we shift the bits variable by bits with bits >> 24 that affectively removes the last 6 characte Rs of the Hex string leaving the two. to get the value variable, we use the bitwise AND OPERATOR&NBSP ;& to have the final bits is the value. The "bits is usually" (defined by the number of bits in 0X7FFFFF) the final 6 characters of the hex string,
Now, The 8 * (shift-3) value determines how many bits we ' re going to shift value over. In the this case, it's determined to be a. If we divide by 4, we'll have the number of zeros characters that'll be behind the value in the hex string repre Sentation of the target number. You ' ll be in that it ' s zeros. Another thing to how to-is-confusing is that value << y is the same as value * 2**y. That's how the equations are related.
>>> bits = ' 453062093 ' >>> hex (int (bits)) ' 0X1B012DCD ' >>> shift = bits > > >>> shift >>> Hex (Shift) ' 0x1b ' >>> value = bits & 0X007FFFFF >>> Hex (value) ' 0X12DCD ' >>> 8 * (shift-3) 192 /4 #each character in a hex string represents 4 bits >>> value <<= 8 * (shift-3) >& Gt;> Hex (value) ' 0x12dcd000000000000000000000000000000000000000000000000l ' >>> Hex (value). Count (' 0 ')-1 #don ' t count the leading zero 48
The full function version ' is ' only a few lines long.
>>> def get_target_from_bits (bits): ... shift = Bits >> ... Value = Bits & 0x007fffff ... Value <<= 8 * (shift-3) ... return value ... >>> target = def get_target_from_bits (int (bits)) >>> Hex (target) 0x12dcd000000000000000000000000000000000000000000000000l '
So nice. If you look way above to the string manipulation code it's way more confusing and has so many extra lines than the fun Ction above. It ' s great to go through both to really understand the meaning, but then stick with the simple one. Moving on. determining if a Hash is less than the Target
As always it seems, there are two simple ways to = if a block ' s hash was valid according to the target. The the ' The ' Way is ' to use ' full, character, 256 bit, hex strings and compare those. This works great since we'll be able to the easily eye to eye. To the "the" case, we ' re going to pad the hex_target with the zeros to fill all characters.
>>> Hex_target = Hex (target) >>> len (hex_target) >>> len (hex_target[2:-1) ) #[2:-1] Removes the leading ' 0x ' and ending ' L ' >>> num_padded_zeros = 64-hex_target_len >& gt;> num_padded_zeros >>> padded_hex_target = "0X%S%SL"% (' 0 ' * (64-num_padded_zeros), hex_ TARGET[2:-1]) >>> padded_hex_target ' 0x0000000000012dcd000000000000000000000000000000000000000000000000l '
Finally, we want to verify which the block's hash is less than the target. And also, since strings can be considered less than or greater than, we'll go to with that.
>>> Len (block_hash) >>> padded_block_hash = ' 0x%sl '% block_hash >>> Padded _block_hash 0x00000000000019c6573a179d385f6b15f4b0645764c4960ee02b33a3c7117d1el >>> Padded_hex _target 0x0000000000012dcd000000000000000000000000000000000000000000000000l >>> assert padded_ Block_hash < Padded_hex_target >>>
In this case, you'll be the hex target is larger than the "block" hash. Comparing which string is larger are as simple as either < or. If you are wondering how to Python can determine that the characters like ' F ' > ' 1 ', the questions below.
The other way to confirm are by using the integers for both values. But as you'll be, it's very difficult, if not impossible, to eyeball which are value larger, and how much larger one value is to than the other.
>>> block_hash_int = Int (Block_hash,) >>> block_hash_int 41418456048005639864974238890271849696605172030151526454492446L >>> Target 484975157177710342494716926626447514974484083994735770500857856L >>> assert (Block_hash_int < Target) >>> target-block_hash_int 443556701129704702629742687736175665277878911964584244046365410L
Those ints are so huge that looking in one by itself are pretty much more impossible to know if it's easy or difficult to being low ER than. But since Block_hash_int is lower than target int by one character, you can have a. When you subtract those two giant numbers another number.
Both are valid methods, but being able to look at the hex strings are better than at the looking. But really, when the code is running, there's no real benefit to pick one on the other. Calculating Difficulty
The most important part of difficulty was to remember from above that difficulty is simply a human representation of the TA Rget. I talked about how an integer values of targets are pointless since it ' s hard to humanly compare two values that are giant in Teger. Likewise, it's tough to compare two targets to each other using the hex strings. The difficulty values in a blocks are to make that easier.
Below, Difficulty_one_target is defined as the easiest allowed target value. To calculate the difficulty of another blocks, we simply divide the difficulty_one_target by the target we ' ve calculated us ing bits. You'll be in that Difficulty_one_target would be larger than any other targetnumber since targets go lower with more difficul Ty. When you divide the larger numerator by a smaller denominator, you ll have a greater than one value.
> >> difficulty_one_target = 0x00ffff * 2** (8* (0x1d-3)) >>> Difficulty_one_target 26959535291011309493156476344723991336010898738574164086137773096960L #calculated using >>> pad_leading_ Zeros (Hex (difficulty_one_target)) #pad_leading_zeros is function defined below ' 0x00000000ffff0000000000000000000000000000000000000000000000000000 ' >>> calculated_difficulty = Difficulty_one_target/float (target) #float () to make it decimal devision 55589.518126868665 #this is the same as the DIF Ficulty on the block. >>> allowed_error = 0.01 >>> assert abs (float (block_difficulty)-calculated_difficulty) <= allowed _error >>>
Feel the "Go" back and read this over slowly. It took me a long time to figure out the relationship between bits, difficulty, and target. Whether We need ints, hex values, or strings to verify. There are a bunch of ways to does this, and hopefully I ' ve listed them all here. How to and when blocks difficulty is updated
The final big part of Bitcoin ' s proof of work are to show how and, the difficulty is changed. Pretty much every post on this topic would say that chain'll recalculate the required new difficulty every block S. But they don ' t dive too deep at all into the topic. That ' s what I ' m going.
The "I" I have to "start with" and "to" and "go" to bits. The