3

My understanding is that Difficulty (aka Network Difficulty) is an approximate representation of the Target, a 256-bit number which is hard to reason about or work with in human-readable Decimal format.

The Bitcoin wiki defines Difficulty as: difficulty = difficulty_1_target / current_target, where difficulty_1_target was the Target during the first Difficulty Epoch (the first 2016 blocks).

Is this definition of Difficulty correct? If yes, is it accurate to think about Difficulty as a type of proportion or ratio? And if it is a floating point number, what is its precision?

I don't often work with hexadecimal or 256-bit numbers, so I am confused where the "approximation" piece comes in, making Difficulty values easier to work with than the Target. Is Difficulty rounded after some decimal place?

Lastly, could someone please confirm the formula used to compare a hash against the Target, to see if it mines a valid block? For more practical use, how would you represent this formula using Difficulty instead of the Target?

Thank you

3 Answers 3

5

Is this definition of Difficulty correct?

Yes.

If yes, is it accurate to think about Difficulty as a type of proportion or ratio?

Yes, it is how many times harder current blocks are to mine than blocks in the first difficulty epoch were.

For reference, difficulty 1 corresponds to (very close to) 4295032833 hash attempts per block. It has a target of (exactly) 26959535291011309493156476344723991336010898738574164086137773096960.

Block 822627 has a target of (exactly) 374406027949793378682501776760424667692437142927048704.

The ratio between these two huge numbers is (approximately) 72006146478567.1. That is the difficulty of block 822627. It is roughly 72006 billion times harder to mine a block today than it was in January 2009.

And if it is a floating point number, what is its precision?

Whatever precision you calculate it to. Typical implementations will use a floating-point data type in the computation, which necessary limits its precision.

But it's really just the ratio of two huge numbers. You can calculate it to much higher precision too. Block 822627 has difficulty 72006146478567.09941095874369093485414495333341140374503764945604440...

That much precision isn't needed, as the difficulty is really just used for presenting the hardness of mining a block to humans. Internally the software uses the target, which is exact.

Lastly, could someone please confirm the formula used to compare a hash against the Target, to see if it mines a valid block?

The requirement is: block_hash ≤ target (where block_hash is the block hash interpreted as 256-bit little-endian number). The lower the target is, the harder it is to land below it. In a way, the difficulty is a measure for "target lowness".

For more practical use, how would you represent this formula using Difficulty instead of the Target?

Perhaps something like block_hash_diff ≥ difficulty, where block_hash_diff is the ratio between the first block's target (given above) and the block's actual target?

5
  • Thanks Pieter! This is super helpful and clears up a lot of my confusion. At difficulty 1, where target is 0xffff * 2**208 or 26959535291011309493156476344723991336010898738574164086137773096960, I thought the statistical average number of hashes required to find a block was pow(2, 32) or 4294967296, but in your answer you say it is very close to 4295032833. Could you share how you arrived at your number?
    – sha2fiddy
    Commented Dec 24, 2023 at 15:09
  • 1
    The number of valid hashes (2^208 * 0xffff) divided by 2^256 (number of possible hash outcomes) is (very close to) 1/4295032833. More exactly, it is 1/(2^48 / 0xffff). Commented Dec 24, 2023 at 15:23
  • 1
    To be entirely precise, the number of valid hashes at difficulty 1 is actually (0xffff * 2**208) + 1, as the consensus rule is that the hash value is less than or equal to the target. But the effect of that + 1 is so small that it's generally ignored. Commented Dec 24, 2023 at 15:30
  • Interesting... in the mining industry, it is common to take an amount of mining shares and multiply by 4294967296 (2^32) to produce an approximate number of hashes. Divide that by total seconds for an approximate hashrate. IE, assuming a share difficulty level 1, appx_hashrate = shares * 4294967296 / seconds. I'm now wondering if it would be more accurate to use 4295032833 for the rate of diff 1 shares-to-hashes?
    – sha2fiddy
    Commented Dec 24, 2023 at 18:17
  • 1
    @sha2fiddy Inside the Stratum protocol used for pool mining there is also a notion of (share) difficulty, however it corresponds to exactly 2^32 hashes per block (so it differs from difficulty as used by the rest of the ecosystem). Commented Dec 24, 2023 at 18:43
3

is it accurate to think about Difficulty as a type of proportion or ratio?

I think of it as just a number that is an abstract representation of the probability of a mining attempt failing. As with darts or archery etc, smaller targets are more difficult to hit.

difficulty ∝ 1 / targetsize


if it is a floating point number,

As Pieter Wuille clarified, floating point arithmetic is used in recalculating network targets.

For my purposes, I find it easiest to ignore difficulty completely and work with targets. Your subject area scope may differ.


