<p>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 <code>nBits</code> field of the block header.</p>
<p>The <code>nBits</code> field of the block header compresses the target from 256 bits into a 32 bits. A description of the format can be found <a href="https://developer.bitcoin.org/reference/block_chain.html#target-nbits" rel="nofollow noreferrer">here</a>.</p>
<p>Basically, the <code>nBits</code> field, when represented in Big endian, is split into two parts: the first byte, and the last three bytes. The formula for decompressing the <code>nBits</code> field is as follows: <code>(last three bytes) * 256 ^ ((first byte) - 3)</code>. This gives you a 256 bit integer that has the first 3 most significant bytes of the target.</p>

CC BY-SA 3.0
2018-02-28T23:29:46.443Z
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
CC BY-SA 4.0
2018-02-28T22:23:49.150Z
2021-03-01T17:08:01.920Z
2021-03-01T17:08:01.920Z
Ava Chow
<p>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.</p>
<p>First it creates the range of SHA256 powers of 2 thresholds for you to visualize the shear magnitude of these numbers.</p>
<p>Then the bitsToHex function is used to decompress &quot;bits&quot;.</p>
<p>Then decompressed &quot;bits&quot; are casted as a BigInt in order to get the integer used for hashing comparison.</p>
<p>Code comments should clarify the rest.</p>
<pre class="lang-javascript prettyprint-override"><code>console.log(&quot;\nSHA256 in powers of 2\n&quot;);

// from easy to hard
for(let i = 256n; i &gt;= 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, &quot;0&quot;);
  
  // beautify console
  console.log(`2n**${i}-1n D`.padStart(12, &quot; &quot;), dec.toLocaleString(&quot;en-US&quot;).padStart(103, &quot;.&quot;));
  console.log(`2n**${i}-1n H`.padStart(12, &quot; &quot;), `0x${hex}`.padEnd(116, &quot; &quot;));
}

/**
 * @dev Takes a Bitcoin block header property &quot;bits&quot; 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 &quot;bits&quot;.
  const target = (bits &amp; 0x007fffff) * 2 ** (8 * ((bits &gt;&gt;&gt; 24) - 3));
  // convert to 256bit hex
  return target.toString(16).padStart(64, &quot;0&quot;);
}

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

// Satoshi's genesis block &quot;bits&quot; A.K.A target hash
// for details see https://bitcoinexplorer.org/block-height/1#JSON
// &quot;bits&quot;: &quot;1d00ffff&quot;,
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 &quot;bits&quot; A.K.A target hash
// for details see https://bitcoinexplorer.org/block-height/776774#JSON
// &quot;bits&quot;: &quot;17073039&quot;,
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);
</code></pre>
<p>...console output:</p>
<pre class="lang-bash prettyprint-override"><code>genesis block target difficulty HEX: 00000000ffff0000000000000000000000000000000000000000000000000000
genesis block target difficulty DEC: 26959535291011309493156476344723991336010898738574164086137773096960n
current block target difficulty HEX: 0000000000000000000730390000000000000000000000000000000000000000
current block target difficulty DEC: 688509036841676372057001313638142781710850853198364672n
</code></pre>
<p>As you can see, difficulty has gotten a lot harder since genesis block.</p>

CC BY-SA 4.0
2023-02-17T00:45:34.547Z
2023-02-17T00:50:56.457Z
2023-02-17T00:50:56.457Z
suchislife
<p>This block:
<a href="https://blockchain.info/block/00000000000000000025c089d0a7b2bf6241888c4dd90ab7a4c4baa6a2823551" rel="noreferrer">https://blockchain.info/block/00000000000000000025c089d0a7b2bf6241888c4dd90ab7a4c4baa6a2823551</a></p>

<p>Shows difficulty at 3,007,383,866,429.73, and bits at 392009692.</p>

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

<pre><code>(log2(3007383866429.73) + 32) / 4) =&gt; 18.362911541451258
</code></pre>

<p>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?</p>

<difficulty>
understanding bits and difficulty in a block header
patrick
# understanding bits and difficulty in a block header

(Asked by: username_0 on 2018-02-28)

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?

**Tags:** difficulty


---

## 2 answers

### Answer by username_1 on 2018-02-28. Score: 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](https://developer.bitcoin.org/reference/block_chain.html#target-nbits).

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.

> **Comments:**
> **username_0**: 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.  

---

### Answer by username_2 on 2023-02-17. Score: 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.


---

