¿Cómo puedo verificar el hash de un bloque de bitcoin?

Elijamos un bloque de bitcoin de ejemplo: #499583

Este es el bloque: https://insight.bitpay.com/api/rawblock/000000000000000000677c4077da7c9f01dde5f332ba2fbff962ee699714d5da

Empieza con00000020164a1e4a7f34b96b0e201d....

Estoy tratando de hacer un hash para que el hash sea de 000000000000000000677c4077da7c9f01dde5f332ba2fbff962ee699714d5danuevo. Este es mi código Javascript:

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);
  })
})

Pero el resultado es 484cd10be70dbc7615dd9a71b1f91375b100715d9b2a0ecc6a05b9d247a8cda9. ¿Qué estoy haciendo mal? El resultado debería ser 000000000000000000677c4077da7c9f01dde5f332ba2fbff962ee699714d5da. ¿Hago hash de algo en el formato incorrecto?

Respuestas (2)

Me parece que está procesando todo el bloque en lugar de solo el encabezado. Toma mi código (en 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 ( );
}

y la salida es:

000000000000000000677c4077da7c9f01dde5f332ba2fbff962ee699714d5da

¿Qué formato deben tener los datos de entrada? Estoy tratando de conectar manualmente los datos en una calculadora sha256 y no obtengo el resultado correcto. Sé que es un doble sha256 pero debo estar cometiendo un error en alguna parte.
la entrada son datos binarios sin procesar de 80 bytes de longitud
Te agradezco amaclin, no sabía que solo necesitas hash el encabezado. Pero, ¿puede alguien escribir un programa tan corto en Javascript, Java o Python? (No puedo leer C ++, no sé qué es QByteArray, qué es MyKey32, qué está haciendo realmente el programa).
#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;
}

mi código usa openssl. pasó.