Author

Topic: Steps to translate blockheader to current block hash. (Read 2585 times)

newbie
Activity: 42
Merit: 0
Code:
$t=pack("H*" , $t);
$t=strrev(hex2bin(hash("sha256",hash("sha256",$t,true))))

Thank you theymos. That code worked beautifully.

The hex2bin wasn't necessary at all actually since the hash function will return raw/binary data if you add "true" to the third argument (which you had done).

And the strrev needed to be modified a bit (created my own reverse function) that reverses two chars at a time instead of 1. Don't know why I had to do that but I did.

Now how to get the blocknumber from the block_hash via bitcoind? (Not that I don't love blockexplorer.com, theymos!)
administrator
Activity: 5222
Merit: 13032
Code:
$t=pack("H*" , $t);
$t=strrev(hex2bin(hash("sha256",hash("sha256",$t,true))))
kjj
legendary
Activity: 1302
Merit: 1026
Yeah, don't use base_convert().  Big red warning on the man page.

Try hex2bin() instead.
newbie
Activity: 42
Merit: 0
You do concatenate them. Hash this:
Code:
010000001d8f4ec0443e1f19f305e488c1085c95de7cc3fd25e0d2c5bb5d0000000000009762547903d36881a86751f3f5049e23050113f779735ef82734ebf0b4450081d8c8c84db3936a1a334b035b

If you get a different first hash than I posted, then you're doing the hashing wrong. Maybe you forgot to convert this hexadecimal to binary...

Well, I must be doing the hashing wrong then :S

I have the following code on my php page:

Code:
$t = "010000001d8f4ec0443e1f19f305e488c1085c95de7cc3fd25e0d2c5bb5d0000000000009762547903d36881a86751f3f5049e23050113f779735ef82734ebf0b4450081d8c8c84db3936a1a334b035b";

echo hash("sha256", base_convert($t, 16, 2));

Basically it converts the string you provided into base 2 and then hashes the base 2 code with sha256.

And it shows: 60e05bd1b195af2f94112fa7197a5c88289058840ce7c6df9693756bc6250f55

So I did not get the first hash that you did (0cdb93c3412d2f30eb7d8dfd13d3142eaa8738c0de2337ac8a80c623715d9c07)

I have a feeling that my binary encoding is not correct. I am converting from base 16 to base 2.

Should I be using the PHP pack function perhaps?

If so, is the format "Hex string, low nibble first" or "Hex string, high nibble first"?
administrator
Activity: 5222
Merit: 13032
You do concatenate them. Hash this:
Code:
010000001d8f4ec0443e1f19f305e488c1085c95de7cc3fd25e0d2c5bb5d0000000000009762547903d36881a86751f3f5049e23050113f779735ef82734ebf0b4450081d8c8c84db3936a1a334b035b

If you get a different first hash than I posted, then you're doing the hashing wrong. Maybe you forgot to convert this hexadecimal to binary...
newbie
Activity: 42
Merit: 0
So you just concatenated all of those strings of text above theymos? In that order? Hashed them with sha256 and came up with that result?

I have answered my own question. Unfortunately that answer is "no".

Can somebody kindly show me just one full length string of text that I can hash twice and come up with a correct block hash?

I am sure if I could simply see the string and look at blockexplorer.com's raw data I could figure it out.
legendary
Activity: 1372
Merit: 1008
1davout
kjj
legendary
Activity: 1302
Merit: 1026
Thanks for that, guys!

So you just concatenated all of those strings of text above theymos? In that order? Hashed them with sha256 and came up with that result?

Can I ask a question now..? WHY are we constantly changing endianness? Is it safer cryptographically or something?

Perhaps I did find the correct hash already, I just didn't think so because it didn't start with zeros :S

Because byte ordering in memory is different from byte order on the network.  There are a lot of different multi-byte word storage schemes in use by different CPU families.  The network byte order is the common standard, and each machine is responsible for converting to and from it.  It gets trickier with hashing like this, since some parts of the header are bit strings, and other parts are machine words.

So, in bitcoin, we have the network byte order, the local machine byte order, and the byte order that makes the hashes work out like everyone else's, and they are all potentially different.
newbie
Activity: 42
Merit: 0
Thanks for that, guys!

So you just concatenated all of those strings of text above theymos? In that order? Hashed them with sha256 and came up with that result?

Can I ask a question now..? WHY are we constantly changing endianness? Is it safer cryptographically or something?

Perhaps I did find the correct hash already, I just didn't think so because it didn't start with zeros :S
administrator
Activity: 5222
Merit: 13032
The numbers are little-endian and the hashes have their endianness reversed in relation to the hash endianness on Bitcoin Block Explorer.

Here's a block that I converted previously:

Code:
01000000 version
1d8f4ec0443e1f19f305e488c1085c95de7cc3fd25e0d2c5bb5d000000000000 previous block
9762547903d36881a86751f3f5049e23050113f779735ef82734ebf0b4450081 Merkle root
d8c8c84d timestamp
b3936a1a bits
334b035b nonce

First hash is:
0cdb93c3412d2f30eb7d8dfd13d3142eaa8738c0de2337ac8a80c623715d9c07

Second hash is:
1195e67a7a6d0674bbd28ae096d602e1f038c8254b49dfe79d47000000000000

Reverse the endianness and you get:
http://blockexplorer.com/block/000000000000479de7df494b25c838f0e102d696e08ad2bb74066d7a7ae69511
full member
Activity: 195
Merit: 100
I have managed to extract the following information from this pushpool solution:

What parts of that information (and in what order?) needs to be hashed by way of sha256 twice to come up with that block's hash?

The data I have found seems to be correct for the block in question, but how do I come up with the block hash from that information alone? Or is it even possible?

 Smiley Looks like we are at the same stage of understanding bitcoin  Smiley

This sunday I am working on exactly the same issue. I found three aspects helpful:

1) The decription at https://en.bitcoin.it/wiki/Block_hashing_algorithm gives a rough idea

