2

I did a terrible job of explaining it in the title so I'll explain here. Say the target hash to solve for a block is 00004aef... etc. does that mean that you can't solve the block if you get 00005fad (since 5 is more than 4 so technically you didn't get lower or equal to the hash)? Or is the only thing that matters in relation to the less or equal when it comes to solving the hash the amount of 0's you get?

Also, what if you get a letter after the 0's, for example 0000ba2... does that mean you need to get 0000a... or does it not matter?

Thanks.

1 Answer 1

10

The comparison used is numeric

These are numbers not strings of characters. You can see this by looking at the code in the 2009 main.cpp of the Bitcoin reference implementation:

        uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
        uint256 hash;

[...]

           if (hash <= hashTarget)
            {
                pblock->nNonce = tmp.block.nNonce;
                assert(hash == pblock->GetHash());

                    //// debug print
                    printf("BitcoinMiner:\n");
                    printf("proof-of-work found  \n  hash: %s  \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());

Note that if (hash <= hashTarget) is a numeric comparison. Both hash and hashTarget are type uint256 - an unsigned integer.

Numbers expressed in hexadecimal are still numbers

There is a choice of visual representations but the choice made does not change the underlying nature of the number or the way in which numbers are compared arithmetically or at a machine level in a computer.

Your example, 00005fad, is a number expressed in hexadecimal (base 16), the same number can be written in normal decimal (base 10) as 24493. Anyone unfamiliar with non-decimal representations such as hexadecimal, octal and binary can check this using something like the Windows 10 calculator, in the menu choose "Programmer Mode" then click on "hex" and enter 5fad - it shows the same value in several different representations.

Maybe this will make it clearer?

Item Binary Comments / Verdict
Target 000000001100
Block A hash 000000001101 Larger ∴ Failure
Block B hash 000000001011 Smaller ∴ Success

Even though the block hashes have the same number of leading zeroes, one is a failure and the other a success.

Leading zeroes

The notion that Bitcoin cares about the number of leading zeroes in, say, a hexadecimal representation, is a commonly repeated mistake (don't ask me how I know this).

If you insist on writing numbers with leading zeroes it is still obviously true that 000015 (fifteen) with four leading zeroes is smaller than 000150 (a hundred and fifty) with only three leading zeroes. It would however be a mistake to think that smaller numbers always have more leading zeroes. Both you and Bitcoin know that 000017 (seventeen) is smaller than 000019 (nineteen) even though both have the same number of leading zeroes.

It is true that a is less than b in exactly the same way that 7 is less than 8 or that 2 is less than 3. But it is probably a mistake to start comparing individual digits in a particular visual representation. The hash and hash targets are ordinary numbers (though large) that are compared in an ordinary way.

So where does this talk of leading zeroes come from? According to a prominent contributor:

hashcash, the original PoW system, had a "difficulty" that was actually the number of zero bits up front in the hash. Bitcoin's proof of work is based on it, but generalized to a big integer comparison.

See

Examples

Lets look at some recent blocks (most recent at top, reverse chronological order)

Block Mined on Difficulty Hash bits
669315 2021-02-06 02:48 21434395961349 0000000000000000000bbefe7b336aab05ef49c9c6ccd70a895b3cc4669ac924
669314 2021-02-06 02:36 21434395961349 0000000000000000000ae88c36b136ef612f0a0622bdf614854a7810e3f781cf
669313 2021-02-06 02:34 21434395961349 0000000000000000000acd9e8fd6512d3832e98a8c87d049afbd805abd44d8c2
669312 2021-02-06 02:25 21434395961349 0000000000000000000beb9d24f999168c79fa58394868f9fcc5367c28f137dc
669311 2021-02-06 02:22 20823531150112 00000000000000000004f29390852281bae27d3662f648020bb47cced0d883b8
669310 2021-02-06 02:18 20823531150112 00000000000000000000cd7ef96b5f6687c8b49df40c2dec2128adc39827707e
669309 2021-02-06 01:54 20823531150112 00000000000000000009d6c5902b0b8598f2ebd0fe076581b039fe789b4daca6
669308 2021-02-06 01:37 20823531150112 0000000000000000000be631fd1026989a86cf9dae421e7eca0f80d77b6bba5e

Notice that the difficulty increased after block 669311 but the number of leading zeroes in the hashes has not increased (not in hexadecimal and not in binary).

Implementations

If you want to see exact details you could look at early versions of the Bitcoin reference implementation in C++. However I would suggest instead looking at the current BTCD implementation in go-lang because that is well commented and, in my opinion, an easier language to read.

e.g. https://github.com/btcsuite/btcd/blob/master/chaincfg/params.go

    // TargetTimespan is the desired amount of time that should elapse
    // before the block difficulty requirement is examined to determine how
    // it should be changed in order to maintain the desired block
    // generation rate.
    TargetTimespan time.Duration

    // TargetTimePerBlock is the desired amount of time to generate each
    // block.
    TargetTimePerBlock time.Duration

and https://github.com/btcsuite/btcd/blob/master/blockchain/difficulty.go

    // Calculate new target difficulty as:
    //  currentDifficulty * (adjustedTimespan / targetTimespan)
    // The result uses integer division which means it will be slightly
    // rounded down.  Bitcoind also uses integer division to calculate this
    // result.
    oldTarget := CompactToBig(lastNode.bits)
    newTarget := new(big.Int).Mul(oldTarget, big.NewInt(adjustedTimespan))
    targetTimeSpan := int64(b.chainParams.TargetTimespan / time.Second)
    newTarget.Div(newTarget, big.NewInt(targetTimeSpan))

Calculating the hash target

See


2
  • So if more 0's aren't added every time the difficulty increases, what actually changes in regards to its difficult? It started at difficulty 1 with the genesis block and is now at over 21 trillion difficulty, yet has only went from 8 leading 0's to 19 leading 0's. What would have changed when the difficulty went from 1, to 1.18 for example?
    – L M
    Feb 10, 2021 at 1:36
  • @LM: See answers to questions in additional links appended to answer. Feb 10, 2021 at 11:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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