0

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.

0

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.

| improve this answer | |
  • thanks for your time and thanks for your super reply! – monkeyUser Sep 4 at 9:14
  • 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 Sep 4 at 9:42
  • 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 Sep 6 at 19:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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