5

From Bitcoin's whitepaper I've gathered that the hash of a block must start with a certain number of zeroes. And that this number of zeroes is adjusted every 2 weeks. Consequently the hash target is a power of two.

Requiring an extra zero for the hash function will divide the hash target by 2.

With that being said, in another question on the exchange (How is difficulty calculated?) it appears that the difficulty can be multiplied by fractions (e.g. 40%).

Does that mean that the hash targets aren't necessarily powers of 2? Or is the target rounded to the nearest power of 2?

4
  • I'm a little confused about your question. Why would the hash target be a multiple of 2? Leading zeros are 0000xxx not xxx0000.
    – robert
    Apr 24 at 20:07
  • @robert OP's assumption isn't correct, but if it were, the hash target would be a power of 16 (due to the hexidecimal encoding used for block hashes), not 2.
    – chytrik
    Apr 28 at 20:26
  • @chytrik In the whitepaper (Section 4) they talk specifically about bits (zeroes or ones), not digits or other hex: "[...] the block's hash the required zero bits" So if one is to refer to the whitepaper, the target would be indeed a power of 2.
    – Fred
    Apr 28 at 21:18
  • 1
    @Fred ah! That is true, I’d forgotten about that, sorry. Of note: David Harding has put together a page listing some ‘whitepaper errata’, which includes the ‘leading zero bits’ hash target error, see: gist.github.com/harding/…
    – chytrik
    Apr 28 at 23:08
16

Contrary to popular belief, the target is not actually based on the number of leading zeroes. This is a major simplification that is used to get the general idea across, but is not actually how the code works. Instead, the target is just a number that is adjusted by the ratio between the actual time between blocks and the expected time between blocks (with an off by one error which actually causes it to not quite work as expected). So the targets are not necessarily multiples of 2.

There is one additional caveat - the new difficulty can only be at least a quarter of and at most 4 times more than the old difficulty. The multiplier (the ratio between times) thus must be between 1/4 and 4.

2
  • So basically it isn't specified anywhere, except in the code? Because the whitepaper talks about the number of zeroes - without giving any precise implementation details ...
    – Fred
    Apr 24 at 22:39
  • 2
    @Fred Yes. The whitepaper leaves out a lot of specific implementation details that you can only learn about by reading the code.
    – Andrew Chow
    Apr 24 at 23:03
14

As Andrew's answer points out, the 'number of leading zeros' is just a simplification, so I thought I would give an example to more concretely illustrate this:

Block hashes are usually represented in hex format, which utilizes the character set [0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f]. But for simplicity, we can just use a base 10 number set [0,1,2,3,4,5,6,7,8,9], the exact same principles apply.

The block hash is the output of a SHA256 operation, so it is a 256-bit number, which is a very large number. This means the output of the SHA256 operation will be a number in the range of 0 to 2^256. Again though, for simplicity sake we can consider a much smaller number range in our example, so we'll use the range 0 to 1,000,000 instead.

Now, lets imagine that the hash target is ≤500, thus any otherwise valid block input that gives an output of 0000500 or less would be considered a valid block. Lets also imagine that the hash target changes to be ≤450 for the next difficulty period, making any output of 0000450 or less a valid block.

Notice that these two targets would "require the same number of leading zeros", but a block that hashes to 0000475 would only be valid in the earlier difficulty period, and not the later. This is because the hash target is a specific number, the number of leading zeros is only a simplification/rough proxy for this.

1
  • Very nice simple explanation, thanks. Kind of reminds me of arithmetic coding - treat the entire 256-bit hash as a float (mantissa) between [0.0 .. 1.0) and set the target to some float value ...
    – davidbak
    Apr 22 at 0:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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