4

This block: https://blockchain.info/block/00000000000000000025c089d0a7b2bf6241888c4dd90ab7a4c4baa6a2823551

Shows difficulty at 3,007,383,866,429.73, and bits at 392009692.

If I want to see how many zeros need to be in the hash, I believe I can just do:

(log2(3007383866429.73) + 32) / 4) => 18.362911541451258

Which is correct.. But how does bits come from difficulty? How can I calculate the number of zeros from the bits instead of the difficulty?

2 Answers 2

8

Contrary to popular belief, Bitcoin's proof of work is not actually based on the number of zeroes. Rather the block hash, when interpreted as a 256 bit integer, must be less than the target value. The target value is what actually determines the difficulty. The target value is represented in a compact form in the nBits field of the block header.

The nBits field of the block header compresses the target from 256 bits into a 32 bits. A description of the format can be found here.

Basically, the nBits field, when represented in Big endian, is split into two parts: the first byte, and the last three bytes. The formula for decompressing the nBits field is as follows: (last three bytes) * 256 ^ ((first byte) - 3). This gives you a 256 bit integer that has the first 3 most significant bytes of the target.

1
  • I see.. I am working on a project that depicts bitcoin mining at a high level, and so I want my example data to look as accurate as possible. I am looking for some kind of formula where I can say: given difficulty X, the hash that would solve this should start with Y zeros.. And actually my project has a small amount of screen real estate available, so I'd prefer if I could literally use an extremely low difficulty like "25" for example, and have that (as realistically as possible) equate to a hash with a small-ish number of leading 0s.
    – patrick
    Feb 28, 2018 at 23:29
0

I've created some javascript code as a result of my research in trying to understand how target difficulty works. It seems a good idea to share after finding this post.

First it creates the range of SHA256 powers of 2 thresholds for you to visualize the shear magnitude of these numbers.

Then the bitsToHex function is used to decompress "bits".

Then decompressed "bits" are casted as a BigInt in order to get the integer used for hashing comparison.

Code comments should clarify the rest.

console.log("\nSHA256 in powers of 2\n");

// from easy to hard
for(let i = 256n; i >= 0n; i-=4n) {
  // calc decimal representaion
  const dec = BigInt(2n**i-1n);
  // calc hexadecimal representation
  const hex = BigInt(2n**i-1n).toString(16).padStart(64, "0");
  
  // beautify console
  console.log(`2n**${i}-1n D`.padStart(12, " "), dec.toLocaleString("en-US").padStart(103, "."));
  console.log(`2n**${i}-1n H`.padStart(12, " "), `0x${hex}`.padEnd(116, " "));
}

/**
 * @dev Takes a Bitcoin block header property "bits" and converts it into a 256-bit hex.
 * 
 * The bits property of a Bitcoin block header is a 32-bit integer that 
 * represents the difficulty target for mining that block. 
 * The first three bytes of the bits value are the exponent (in base 256) of
 * the difficulty target, and the last byte is the coefficient.
 * To convert the bits value into a 256-bit hex, we need to extract the 
 * exponent and coefficient from the bits value and calculate the target value. 
 * Then we can convert the target value into a 64-character hex string.
 * 
 */
function bitsToHex(bits) {
  // calc target value from compressed "bits".
  const target = (bits & 0x007fffff) * 2 ** (8 * ((bits >>> 24) - 3));
  // convert to 256bit hex
  return target.toString(16).padStart(64, "0");
}

// console spacer
console.log("\nBitcoin Target Difficulty\n");

// Satoshi's genesis block "bits" A.K.A target hash
// for details see https://bitcoinexplorer.org/block-height/1#JSON
// "bits": "1d00ffff",
const genesisTargetDifficultyHEX = bitsToHex(0x1d00ffff);
const genesisTargetDifficultyDEC = BigInt(`0x${genesisTargetDifficultyHEX}`);
console.log('genesis block target difficulty HEX:', genesisTargetDifficultyHEX);
console.log('genesis block target difficulty DEC:', genesisTargetDifficultyDEC);

// Bitcoins's current block "bits" A.K.A target hash
// for details see https://bitcoinexplorer.org/block-height/776774#JSON
// "bits": "17073039",
const currentTargetDifficultyHEX = bitsToHex(0x17073039);
const currentTargetDifficultyDEC = BigInt(`0x${currentTargetDifficultyHEX}`);
console.log('current block target difficulty HEX:', currentTargetDifficultyHEX);
console.log('current block target difficulty DEC:', currentTargetDifficultyDEC);

...console output:

genesis block target difficulty HEX: 00000000ffff0000000000000000000000000000000000000000000000000000
genesis block target difficulty DEC: 26959535291011309493156476344723991336010898738574164086137773096960n
current block target difficulty HEX: 0000000000000000000730390000000000000000000000000000000000000000
current block target difficulty DEC: 688509036841676372057001313638142781710850853198364672n

As you can see, difficulty has gotten a lot harder since genesis block.

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.