Difficulty adjustment in blockchain

We looked at the Proof-of-Work algorithm in the previous article, and in this article, we shall look at how we adjust the target hash based on the difficulty value to keep the transaction time constant.

For starters, we calculate the target hash based on a difficulty value. It is this difficulty value that we adjust to keep the time taken to produce a transaction constant. Let’s see how we adjust this difficulty value.

Bitcoin adjusts the difficulty value every 2016 transactions (it’s actually blocks and we shall discuss blocks later). Bitcoin expects each transaction (block) to take around 10 minutes. Therefore, effectively, Bitcoin adjusts the difficulty value every 20160 minutes, which is equal to two weeks. To make sure that transactions on average take 10 minutes, we need to measure the time taken for each transaction.

So, we timestamp every transaction. A timestamp is the number of milliseconds that have elapsed since the Unix epoch, which is 00:00:00 01 January 1970. We can find the difference between the timestamp of the 2016th block in the current batch and the 2016th block of the previous batch to find out the total time taken to complete these 2016 transactions.

Calculating difficulty

Once we have this value, we can compare this with the expected value, which is 20160 minutes, by dividing the expected value by the actual value. If both the values are the same, we will get a value of one. If the transactions have taken place quicker, then the result would be greater than one. Similarly, if the transactions take longer, we will get a value of less than one.

={\text{expected value (20160)} \over \text{actual value}}

We can then use this value to calculate difficulty. If the transactions were quicker, then that means we should increase the difficulty. We have already seen that by dividing the expected value by the actual value, we get a value greater than one if the transactions were quicker. Consequently, if we multiply this value by the existing difficulty, we will end up with a higher difficulty value.

\text{new difficulty}={\text{difficulty} \times {\text{expected value (20160)} \over \text{actual value}}}

Now, let’s look at a few examples. Assuming the actual value was 30,000, and the difficulty value is 100, let’s see what the new difficulty value would be.

\text{new difficulty}={100 \times {20160 \over 30000}}
\text{new difficulty}={100 \times 0.672}
\text{new difficulty}={67.2}

As you can see, the difficulty value has come down since the transactions have taken longer.

Let’s take another example with an actual value of 15,000 and a difficulty value of 100:

\text{new difficulty}={100 \times {20160 \over 15000}}
\text{new difficulty}={100 \times 1.334}
\text{new difficulty}={133.4}

The difficulty value has gone up since the transactions were quicker.

Calculating target hash based on difficulty

Let’s now see how we calculate the target hash based on the difficulty value. We have seen that the theoretical maximum hash value is 2255. But in actuality, the maximum hash value is set to:

0x00000000FFFF0000000000000000000000000000000000000000000000000000

We obtain the target hash value by dividing this maximum hash value by the difficulty value.

\text{target hash}={\text{maximum hash value} \over \text{difficulty}}

When a blockchain network is incepted, the target hash would be the maximum hash value. So, the difficulty value will be 1. As a result, the difficulty value can never be lower than 1 since a lower difficulty value will mean that the target hash will be higher than the maximum hash value.

The target hash becomes smaller and smaller as many computers join the network or as the processing power of the existing computers increases. This increases the difficulty of solving the puzzle and consequently, ensures that the time taken to solve the puzzle remains 10 minutes.

Storing target hash

However, we don’t store the target hash as a 256-bit hash in blocks (We shall learn about blocks later. For the time being, consider blocks as same as transactions.). In order to conserve space, we store it as a 32-bit (4-bytes) integer value. For example, the maximum possible hash is defined as 486604799, which is 0x1d00ffff in the hexadecimal format. This integer is called bits.

Let’s see how the bits are then converted back to the hash format. First, the value of the bits is converted to the hexadecimal format, which is 0x1d00ffff. This is, as aforementioned, a 4-byte number. The most significant byte of this (0x1d) is called the index. The 3 least significant bytes of this (0x00ffff) are called the coefficient. Now, we can use the following formula to find out the target hash value.

\text{target hash} = \text{coefficient} \times 2^{8 {(\text{index}-3)}}

Let’s try to plug the coefficient and the index into this formula to obtain the target hash.

\text{target hash} = \text{coefficient} \times 2^{8  {(\text{0x1d}-3)}}

This will give an output of

0xFFFEFFD1A3A429BFBCB8A4188E09DA06491A6841F000000000000000

We can round this off to

0xFFFF0000000000000000000000000000000000000000000000000000

Note that this has only 224 bits. To make it 256 bits, we can add zeroes in front.

0x00000000FFFF0000000000000000000000000000000000000000000000000000

This is the computed target hash.

Another method to calculate the target hash

However, there is an easier way to calculate this as well. Consider the index as the number of bytes and the coefficient as a prefix. In our example, the index is 0x1d, which converted to decimal is 29. So, the calculated value should have 29 bytes. The prefix, 0x00ffff, has only 3 bytes. So, append 52 zeroes to the prefix to obtain the remaining 26 bytes. And then add zeroes in front of this value to get a 256-bit hash.

One should also keep in mind that a maximum hash value of 0x00000000FFFF0000000000000000000000000000000000000000000000000000 is not applicable to pool miners (We shall see about pool mining in detail later). Pool miners use a maximum hash value of 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.

So, the difficulty value calculated by pool miners would differ from the one calculated by others. The difficulty value calculated by pool miners is called pdiff whereas the one calculated by others is called bdiff.

Now that we understand how we adjust the target hash value, let’s see how we create blocks out of transactions in the next article.

Leave a Reply

placeholder="comment">