Bitcoin Stack Exchange is a question and answer site for Bitcoin crypto-currency enthusiasts. It only takes a minute to sign up.
Sign up to join this communityAnybody can ask a question
Anybody can answer
The best answers are voted up and rise to the top
I've created a function for parsing Json Objects and values and just when I think nothing can stop me, just when I feel like I'm the king of the blockchain and I can finally join in on the mining race ..... I get a painful reminder/reality check...
The transactions within the getblocktemplate each have these as keys and thier values.
Question
Which Key value from the list of contents within each transaction array is my merkleroot function supposed to use to build a merklerot Hash.... Is it data
or hash
? Or is it the txid
?
Merkleroot needs transaction hash....so is it hash Json Key or is it the data Json Key ?
Thanks in advance
The transaction Merkle tree, whose root is stored in the block header, is computed over the individual transactions' txid value (which are the double-SHA256 of their data after stripping the witness).
The witness Merkle tree, whose root is stored in a coinbase output (only required for blocks containing segwit transactions, see BIP141), is computed over the transactions' hash value (which are the double-SHA256 of their data including the witness).
I recommend you study the source code of existing mining software, instead of asking questions about every tiny detail of the process.
Just as Pieter-Wuille explained but in clearer detail........
The transaction data needed to compute a merkleroot in regards to bitcoins mining process is the "txid" key returned by the getblocktemplate response. This applies to non witness transaction processing.
In order to process transactions with witness data, you would need to gat the "hash" key value instead!
It all depends on whether or not you want your miner to process witness tagged transactions.
From getblocktemplate
response
data
- Raw transaction data.
txid
- Double hashed output of raw transaction data.
hash
- Witness hash output for transactions with witness data.
This is a working merkleRoot function I developed myself. Works as intended.
#include <iostream> #include <vector> #include "sha256.h" // Your sha256 solution with hex parsing function using std::string; using std::vector; using std::cout; string MKccx(vector<string> &transactions_vector) { string hash; string temp1; int x = 0, d = 0; vector<string> calculate_tx; // calculate_tx[0] = SwapPerRound_2bits(coinbase_hash); // Store swapped endian format in vector index 0 if (transactions_vector.empty()) { std::cout << "\n" << "ERROR! NO TRANSACTION FOUND IN ARRAY!!... NOT EVEN A COINBASE TRANSACTION!!!... EXITING FUNCTION!" << "\n \n"; throw; } else if (transactions_vector.size() == 1) { hash = transactions_vector[0]; return hash; } for(int i = 0; i < transactions_vector.size(); i++) // Swap 2 bytes and reverse order of all txid's within transactions array transactions_vector[i] = SwapPerRound_2bits(transactions_vector[i]); while(true) { int z = 0; if (transactions_vector.size()%2 == 1) // IF SIZE OF VECTOR % 2 == 1 { temp1 = transactions_vector[transactions_vector.size()-1]; // STORE VALUE OF LAST VECTOR INDEX TO TEMP1 transactions_vector.push_back(temp1); // ADD THAT VALUE INTO VECTOR for(int i = 0, z = i+1; i < transactions_vector.size(); i+=2) { hash = transactions_vector[i] + transactions_vector[z]; // Concatenate txid pairs together hash = double_Hex_sha256(hash); // DoubleHash concatenated txid's calculate_tx.push_back(hash); z+=2; } for (int i = 0; i < calculate_tx.size(); i++) { temp1 = calculate_tx[i]; transactions_vector[i] = temp1; } transactions_vector.resize(calculate_tx.size()); if (calculate_tx.size() == 2) { hash = calculate_tx[0] + calculate_tx[1]; hash = double_Hex_sha256(hash); hash = SwapPerRound_2bits(hash); return hash; } calculate_tx.clear(); } else if (transactions_vector.size()%2 == 0) // IF SIZE OF VECTOR % 2 == 0 { for(int i = 0, z = i+1; i < transactions_vector.size(); i+=2) { hash = transactions_vector[i] + transactions_vector[z]; // Concatenate txid pairs together hash = double_Hex_sha256(hash); // DoubleHash concatenated txid's calculate_tx.push_back(hash); z+=2; } for (int i = 0; i < calculate_tx.size(); i++) { temp1 = calculate_tx[i]; transactions_vector[i] = temp1; } transactions_vector.resize(calculate_tx.size()); if (calculate_tx.size() == 2) { hash = calculate_tx[0] + calculate_tx[1]; hash = double_Hex_sha256(hash); hash = SwapPerRound_2bits(hash); return hash; } calculate_tx.clear(); } } }// Successful compilation on 06/02/2022 int main(int argc, char const *argv[]) { // HARDCODED TXID'S vector<string> transaction = {"8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87","fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4","6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4","e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d","c02092b00aa0aea8463c624ccebdb0efdb18347068aa48c3d1b42766ca7e92ba"}; vector<string> block100000 = {"8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87","fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4","6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4","e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d"}; vector<string> transaction2 = {"8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87"}; vector<string> transaction3 = {}; string merk; merk = MKccx(transaction3); std::cout << "MerkleRoot Hash is : " << merk << "\n \n"; // std::cout << "Merkle hash of Block 100,000 is : " << merk << "\n \n"; return 0; }
SwapPerRound_2bits()
- Whatever solution you use for swapping endianness
double_Hex_sha256()
- Equivalent of sha256(sha256());
WONDERING HOW IT ALL COMES TOGETHER??
YOU'LL NEED A JSON LIBRARY TO GET THE TRANSACTIONS INTO YOUR C++ PROGRAM
IF YOU DON'T ALREADY HAVE A WORKING JSON PARSER/SERIALIZATION LIBRARY THEN I RECOMMEND nlohmann json library FOR JSON PARSING & SERIALIZATION.
Just include its single header ".hpp" file in project folder and you're good to go!
A little batch script used but nothing advanced.
#include "json.hpp" // for json serialization parser #include <fstream> // for ifstream #include <stdlib.h> // for system calls #include "windows.h" // if on windows using namespace nlohmann; using std::ifstream; inline void RunCommand_With_Output_Without_SYMBOL_Defined(string Command_To_Run, string Output_FileName) { string xx_combine = Command_To_Run + " >" + Output_FileName; char run_command[xx_combine.length()]; strcpy(run_command, xx_combine.c_str()); system(run_command); // execute the command } // Successfully compiled on 20/01/2022 10:20PM void GETBLOCKTEMPLATE() { string getblocktemplate_syntax = "cd \"C:\\Users\\YOUR DESKTOP NAME\\Desktop\\Z Code\" && call gt.bat"; string filename = "getblocktemplate_Response.json"; // Create file Name RunCommand_With_Output_Without_SYMBOL_Defined(getblocktemplate_syntax, filename); // create json file with getblockresponse output } // Successfully compiled on 31/01/2022 11:30AM int main(int argc, char const *argv[]) { // DYNAMIC APPROACH FOR USAGE string merk; GETBLOCKTEMPLATE(); // Call getblocktemplate() ifstream file_input("getblocktemplate_Response.json"); // Open file json object = json::parse(file_input); // Parse json data file_input.close(); // close file vector<string> Txid_Retreiver; // vector for holding transactions auto &Array_Txid = object["transactions"]; // Create object pointing to 'transactions' array for(auto &target : Array_Txid) // Traverse through transaction array Txid_Retreiver.push_back(target["txid"].get<std::string>()); merk = MKccx(Txid_Retreiver); std::cout << "MerkleRoot Hash is : " << merk << "\n \n"; return 0; }
And that's pretty much how I pulled it off.
Hope this helps someone.
Cheers....
You can get bonuses upto $100 FREE BONUS when you:
๐ฐ Install these recommended apps:
๐ฒ SocialGood - 100% Crypto Back on Everyday Shopping
๐ฒ xPortal - The DeFi For The Next Billion
๐ฒ CryptoTab Browser - Lightweight, fast, and ready to mine!
๐ฐ Register on these recommended exchanges:
๐ก Binance๐ก Bitfinex๐ก Bitmart๐ก Bittrex๐ก Bitget
๐ก CoinEx๐ก Crypto.com๐ก Gate.io๐ก Huobi๐ก Kucoin.
Comments