2) Reading the source of the satoshi implementation is...um...a good exercise in c++ fluency. However it is helpful for this question. The issue is: You have to get all the endian-nesses and all the sequences right. Satoshi implements an elaborate serialization concept and derives the has from there.

3) Probably the most helpful thing in this regards is the pastebin reference from (1) http://pastebin.com/n8UEGA86 It contains a c implementation of exactly the part you are looking into. I did not try it myself (but probably will do so eventually).

That said, let me make a general recommendation: Read the Satoshi implementation. It is not well documented, has a file structuring which is quite hard to read, uses boost library calls and has all kinds of twists and turns. However, it does pay off. Satoshi has numerous twists and turns and ideas and it takes a while to understand those. But it is not only every elegant (you can learn something about programming...)  -  it also contributes to the security and stability of the system.

I would recommend against php based implementations. And I would recommend against doing own implementations in bitcoin before you have completely digested the concepts in the Satoshi implementation. It took me 6 weeks of debug instrumentation, code commenting, code analysis and more - and as a result of this I ended up with this opinion.

Good luck.



newbie
Activity: 42
Merit: 0
I have managed to extract the following information from this pushpool solution:

Code:
    [original_solution] => 0000000105d3571220ef5f87c6ac0bc8bf5b33c02a9e6edf83c84d840109592c0000000027523728e15f5fe1ac507bff92499eada4af8a0c485d5178e3f96568c18f84994e0e4efc1c0175d646a91ad4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    [block_header] => 0000000105d3571220ef5f87c6ac0bc8bf5b33c02a9e6edf83c84d840109592c0000000027523728e15f5fe1ac507bff92499eada4af8a0c485d5178e3f96568c18f84994e0e4efc1c0175d646a91ad4
    [previous_block_hash] => 000000000109592c83c84d842a9e6edfbf5b33c0c6ac0bc820ef5f8705d35712
    [version] => 00000001
    [merkle_root] => c18f8499e3f96568485d5178a4af8a0c92499eadac507bffe15f5fe127523728
    [timestamp] => 4e0e4efc
    [timestamp_decimal] => 1309560572
    [bits_compact_target] => 1c0175d6
    [bits_data_decimal] => 469857750
    [nonce] => 46a91ad4
    [nonce_decimal] => 1185487572

What parts of that information (and in what order?) needs to be hashed by way of sha256 twice to come up with that block's hash?

I have checked out all of the data here: http://blockexplorer.com/testnet/rawblock/0000000000833b13e1d753f4b1d4d18e3a7bde2c2efb8deebaa0b868e3e4dcdf

The data I have found seems to be correct for the block in question, but how do I come up with the block hash from that information alone? Or is it even possible?
newbie
Activity: 42
Merit: 0
I am in the process of writing some php code that will create the current block hash from a block's header.

I am able to find the previous block hash by reversing endianness on the 64 characters after the first 8 characters in the block's header.

Do I have to do the same with the next 64 characters of the merkle root? Recombine everything and then hash it twice with sha256 to determine the current block's hash?

I am starting from a pushpool "solution".
Jump to: