Calculate block hash is different in regtest? 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)                                   

{
  &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;
}

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.
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..

--&gt;
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 &quot;$ver...$nonce&quot; 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.