Calculate/Confirm the Hash of a Bitcoin Block Header

0
101
Calculate/Confirm the Hash of a Bitcoin Block Header


After a number of analysis, I’ve give you the next Javascript perform that calculates the legitimate hash of any block offered you enter the 6 required parameters which are formally used to generate the hash of a Bitcoin block header. I feel it might assist folks perceive how a block header is accurately hashed.

Parameters of this instance are set with Bitcoin Block #722,460.

/**
 * @dev This perform takes the model, timestamp, bits or nonce and returns
 * its illustration as a hexadecimal string in little-endian byte order
 * 
 */
perform toLittleEndianHex(worth) {
  // Create a brand new 4-byte little-endian DataView with an ArrayBuffer
  const littleEndian = new DataView(new ArrayBuffer(4));
  // Set the worth of the DataView to the model, timestamp, bits or nonce in little-endian byte order
  littleEndian.setUint32(0, worth, true);
  // Convert the DataView right into a Uint8Array
  const byteArray = new Uint8Array(littleEndian.buffer);
  // Convert every byte right into a 2-character hexadecimal string, and push them into an array
  const hexArray = [];
  for (let i = byteArray.size - 1; i >= 0; i--) {
    hexArray.push(byteArray[i].toString(16).padStart(2, "0"));
  }
  // Reverse the order of the hexadecimal strings within the array and be part of them right into a single string
  return hexArray.reverse().be part of("");
}

/**
 * @dev This perform takes a hexadecimal string and returns its 
 * illustration as a Uint8Array
 * 
 */
perform hexStringToUint8Array(hexString) {
  // Convert the hexadecimal string into an array of 2-character substrings, representing every byte
  const byteArray = hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16));
  // Create a brand new Uint8Array from the array of bytes
  return new Uint8Array(byteArray);
}

/**
 * @dev This perform takes a hexadecimal string and returns its reverse
 * 
 */
perform reverseHexString(hexString) {
  // Convert the hexadecimal string into an array of 2-character substrings, representing every byte
  // Reverse the order of the substrings and be part of them right into a single string
  return hexString.match(/.{1,2}/g).reverse().be part of("");
}

/**
 * @dev This perform takes an object representing block information, calculates 
 * its hash worth, and logs it to the console
 * 
 */
async perform calculateBlockHash(blockData) {
  // Destructure the block information object to extract its properties
  const { model, previousblockhash, merkleroot, time, bits, nonce } = blockData;
  // Convert every property to its hexadecimal illustration in little-endian byte order
  const versionHex = toLittleEndianHex(model);
  console.log("versionHex:", versionHex);
  const previousblockhashHex = reverseHexString(previousblockhash);
  console.log("previousblockhashHex:", previousblockhashHex);
  const merklerootHex = reverseHexString(merkleroot);
  console.log("versionHex:", merklerootHex);
  const timeHex = toLittleEndianHex(time);
  console.log("timeHex:", timeHex);
  const bitsHex = toLittleEndianHex(bits);
  console.log("bitsHex:", bitsHex);
  const nonceHex = toLittleEndianHex(nonce);
  console.log("nonceHex:", nonceHex);
  // Concatenate the hexadecimal representations right into a single string representing the block header
  const headerHex = `${versionHex}${previousblockhashHex}${merklerootHex}${timeHex}${bitsHex}${nonceHex}`;
  console.log("headerHex:", headerHex);
  // Convert the header hexadecimal string right into a Uint8Array
  const headerBin = hexStringToUint8Array(headerHex);
  // Use the Net Crypto API to calculate the double-SHA256 hash of the block header
  const hashDigest1 = await crypto.refined.digest("SHA-256", headerBin);
  const hashDigest2 = await crypto.refined.digest("SHA-256", hashDigest1)
  // Convert the hash digest right into a Uint8Array
  const hashBin = new Uint8Array(hashDigest2);
  // Convert the hash Uint8Array right into a hexadecimal string with reversed byte order
  const hashHex = Array.from(hashBin, b => b.toString(16).padStart(2, "0")).be part of("");
  const hashResult = hashHex.match(/.{1,2}/g).reverse().be part of("");
  // Log the hash consequence worth to the console
  console.log("hashResult:", hashResult);
}

/**
 * @dev Knowledge from Block #722,460
 * Confirm at https://bitcoinexplorer.org/block-height/722460#JSON
 * 
 */
const blockData = {
  model: 536879108,
  previousblockhash: "00000000000000000009d54a110cc122960d31567d3ee84a1f18a98f50591046",
  merkleroot: "e1e0573e6098d8128ee859e7540f56b01fe0a33e56694df6d2fab0f96c4954b3",
  time: 1644403033,
  bits: 0x170a8bb4,
  nonce: 1693537958
};

// Name the calculateBlockHash perform with the blockData object as its argument
await calculateBlockHash(blockData);

Console Output:

versionHex: 04200020
previousblockhashHex: 461059508fa9181f4ae83e7d56310d9622c10c114ad509000000000000000000
versionHex: b354496cf9b0fad2f64d69563ea3e01fb0560f54e759e88e12d898603e57e0e1
timeHex: 59990362
bitsHex: b48b0a17
nonceHex: a656f164
headerHex: 04200020461059508fa9181f4ae83e7d56310d9622c10c114ad509000000000000000000b354496cf9b0fad2f64d69563ea3e01fb0560f54e759e88e12d898603e57e0e159990362b48b0a17a656f164
hashResult: 00000000000000000002b73f69e81b8b5e98dff0f2b7632fcb83c050c3b099a1

LEAVE A REPLY

Please enter your comment!
Please enter your name here