I am confused where the "approximation" piece

See Pieter Wuille's clarifying comment:

The difficulty is an approximation [...] because in practice it's a floating-point number, computed to some finite precision.


the formula used to compare a hash against the Target,

if hash <= target then success

P.S. Targets are ranges

Really the target is a sub-range within the range of numbers that can be represented by a 256-bit integer. It is the size of this sub-range as a proportion of the total range that is important. You can achieve the same effect by saying miners have to find a number in the top n% or the bottom n% or any range n% wide anywhere in between. In a range of 0-1000 the target subranges of 0-10 or 990-1000 or 357-367 are all equally difficult to hit using a pseudo-random number generator such as a hashing algorithm. Bitcoin's inventor made an arbitrary choice of one end of the range. If the other end had been chosen the relationship between target and difficulty would not be an inverse one.


Somehow I thought the Target got larger as hashrate increased,

It is the opposite: the size of the target range is made smaller (more difficult to hit) after total network hashrate increases.


P.P.S Difficulty is a useful concept but a superfluous number for most purposes?

The API docs say

getdifficulty

Returns the proof-of-work difficulty as a multiple of the minimum difficulty.

(my emphasis)

Note that the difficulty number is not actually used in mining or block validation, the target is. I believe difficulty is only used as a way of presenting the target to humans in a way that might be more intuitive.

5
  • Thank you. When I query my Bitcoin node getdifficulty it currently returns 72006146478567.09 , a floating point number. If Difficulty is not a floating point number, is this transformation just happening at the JSON RPC layer, and why? if hash <= target then success - now I am extra confused. Somehow I thought the Target got larger as hashrate increased, and that the formula should look more like this: if hash <= 1 / target then success.
    – sha2fiddy
    Commented Dec 23, 2023 at 23:33
  • See postscripts to answer. Commented Dec 24, 2023 at 0:04
  • I don't think the rounding in the "bits" representation is relevant here; that's internal to the target computation algorithm. The bits that come out, and its corresponding "rounded" target are the exact values from the perspective of consensus rules. The difficulty is an approximation of that, because in practice it's a floating-point number, computed to some finite precision. Commented Dec 24, 2023 at 2:08
  • Thanks @Pieter, I have updated my answer -- but I am not sure if I improved it or just compounded my errors. If I am heading in the wrong direction here it might be best for me to just delete this answer. Commented Dec 24, 2023 at 10:36
  • @RedGrittyBrick I think I've confused you more. There are two separate processes: (1) the "bits" encoding that has limited precision, and which is applied during difficulty correction and (2) the conversion from target to difficulty which typically happens using floating-point arithmetic. (1) is a rounding operation, but I don't think it is in any way related to OP's question, and I think you should drop mention of it here. This rounding is done during the difficulty correction and the result is the actual network target. (2) is what is OP is asking about. Commented Dec 24, 2023 at 13:53
0

The Bitcoin wiki defines Difficulty as: difficulty = difficulty_1_target / current_target, where difficulty_1_target was the Target during the first Difficulty Epoch (the first 2016 blocks).

It might be more useful to refer to that as "relative difficulty", while 1/current_target is the absolute difficulty.

If yes, is it accurate to think about Difficulty as a type of proportion or ratio?

Yes, the relative difficulty is the ratio of the absolute difficulty to the original difficulty. The absolute difficulty is the ratio of the total number of possible hash outputs to the number of valid hashes.

And if it is a floating point number, what is its precision?

Uhhh... 256 bits?

"Floating point" isn't a type of number, it's a data type. A datatype is a method of representing a number, it's not the number itself. The difficulty is a rational number. It is uniquely defined by the target, which is a 256 bit number.

You can also, if you want, have a floating-point variable that represents this number. What precision that number has depends on what float you use. If you use a signed 32 bit float, it will have 24 bits of significant precision (as opposed to the exponent part). For 64 bits, it will have 53 bits. If you store it as float with fewer than 256 bits, then it will be rounded when it's converted to a float.

It might be useful to compare it to π. π is an irrational number, and has an infinite amount of precision. math.pi() is a float that represents π and has finite precision, and thus is a rounded version of π.

For more practical use, how would you represent this formula using Difficulty instead of the Target?

A block is valid if the total number of possible hash values divided by the actual hash value is greater than or equal to the absolute difficulty. Or, equivalently, if the actual hash value divided by the total number of possible hash values is less than or equal to the reciprocal of the absolute difficulty, or the actual hash value divided by the total number of possible hash values is less than or equal to the original difficulty divided by the current difficulty.

Not the answer you're looking for? Browse other questions tagged or ask your own question.