Download single and specific block for study purposes

4

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.

f126ck

Posted 2017-07-03T15:31:49.283

Reputation: 205

Answers

8

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

Andrew Chow

Posted 2017-07-03T15:31:49.283

Reputation: 40 910

You beat me to it.Penquin 2017-07-03T17:51:54.473

3

  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.

Penquin

Posted 2017-07-03T15:31:49.283

Reputation: 609

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. https://en.bitcoin.it/wiki/Data_directory

Hypocritus 2018-05-20T03:31:21.137

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

Nate Eldredge

Posted 2017-07-03T15:31:49.283

Reputation: 21 420

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

pebwindkraft

Posted 2017-07-03T15:31:49.283

Reputation: 4 568

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 2017-10-22T21:07:10.403

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) >outfiledave_thompson_085 2017-10-25T06:49:03.270

thx, I could get it to work this way: printf $(sed 's/[[:xdigit:]]{2}/\x&/g' <hexfile)pebwindkraft 2017-11-01T07:54:14.910