Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: DannyHamilton on December 17, 2022, 09:43:33 AM



Title: How to get <target> values for a block?
Post by: DannyHamilton on December 17, 2022, 09:43:33 AM
User HoBzY posted a question in this sub-forum, but it seems that the thread got locked (maybe on purpose, maybe on accident).
Here's a link to the original question:
https://bitcointalk.org/index.php?topic=5428781.0

How do you get 422681968 nbits out of 86564599.52 complexity?

https://www.blockchain.com/explorer/blocks/btc-testnet/2411287

Or how do you get the target value in general?

I sent him the following message, but I figured I'd include it here as well so there's an opportunity for others to correct me if I made a mistake in any of the math or formulas (it is almost 4am here and I haven't slept yet, so mistakes are vERY possible):

You provided nbits = 422681968
If you convert that integer value to hex, you get the 4 bytes (32 bits) that nbits is made up of:
422681968 = hex value 0x19319D70

Split the first byte off of nbits to get hex value 0x19 leaving behind the remaining 3 bytes of 0x319D70
These are the two pieces that are used to calculate the target hash value and the difficulty using this formula:
TARGET = 0x319D70 * 2(8(0x19 - 3))

To make the math a bit easier to understand, we can convert those hex values back to integers for the purposes of this discussion:
= 3251568 * 2(8(25-3))
= 3251568 * 2(8(22))
= 3251568 * 2176
= 3251568 * 95780971304118053647396689196894323976171195136475136
TARGET = 311438341301388531462158357898567283222551020627518185013248

Convert this value back to hex to get the hash value that the block hash is compared to:
TARGET = 0x00000000000000319D7000000000000000000000000000000000000000000000

You may notice that hex value of TARGET is 0x319D70 shifted to the left until the 31 is in the 25'th (0x19) byte from the right. That's what that formula above does. It takes the last 3 bytes (6 characters) from nbits, and shifts them to the left until the first byte of that block of 3 bytes is exactly the number of bytes from the right that is specified by the first byte of nbits.

Now that you have the TARGET, the DIFFICULTY is just:
DIFFICULTY = (0xFFFF * 2208)/TARGET

Let's convert the formula above into integers to make the math easier to follow:
(65535 * 2208)/TARGET

We have the integer value of TARGET above so:
(65535 * 2208)/311438341301388531462158357898567283222551020627518185013248
= 86564599.52 = DIFFICULTY



You didn't ask for it, but the calculation of the expected hash rate for a given difficulty is closely related, so I figured I'd share it.

The average number of hashes needed to find an acceptable hash at a given difficulty can be calculated as:
DIFFICULTY * 2256 / (0xFFFF * 2208)

Since the DIFFICULTY on the previous example was:
86564599.52

The average number of hashes that need to be calculated per block is:
= 86564599.52 * 2256 / (0xFFFF * 2208)
= 86564599.52 * 2256 / (65535 * 2208)
= 371797797113897361

Since blocks are intended to occur on average every 10 minutes (and there are 600 seconds in 10 minutes), this means that a DIFFICULTY of 86564599.52 would be set when the global average hash rate is:
371797797113897361 total hashes / 600 seconds = 619662995189828 hashes per second.

That's about 619.663 Thash/sec


Title: Re: How to get <target> values for a block?
Post by: odolvlobo on December 22, 2022, 08:27:13 PM
User HoBzY posted a question in this sub-forum, but it seems that the thread got locked (maybe on purpose, maybe on accident).
Here's a link to the original question:
https://bitcointalk.org/index.php?topic=5428781.0
How do you get 422681968 nbits out of 86564599.52 complexity?

I suspect that HoBzY's confusion stems from the term nBits.

The term comes from the name of the variable in the code and it does not stand for "number of bits" or "the bits associated with the value N".

Satoshi used a (mostly deprecated) variable naming scheme invented at Microsoft called Hungarian Notation (https://en.wikipedia.org/wiki/Hungarian_notation). In this scheme, the name of a variable is prefixed by a symbol that represents the variable's type. In the case of nBits, the prefix is n, which says that the variable is a signed integer.

So, the name nBits indicates that it represents "bits" in the form of an integer.

It is a poorly named variable in my opinion, since bits says nothing about what the variable represents and it isn't even an integer.


Title: Re: How to get <target> values for a block?
Post by: NotATether on December 23, 2022, 04:17:20 AM
I suspect that HoBzY's confusion stems from the term nBits.

The term comes from the name of the variable in the code and it does not stand for "number of bits" or "the bits associated with the value N".

Satoshi used a (mostly deprecated) variable naming scheme invented at Microsoft called Hungarian Notation (https://en.wikipedia.org/wiki/Hungarian_notation). In this scheme, the name of a variable is prefixed by a symbol that represents the variable's type. In the case of nBits, the prefix is n, which says that the variable is a signed integer.

So, the name nBits indicates that it represents "bits" in the form of an integer.

It is a poorly named variable in my opinion, since bits says nothing about what the variable represents and it isn't even an integer.

I always thought the "n" stood for number. I guess most programmers and even AIs (by consequence of analyzing these programmers' input) think of it that way as well.

Regardless, floats are not used for this kind of calculation by Bitcoin Core. I heard they have a wide 256-bit int type which they adapt to store all the precision of numbers without requiring any decimal places.