I’ll cut to the chase. You’re reading this because you want to understand the concept of bitcoin difficulty but you don’t want a long intro about bitcoin in general, you just want to know how the difficulty algorithm works.
Here’s how:
b = 1 / hp
Where:
b = Block Time
h = Hash rate
p = Probability of finding a block in one hashing attempt
b and h should have the same time units (e.g. seconds) and p, like all probabilities, is between 0 and 1. Having any 2 of these values means the third can be found.
Using this simple equation websites such as blockchain.info can publish the hash rate, currently about 35,000,000 TH/sec (that’s 35,000,000,000,000,000,000).
Blockchain.info don’t find the hash rate by by calling up all the bitcoin miners every month and ask them what their hash rate is, nor is there a centralized mining registry where miners must report their hash rate every month. The hash rate is instead calculated using the above equation, (well actually rearranged a little to be h=1/bp). It’s an extremely cheap calculation. p and b are known. b is the mean time between blocks and that can be calculated by averaging the block time of the last few blocks, and p can be calculated from the difficulty.
But what is the difficulty?
Consider the equation p=x/y. Holding y constant and changing the value of x causes p to change proportionally to x. Difficulty is the inverse of p. d = 1/p if you like. This d is not needed in the calcuulations though. The lower x (and thus p) are, the greater the difficulty. A bitcoin miner is said to “solve” a block if they produce a hash of that block which is lower than the current difficulty, x.
Essentially, mining is randomly guessing numbers from 0 to y until you find one that’s less than or equal to x.
However, this guessing has to be random and done in a very specific way; and if you make a correct guess you have to prove that you made the guess in this way: Computing SHA-256 hashes of a block header.
As a miner, every time you produce a hash you’re essentially generating a random number between 0 and 2256. Because of the way hashing works, you have no control of how these numbers are distributed. You can’t aim at a certain range of numbers, or rule out certain numbers you already tried. All you can do is keep trying again and again, until you get a number less than the current difficulty target. And it’s possible to guess the same number twice. Although hash collisions are highly unlikely.
Difficulty Adjustment
Every 2,016 blocks the bitcoin difficulty is adjusted such that it will make the average block time about ten minutes. If the hash rate is unusually high the average block time will be less than ten minutes and if the hash rate is unusually low it will be more than ten minutes.
Let’s do an example adjustment.
First observe the previous 2,016 blocks and for each one note the time between it and it’s predecessor. Sum up all these observations and divide by 2,016 to find the mean, or use the median — they’re likely to be very similar. We measure this number to be 2m 35s, or 155s. So that’s one variable found: the block time or b.
The other variable is the current p (probability of finding a block), which is burned onto each of the previous 2,016 blocks. The current difficulty is 2243.
So let’s calculate it:
p = 2243 / 2256
p = 1 / 2256-243
p = 1 / 213
p = 0.0001220703125
So that’s the current p. Having b and p we can compute h. Re-arrange the equation:
h = 1 / bp
h = 1 / (0.0001220703125 ✕ 155.0)
h = 1 / 0.0189208984375
h = 52.851612903225806
This is the current hash rate. Using our trusted equation again, this time in terms of p, to compute the probability necessary to make the blocks happen every ten minutes given the current hash rate.
p = 1 / hb
p = 1 / (52.851612903225806 ✕ 600)
p = 0.0000315348307291666
Finally multiply the new p by 2256 to get the newly adjusted difficulty target. Using python:
>>> import math
>>> (2 ** 256) * 0.0000315348307291666
3.65148393387532e+72
>>> math.log(_,2)
241.04730571477836
So the difficulty has got smaller roughly by a factor of 4 — it’s gone from 2243 to 2241. This means there’s a smaller target, thus the probability will be smaller, thus more hashing attempts will fail thus the block time will increase, also by a factor of 4. This makes sense as the original non-adjusted block time was 2m 35s, which is roughly one quarter of 10 minutes.
It’s worth pondering for a second the enormity of these numbers. Searching for a number less than 2243 in the search space of 2256 is like searching for a needle in a haystack, but 2243 is a massive number. Far larger than the number of atoms in the earth.