Difficulty in Mining

You are here:
< Back

Difficulty is a value used to show how hard is it to find a hash that will be lower than target defined by system.

The Bitcoin network has a global block difficulty. Valid blocks must have a hash below this target. Mining pools also have a pool-specific share difficulty setting a lower limit for shares.

Principles of operation

In Bitcoin[network there’s global difficulty set for all blocks. For block to be considered legitimate it has to have hash value lower than set target.

Difficulty is changed every 2016 blocks. This is calculated using following formula:

difficulty = difficulty_1_target / current_target

where target is a 256-bit number.

Difficulty_1_target can take various values. Traditionally it’s a hash function first 32 bits of which are equal to 0 while all the rest are 1 (it is also called pdiff or pool difficulty). Bitcoin protocol provides target as a type with floating point and limited accuracy. Different Bitcoin clients often determine difficulty based on this data.

Storing difficulty in blocks

Every block contains a packed version (called “Bits”) of hexadecimal target.

Using following formula target can be obtained from any block. For example if a target packed in a block appears as 0x1b0404cb its hexadecimal version will look as following:

0x0404cb * 2**(8*(0x1b - 3)) = 0x00000000000404CB000000000000000000000000000000000000000000000000

Maximum value for this field is 0x7fffff while minimum is 0x008000.

Maximum possible target (with difficulty equal to 1) is defined as 0x1d00ffff which appears as following in hexadecimal numeration:

0x00ffff * 2**(8*(0x1d - 3)) = 0x00000000FFFF0000000000000000000000000000000000000000000000000000

Next is an easy way of difficulty calculation. It uses an altered version of Taylor series to logarithm and relies on logs to transform difficulty calculation.

#include <iostream>
#include <cmath>

inline float fast_log(float val)
   int * const exp_ptr = reinterpret_cast <int *>(&val);
   int x = *exp_ptr;
   const int log_2 = ((x >> 23) & 255) - 128;
   x &= ~(255 << 23);
   x += 127 << 23;
   *exp_ptr = x;

   val = ((-1.0f/3) * val + 2) * val - 2.0f/3;
   return ((val + log_2) * 0.69314718f);

float difficulty(unsigned int bits)
    static double max_body = fast_log(0x00ffff), scaland = fast_log(256);
    return exp(max_body - fast_log(bits & 0x00ffffff) + scaland * (0x1d - ((bits & 0xff000000) >> 24)));

int main()
    std::cout << difficulty(0x1b0404cb) << std::endl;
    return 0;

Maximum, current and minimum difficulty

Current difficulty can be found out by using Bitcoin command line ‘getDifficulty’.

Due to target function not having minimum value maximum difficulty can be calculated only approximately as following: maximum_target / 1 (as 0 would lead the equation to being infinitely big) which is an inconcievable number (~2 to the 224).

Minimum difficulty is just equal to 1.

Difficulty changes

Difficulty is changed every 2016 blocks based on the time it took to discover 2016 previous blocks. If a block is found every 10 minutes (as it was intended initially for even emission) finding 2016 blocks will take exactly 2 weeks. If previous 2016 blocks were found in more than two weeks the difficulty will be lowered, and if they were mined faster then that it will be raised. The more (or less) time was spent on finding the previous 2016 blocks the more will difficulty be lowered (raised).

To mine a block hash has to be lower than targer (proof-of-work). Hash is a random number between 0 and 2*256-1.

Shift for difficulty of 1: 0xffff * 2**208
For difficulty D: (0xffff * 2**208)/D
Amount of hash-functions needed to be solved for a block to be found at difficulty D: D * 2**256 / (0xffff * 2**208)
Or simply: D * 2**48 / 0xffff

Difficulty is set as if we found previous 2016 blocks at the speed of one block per 10 minutes

According to this we were calculating (D * 2**48 / 0xffff) hashes every 600 seconds.
Our network's hashrate for previous 2016 blocks was: D * 2**32 / 0xffff / 600.
Without significant accuracy loss we can simplify it down to: D * 2**32 / 600.
At difficulty of 1 that is roughly 7 Mhash/s.

Average time of finding a single block can be calculated using this formula: time = difficulty * 2**32 / hashrate where ‘difficulty’ is the current difficulty level of Bitcoin network and ‘hashrate’ is the amount of hashes a miner finds per second.

What is the current difficulty?

Current difficulty, as output by Bitcoin’s getDifficulty.


What is the maximum difficulty?

There is no minimum target. The maximum difficulty is roughly: maximum_target / 1 (since 0 would result in infinity), which is a ridiculously huge number (about 2^224).

The actual maximum difficulty is when current_target=0, but we would not be able to calculate the difficulty if that happened. (fortunately it never will, so we’re ok.)

Can the network difficulty go down?

Yes it can.

What is the minimum difficulty?

The minimum difficulty, when the target is at the maximum allowed value, is 1.

What network hash rate results in a given difficulty?

The difficulty is adjusted every 2016 blocks based on the time it took to find the previous 2016 blocks. At the desired rate of one block each 10 minutes, 2016 blocks would take exactly two weeks to find. If the previous 2016 blocks took more than two weeks to find, the difficulty is reduced. If they took less than two weeks, the difficulty is increased. The change in difficulty is in proportion to the amount of time over or under two weeks the previous 2016 blocks took to find.

To find a block, the hash must be less than the target. The hash is effectively a random number between 0 and 2**256-1. The offset for difficulty 1 is

0xffff * 2**208

and for difficulty D is

(0xffff * 2**208)/D

The expected number of hashes we need to calculate to find a block with difficulty D is therefore

D * 2**256 / (0xffff * 2**208)

or just

D * 2**48 / 0xffff

The difficulty is set such that the previous 2016 blocks would have been found at the rate of one every 10 minutes, so we were calculating (D * 2**48 / 0xffff) hashes in 600 seconds. That means the hash rate of the network was

D * 2**48 / 0xffff / 600

over the previous 2016 blocks. Can be further simplified to

D * 2**32 / 600

without much loss of accuracy.

At difficulty 1, that is around 7 Mhashes per second.

At the time of writing, the difficulty is 22012.4941572, which means that over the previous set of 2016 blocks found the average network hash rate was

22012.4941572 * 2**32 / 600 = around 157 Ghashes per second.

How soon might I expect to generate a block?

(The eternal question.)

The average time to find a block can be approximated by calculating:

time = difficulty * 2**32 / hashrate

where difficulty is the current difficulty, hashrate is the number of hashes your miner calculates per second, and time is the average in seconds between the blocks you find.

For example, using Python we calculate the average time to generate a block using a 1Ghash/s mining rig when the difficulty is 20000:

$ python -c "print 20000 * 2**32 / 10**9 / 60 / 60.0"

and find that it takes just under 24 hours on average.