开发者

(bitcoin) Calculate hash from getwork function - how to do it?

开发者 https://www.devze.com 2023-03-10 22:54 出处:网络
when I call getwork on my bitcoind server, I get the following: ./bitcoind getwork { \"midstate\" : \"695d56ae173bbd0fd5f51d8f7753438b940b7cdd61eb62039036acd1af5e51e3\",

when I call getwork on my bitcoind server, I get the following:

./bitcoind getwork
{
    "midstate" : "695d56ae173bbd0fd5f51d8f7753438b940b7cdd61eb62039036acd1af5e51e3",
    "data" : "000000013d9dcbbc2d120137c5b1cb1da96bd45b249fd1014ae2c2b400001511000000009726fba001940ebb5c04adc4450bdc0c20b50db44951d9ca22fc5e75d51d501f4deec2711a1d932f00000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000",
    "hash1" : "00000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000010000",
    "target" : "00000000000000000000000000000000000000000开发者_运维问答000002f931d000000000000"
}

This protocol does not seem to be documented. How do I compute the hash from this data. I think that this data is in little endian. So the first step is to convert everything to big endian? Once that is done, I calculate the sha256 of the data. The data can be divided in two chuncks of 64 bytes each. The hash of the first chuck is given by midstate and therefore does not have to be computed.

I must therefore hash the chunck #2 with sha256, using the midstate as the initial hash values. Once that is done, I end up with a hash of chunk 2, which is 32 bytes. I calculate the hash of this chunk one more time to get a final hash.

Then, do I convert everything to little endian and submit the work?

What is hash1 used for?


The hash calculation is documented at Block hashing algorithm. Start there for the relatively simple basics. The basic data structures are documented in Protocol specification - Bitcoin Wiki. Note that the protocol definition (and the definition of work) more or less assumes that SHA-256 hashes are 256-bit little-endian values, rather than big-endian as the standard implies. See also

Getwork is more complicated and runs into more serious endian/byte ordering confusion.

First note that the getwork API is optimized to speed up the initial steps of mining. The midstate and hash1 values are for these performance optimizations and can be ignored. Just look at the "data". And when a standard sha256 implementation is used, only the first 80 bytes (160 hex characters) of the "data" are hashed.

Unfortunately, the JSON data presented in the getwork data structure has different endian characteristics than what is needed for hashing in the block example above.

They all say to go to the source for the answer, but the C++ source can be big and confusing. A simple alternative is the poold.py code. There is discussion of it here: New mining pool for testing. You only need to look at the first few lines of the "checkwork" routine, and the "bufreverse" and "bytereverse" functions, to get the byte ordering right. In the end it is just a matter of doing a reversal of the bytes in each 32-bit segment of the data. Yes - very odd. But endian issues are tricky and can end up that way....

Some other helpful information on the way "getwork" works can be found in discussions at:

  • Do I understand header hashing?
  • Stupid newbie question about the nonce

Note that finding the signal to noise in the original Bitcoin forum is getting very hard, and there is currently an Area51 proposal for a StackExchange site for Bitcoin and Crypto Currency in general. Come join us!


It sounds right, there is a script in javascript that do calculate the hash but I do not fully understand it so I don't know, maybe you understand it better if you look.

this.tryHash = function(midstate, half, data, hash1, target, nonce){  
    data[3] = nonce;
    this.sha.reset();

    var h0 = this.sha.update(midstate, data).state;   // compute first hash
    for (var i = 0; i < 8; i++) hash1[i] = h0[i];   // place it in the h1 holder
    this.sha.reset();                 // reset to initial state
    var h = this.sha.update(hash1).state;       // compute final hash
    if (h[7] == 0) {
      var ret = [];
      for (var i = 0; i < half.length; i++)
        ret.push(half[i]);
      for (var i = 0; i < data.length; i++)
        ret.push(data[i]);
      return ret;
    } else return null;
  };

SOURCE: https://github.com/jwhitehorn/jsMiner/blob/4fcdd9042a69b309035dfe9c9ddf716119831a16/engine.js#L149-165


Frankly speaking Bitcoin block hashing algorithm is not officially described by any source.

" The hash calculation is documented at Block hashing algorithm. " should read

The hash calculation is "described" at Block hashing algorithm.

en.bitcoin.it/wiki/Block_hashing_algorithm

btw the example code in PHP comes with a bug (typo) the example code in Python generates errors when run by Python3.3 for Windows XP 32 (missing support for string.decode)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号