9

I just started studying bitcoin.

I would like to be able to download a single block from the Bitcoin network.

This should be an old block, already mined, and which I can know the nonce.

Then I would like, via bash linux commands, to verify that such nonce solves the block.

Thanks to a question asked here, I know I could look at

https://blockchain.info/block-height/474044?format=json

However this is JSON, I imagine I can't use it to verify the nonce.

Hence my question is:

  1. How can I download a block?
  2. What is the file format of such block?
  3. At what bytes start the nonce field I can increment, for example with a Python script?
  4. Once I get to put the right (and known :) ) nonce how can verify that the block is solved? I mean, its hash should starts with lots of zeros, could I treat the block as a string and pass directly to the python hashlib function?

Thanks in advance.

5 Answers 5

12

However this is JSON, I imagine I can't use it to verify the nonce.

You can. You can build the block header using the data at the beginning of the JSON object and then hash that. Of course it would be easier to get the block hex, which you can get by going to the block hash on blockchain.info and appending ?format=hex to the url. For example, for the block height you linked, the hex of that block can be found here: https://blockchain.info/rawblock/000000000000000000ff265a641721e79bbc559d8b0e4894332732109f1a3383?format=hex

How can I download a block?

Get the block hex. That is the raw data for the block itself. You could make it a file by putting the hex in a hex editor or just save the hex as a string in a text file.

What is the file format of such block?

Blocks don't have a file format. They are just blobs of binary data which you will need to understand how to parse. https://bitcoin.org/en/developer-reference#serialized-blocks explains the block serialization.

At what bytes start the nonce field I can increment, for example with a Python script?

The part that is hashed is the block header, the first 80 bytes of the block. The nonce is the last 4 bytes of that header. You can read about the format of the block header here: https://bitcoin.org/en/developer-reference#block-headers

Once I get to put the right (and known :) ) nonce how can verify that the block is solved? I mean, its hash should starts with lots of zeros, could I treat the block as a string and pass directly to the python hashlib function?

No. The block header is not a string. It is a blob of binary data. In python, the easiest thing to do is to make it a bytes object and then pass it in to hashlib.

If a block's proof of work is valid (note that does not mean the block itself is valid), then after you hash it with SHA256 Double, you treat the output as an integer and compare it to the nBits field of the header. The nBits field a 4 byte field beginning 8 bytes from the end of the header and is a compact representation of the target. You can read about how to interpret it here: https://bitcoin.org/en/developer-reference#target-nbits. The block hash (treated as a large integer) must be less than the target specified by the nBits field.

1
  • You beat me to it.
    – Penquin
    Jul 3, 2017 at 17:51
5
  1. Download a block is easy! Here is a link to an online explorer with a specific block, for your experimental purposes I suggest storing the block in its raw hex format (or binary).
  2. Blocks don't have a predefined file format. The Bitcoin protocol enforces a format to the blocks, but how they are stored locally doesn't matter. However Bitcoin Core stores its block in blkxxxxx.dat files.. The LevelDB (.ldb) files contain metadata and indexing information about the bitcoin blocks stored in the blkxxxxx.dat files. It's up to each different Bitcoin implementation to decide for themselves how to store the blocks.
  3. Try manually decoding the block in the URL I posted above. This page contains all the hints you need to get it working. The nonce is 4 bytes and is preceded by 76 bytes of data, so 77 byte to byte 80 is the nonce. Notable, also at the end of the blockheader (= the first 80 bytes).

Thanks to the comment @Hypocritus for pointing out a mistake.

1
  • 1
    Needed to correct Penguin's 2. response above. Bitcoin Core stores bitcoin blocks in .dat files (blkxxxxx.dat). The LevelDB (.ldb) files contain metadata and indexing information about the bitcoin blocks stored in the blkxxxxx.dat files. en.bitcoin.it/wiki/Data_directory
    – Hypocritus
    May 20, 2018 at 3:31
3

Here's how you can check the hash from the command line. You'll want the xxd package; the command xxd -r -p converts a hex string to its raw equivalent (e.g. the two bytes "5a" goes to the single byte 0x5a).

wget -q -O - 'https://blockchain.info/block/000000000000000000ff265a641721e79bbc559d8b0e4894332732109f1a3383?format=hex' \
|xxd -r -p |head -c 80 |sha256sum - |cut -d ' ' -f 1 \
|xxd -r -p |sha256sum - |cut -d ' ' -f 1 |rev
0
1

This as a "comment" to Nate's proposal (adding a comment destroys the newlines and code formatting).

If there is no xxd, you can go this way:

 cat myfile_with_hexchars | tr [:upper:] [:lower:] > myfile_with_hexcodes
 result=$( cat myfile_with_hexcodes | sed 's/[[:xdigit:]]\{2\}/\\x&/g' )
 printf $result > myfile_hex

any hex editor will help to see result, e.g.:

 hexdump -C myfile_hex
3
  • I think this should rather be a full answer, or an edit to Nate's answer to add it. If you want to make it a full answer, I think you'd only need to recreate a small portion of Nate's post, you could start out with something along the lines of "Inspired by Nate's answer, you can use the following code to solve the same problem without installing the package xxd…"
    – Murch
    Oct 22, 2017 at 21:07
  • UUOC, and you don't need the tr; [:xdigit:] and printf \x handle both cases. In fact this only works right if the input is entirely hex pairs so you can just do printf $(sed 's/../\\&/g' <hexfile) >outfile Oct 25, 2017 at 6:49
  • thx, I could get it to work this way: printf $(sed 's/[[:xdigit:]]\{2\}/\\x&/g' <hexfile) Nov 1, 2017 at 7:54
1

The blockchain.com link given in the accepted answer no longer works.

From the published API

https://blockchain.info/api/blockchain_api

The URL you need to download a HEX formatted block is as follows.

https://blockchain.info/rawblock/$block_hash

This gives you a hex formatted file that can be converted to binary with xxd -r -p as above.

The bitcoin block header is quite straightforward.

https://en.bitcoin.it/wiki/Protocol_documentation#Block_Headers | Size | Desc | Type | Comments | | --- | -- | -- | -- | | 4 | version | int32_t | Block version information (note, this is signed) | | 32 | prev_block | char[32] | The hash value of the previous block this particular block references | | 32 | merkle_root | char[32] | The reference to a Merkle tree collection which is a hash of all transactions related to this block | | 4 | timestamp | uint32_t | A timestamp recording when this block was created (Will overflow in 2106[2]) | | 4 | bits | uint32_t | The calculated difficulty target being used for this block | | 4 | nonce | uint32_t | The nonce used to generate this block… to allow variations of the header and compute different hashes |

To view the nonce:

>>> data = open('block.bin', 'rb').read()
>>> nonce = data[4+32+32+4+4:][:4]
>>> nonce.hex()
'6d1daf7b'

To calculate the hash code for the header:

>>> import hashlib
>>> from binascii import unhexlify, hexlify
>>> header = data[:4+32+32+4+4+4]
>>> hash = hashlib.sha256(hashlib.sha256(header).digest()).digest()
>>> hexlify(hash).decode("utf-8")
'83331a9f1032273394480e8b9d55bc9be72117645a26ff000000000000000000'
>>> hexlify(hash[::-1]).decode("utf-8")
'000000000000000000ff265a641721e79bbc559d8b0e4894332732109f1a3383'

This above is from:

https://en.bitcoin.it/wiki/Block_hashing_algorithm

The following blogpost by Andrej Karpathy's has more information about how you can go about verifying the transactions in the block.

https://karpathy.github.io/2021/06/21/blockchain/

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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