<p><strong>The nonce needs to be 8 hex digits</strong> but <code>printf %x</code> only generates the minimum digits needed for the value, which for 0 is only 1 digit. (The same is true of other numeric conversions <code>%d %i %u %o</code> also.) You need to use <code>%08x</code> to force an 8-hexit value:</p>
<pre><code>ver=$(printf 20000000 | tac -rs ..)
prev=$(printf 4776b1ccad27e2de9ccbdc5bf4ad4d972a89e27a020db1f7b59abb857d77f3be | tac -rs .. )
mkl=$(printf 23b4600b467f18ef0ec18bd73a9b921077486cf67c44c912de114888db184bf9 | tac -rs .. )
time=$(printf %x 1599147354 | tac -rs .. )
#should be %08x if any timestamp can be before mid-1978
bits=$(printf 207fffff | tac -rs .. )
nonce=$(printf %08x 0 | tac -rs .. )
printf $ver$prev$mkl$time$bits$nonce | xxd -r -p | openssl sha256 -binary |
 openssl sha256 | awk '{print $2}' | tac -rs..

--&gt;
4221d8b10b0a7eb5e050337c76819abf71113f17e266e88cb12df4bf5ce24b55
</code></pre>
<p>Other changes:</p>
<ul>
<li><p>most of your items didn't even have a newline, and for those that did it is discarded by the <code>tac -rs..</code>, and so none of them need <code>|tr -d '\n'</code> -- although for consistency I removed the <code>\n</code> in some <code>printf</code> formats, and changed the <code>echo</code> (which adds newline by default) to <code>printf</code> (which doesn't). (And even if the/some/any items did contain newline, if you doublequote the final <code>printf &quot;$ver...$nonce&quot;</code> so they get treated as data and not wordsplits, the <code>xxd -r -p</code> will discard them as if they weren't there at all.)</p>
</li>
<li><p>I used the newer syntax <code>$( )</code> for process substitution instead of the older backticks (which I can't show in Stack markdown!) because in many cases it has advantages, although not here specifically, and I like to be consistent. (There are dozens of Qs about this on other Stacks.)</p>
</li>
<li><p>I used <code>openssl</code> instead of <code>sha256sum</code> because I have it on my systems and it's a little easier.</p>
</li>
</ul>
<p>This wasn't a problem on mainnet and testnet, at least for most blocks, because they have difficulty high enough that the nonce value will be at least 29 bits most of the time.</p>

CC BY-SA 4.0
2020-09-04T09:14:30.910Z
thanks for your time and thanks for your super reply!
monkeyUser
CC BY-SA 4.0
2020-09-04T09:42:35.617Z
I put the script on sh file, for that reason I need `| tr -d '\n'`.
Do you have any advice to avoid | tr -d '\n' in file sh?
monkeyUser
CC BY-SA 4.0
2020-09-06T19:01:26.780Z
The code I posted _is_ in a script file (on my CentOS test system) and works fine without `tr -d '\n'` for the reasons I explained -- what makes you think it's needed?
dave_thompson_085
CC BY-SA 4.0
2020-09-04T05:42:48.017Z
2020-09-04T05:42:48.017Z
dave_thompson_085
<p>I'm able to calculate the block hash in mainnet and testnet, but I don't get the right hash in regtest.
I mint +3000 blocks and I get the block with height 3000</p>
<pre><code>bitcoin-cli getblock $(bitcoin-cli getblockhash 3000)                                   

{
  &quot;hash&quot;: &quot;4221d8b10b0a7eb5e050337c76819abf71113f17e266e88cb12df4bf5ce24b55&quot;,
  &quot;confirmations&quot;: 502,
  &quot;strippedsize&quot;: 215,
  &quot;size&quot;: 251,
  &quot;weight&quot;: 896,
  &quot;height&quot;: 3000,
  &quot;version&quot;: 536870912,
  &quot;versionHex&quot;: &quot;20000000&quot;,
  &quot;merkleroot&quot;: &quot;23b4600b467f18ef0ec18bd73a9b921077486cf67c44c912de114888db184bf9&quot;,
  &quot;tx&quot;: [
    &quot;23b4600b467f18ef0ec18bd73a9b921077486cf67c44c912de114888db184bf9&quot;
  ],
  &quot;time&quot;: 1599147354,
  &quot;mediantime&quot;: 1599147353,
  &quot;nonce&quot;: 0,
  &quot;bits&quot;: &quot;207fffff&quot;,
  &quot;difficulty&quot;: 4.656542373906925e-10,
  &quot;chainwork&quot;: &quot;0000000000000000000000000000000000000000000000000000000000001772&quot;,
  &quot;nTx&quot;: 1,
  &quot;previousblockhash&quot;: &quot;4776b1ccad27e2de9ccbdc5bf4ad4d972a89e27a020db1f7b59abb857d77f3be&quot;,
  &quot;nextblockhash&quot;: &quot;121512fc6bc1395ada64a6c63ba2c2955ad9cc240a1fc0282b95cf2c2651b381&quot;
}
</code></pre>
<p>Now I save the values in env variable</p>
<pre><code> ver=`printf 20000000 | tac -rs ..| tr -d '\n'`
 prev=`printf 4776b1ccad27e2de9ccbdc5bf4ad4d972a89e27a020db1f7b59abb857d77f3be | tac -rs .. | tr -d '\n'`
 mkl=`printf 23b4600b467f18ef0ec18bd73a9b921077486cf67c44c912de114888db184bf9 | tac -rs .. | tr -d '\n'`
 time=`printf '%x\n' 1599147354 | tac -rs .. | tr -d '\n'`
 bits=`echo 207fffff | tac -rs .. | tr -d '\n'`
 nonce=`printf '%x\n' 0 | tac -rs .. | tr -d '\n'`
</code></pre>
<p>After that I can concat and get the little endian representation</p>
<pre><code>printf $ver$prev$mkl$time$bits$nonce | xxd -r -p | sha256sum -b | xxd -r -p | sha256sum -b | awk '{printf $1}' | tac -rs ..
</code></pre>
<p>The result is: <code>09665bcb63b6c279948f93937669bf1c8f36cffda0646180ba523847cb642384</code>. the same operations in mainnet and testnet works properly.</p>

<bitcoin-core><mining-theory><hash><regtest>
Calculate block hash is different in regtest?
monkeyUser
# Calculate block hash is different in regtest?

(Asked by: username_0 on 2020-09-03)

I'm able to calculate the block hash in mainnet and testnet, but I don't get the right hash in regtest.
I mint +3000 blocks and I get the block with height 3000
bitcoin-cli getblock $(bitcoin-cli getblockhash 3000)                                   

{
  "hash": "4221d8b10b0a7eb5e050337c76819abf71113f17e266e88cb12df4bf5ce24b55",
  "confirmations": 502,
  "strippedsize": 215,
  "size": 251,
  "weight": 896,
  "height": 3000,
  "version": 536870912,
  "versionHex": "20000000",
  "merkleroot": "23b4600b467f18ef0ec18bd73a9b921077486cf67c44c912de114888db184bf9",
  "tx": [
    "23b4600b467f18ef0ec18bd73a9b921077486cf67c44c912de114888db184bf9"
  ],
  "time": 1599147354,
  "mediantime": 1599147353,
  "nonce": 0,
  "bits": "207fffff",
  "difficulty": 4.656542373906925e-10,
  "chainwork": "0000000000000000000000000000000000000000000000000000000000001772",
  "nTx": 1,
  "previousblockhash": "4776b1ccad27e2de9ccbdc5bf4ad4d972a89e27a020db1f7b59abb857d77f3be",
  "nextblockhash": "121512fc6bc1395ada64a6c63ba2c2955ad9cc240a1fc0282b95cf2c2651b381"
}

Now I save the values in env variable
 ver=`printf 20000000 | tac -rs ..| tr -d '\n'`
 prev=`printf 4776b1ccad27e2de9ccbdc5bf4ad4d972a89e27a020db1f7b59abb857d77f3be | tac -rs .. | tr -d '\n'`
 mkl=`printf 23b4600b467f18ef0ec18bd73a9b921077486cf67c44c912de114888db184bf9 | tac -rs .. | tr -d '\n'`
 time=`printf '%x\n' 1599147354 | tac -rs .. | tr -d '\n'`
 bits=`echo 207fffff | tac -rs .. | tr -d '\n'`
 nonce=`printf '%x\n' 0 | tac -rs .. | tr -d '\n'`

After that I can concat and get the little endian representation
printf $ver$prev$mkl$time$bits$nonce | xxd -r -p | sha256sum -b | xxd -r -p | sha256sum -b | awk '{printf $1}' | tac -rs ..

The result is: 09665bcb63b6c279948f93937669bf1c8f36cffda0646180ba523847cb642384. the same operations in mainnet and testnet works properly.

**Tags:** bitcoin-core, mining-theory, hash, regtest


---

## 1 answers

### Answer by username_1 on 2020-09-04. Score: 0 | Accepted answer

The nonce needs to be 8 hex digits but printf %x only generates the minimum digits needed for the value, which for 0 is only 1 digit. (The same is true of other numeric conversions %d %i %u %o also.) You need to use %08x to force an 8-hexit value:
ver=$(printf 20000000 | tac -rs ..)
prev=$(printf 4776b1ccad27e2de9ccbdc5bf4ad4d972a89e27a020db1f7b59abb857d77f3be | tac -rs .. )
mkl=$(printf 23b4600b467f18ef0ec18bd73a9b921077486cf67c44c912de114888db184bf9 | tac -rs .. )
time=$(printf %x 1599147354 | tac -rs .. )
#should be %08x if any timestamp can be before mid-1978
bits=$(printf 207fffff | tac -rs .. )
nonce=$(printf %08x 0 | tac -rs .. )
printf $ver$prev$mkl$time$bits$nonce | xxd -r -p | openssl sha256 -binary |
 openssl sha256 | awk '{print $2}' | tac -rs..

-->
4221d8b10b0a7eb5e050337c76819abf71113f17e266e88cb12df4bf5ce24b55

Other changes:

most of your items didn't even have a newline, and for those that did it is discarded by the tac -rs.., and so none of them need |tr -d '\n' -- although for consistency I removed the \n in some printf formats, and changed the echo (which adds newline by default) to printf (which doesn't). (And even if the/some/any items did contain newline, if you doublequote the final printf "$ver...$nonce" so they get treated as data and not wordsplits, the xxd -r -p will discard them as if they weren't there at all.)

I used the newer syntax $( ) for process substitution instead of the older backticks (which I can't show in Stack markdown!) because in many cases it has advantages, although not here specifically, and I like to be consistent. (There are dozens of Qs about this on other Stacks.)

I used openssl instead of sha256sum because I have it on my systems and it's a little easier.


This wasn't a problem on mainnet and testnet, at least for most blocks, because they have difficulty high enough that the nonce value will be at least 29 bits most of the time.

> **Comments:**
> **username_0**: thanks for your time and thanks for your super reply!  
> **username_0**: I put the script on sh file, for that reason I need `| tr -d '\n'`. Do you have any advice to avoid | tr -d '\n' in file sh?  
> **username_1**: The code I posted _is_ in a script file (on my CentOS test system) and works fine without `tr -d '\n'` for the reasons I explained -- what makes you think it's needed?  

---

