2

Let's pick an example bitcoin block: #499583

This is the block: https://insight.bitpay.com/api/rawblock/000000000000000000677c4077da7c9f01dde5f332ba2fbff962ee699714d5da

It starts with 00000020164a1e4a7f34b96b0e201d....

I'm trying to hash it so that the hash is 000000000000000000677c4077da7c9f01dde5f332ba2fbff962ee699714d5da again. This is my Javascript-Code:

var Bitcoin = require('bitcoinjs-lib');
var request = require('request');
var crypto = require('crypto');

function getRawBlock(blockHash) {
  return new Promise((resolve, reject) => {
    request('https://insight.bitpay.com/api/rawblock/' + blockHash, // hitting an insight API to get the full block
      (error, response, body) => {
        try {
          var block = JSON.parse(body); // result is in JSON
          resolve(block.rawblock)
        } catch (error) {
          reject(error)
        }
      })
  })
}

getRawBlock('000000000000000000677c4077da7c9f01dde5f332ba2fbff962ee699714d5da')
  .then((rawBlock) => {
    var hash = crypto.createHash('sha256').update(rawBlock).digest('hex');
     console.log(hash);
  })
})

But the result is 484cd10be70dbc7615dd9a71b1f91375b100715d9b2a0ecc6a05b9d247a8cda9. What am I doing wrong? The result should be 000000000000000000677c4077da7c9f01dde5f332ba2fbff962ee699714d5da. Do I hash something in the wrong format?

4

Seems to me that you are hashing the whole block instead of header only. Take my code (in C++).

void test ( )
{
  const MyByteArray header ( QByteArray::fromHex (
     "00000020" // version
     "164a1e4a7f34b96b0e201dcc6a623c63fe3874696e4875000000000000000000" // prev hash
     "49de8b4f4bfa9fc890d3d28a93156a111f891dc680090cd497b58a7d5c2b09cf" // merkle
     "2f62345a"      // timestamp
     "edb00018"      // bits
     "ffdfd257" ) ); // nonce
  const MyKey32 key ( header.sha256d ( ) );
  qDebug ( ) << key.toString ( );
}

and the output is:

000000000000000000677c4077da7c9f01dde5f332ba2fbff962ee699714d5da

  • What format does the input data need to be? I'm trying to manually plug the data into a sha256 calculator, and not getting the correct result. I know it is a double sha256 but I must be making a mistake somewhere – chytrik Dec 16 '17 at 21:23
  • input is raw binary data 80 bytes length – amaclin Dec 17 '17 at 4:48
  • I thank you amaclin, I did not know that you only need to hash the header. But can someone maybe write such a short program in Javascript or Java or Python? (I can't read C++, I don't know what a QByteArray ist, what MyKey32 ist, what the proramm is really doing.) – ndsvw Dec 17 '17 at 7:58
1
#include <openssl/sha.h>

int main()
{
    const char * sin = "00000020" // version
        "164a1e4a7f34b96b0e201dcc6a623c63fe3874696e4875000000000000000000" // prev hash
        "49de8b4f4bfa9fc890d3d28a93156a111f891dc680090cd497b58a7d5c2b09cf" // merkle
        "2f62345a"      // timestamp
        "edb00018"      // bits
        "ffdfd257";
    string xxs = Helper::decode16(sin);

    unsigned char md[32];
    SHA256_CTX ctx;
    SHA256_Init(&ctx);
    SHA256_Update(&ctx, xxs.data(), xxs.length());
    SHA256_Final(md, &ctx);

    SHA256_Init(&ctx);
    SHA256_Update(&ctx, md, 32);
    SHA256_Final(md, &ctx);

    const char * tbl = "0123456789abcdef";
    char outs[64 + 1] = { 0 };
    for (int i = 0; i < 32; ++i)
    {
        outs[2 * i + 0] = tbl[md[31-i] >> 4];
        outs[2 * i + 1] = tbl[md[31 - i] & 0xf];
    }
    printf("%s\n", outs);

    return 0;
}

my code uses openssl. passed.

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.