<h2>Just as <a href="https://bitcoin.stackexchange.com/users/208/pieter-wuille">Pieter-Wuille</a> explained but in clearer detail........</h2>
<hr />
<p><em><strong>The transaction data needed to compute a merkleroot in regards to bitcoins mining process is the &quot;txid&quot; key returned by the getblocktemplate response. This applies to non witness transaction processing.</strong></em></p>
<p><em><strong>In order to process transactions with witness data, you would need to gat the &quot;hash&quot; key value instead!</strong></em></p>
<p><em><strong>It all depends on whether or not you want your miner to process witness tagged transactions.</strong></em></p>
<hr />
<hr />
<h2><em><strong>From <code>getblocktemplate</code> response</strong></em></h2>
<hr />
<p><strong><code>data</code></strong> - Raw transaction data.</p>
<p><strong><code>txid</code></strong> - Double hashed output of raw transaction data.</p>
<p><strong><code>hash</code></strong> - Witness hash output for transactions with witness data.</p>
<hr />
<hr />
<h2><strong>This is a working merkleRoot function I developed myself. Works as intended.</strong></h2>
<pre><code>
#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &quot;sha256.h&quot; // Your sha256 solution with hex parsing function

using std::string;
using std::vector;
using std::cout;


string MKccx(vector&lt;string&gt; &amp;transactions_vector)
{
    string hash;
    string temp1;
    int x = 0, d = 0;
    vector&lt;string&gt; calculate_tx;
    // calculate_tx[0] = SwapPerRound_2bits(coinbase_hash); // Store swapped endian format in vector index 0
    if (transactions_vector.empty())
    {
        std::cout &lt;&lt; &quot;\n&quot; &lt;&lt; &quot;ERROR! NO TRANSACTION FOUND IN ARRAY!!... NOT EVEN A COINBASE TRANSACTION!!!... EXITING FUNCTION!&quot; &lt;&lt; &quot;\n \n&quot;;
        throw;
    }
    else if (transactions_vector.size() == 1)
    {
        hash = transactions_vector[0];
        return hash;
    }
    for(int i = 0; i &lt; 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 &lt; 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 &lt; 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 &lt; 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 &lt; 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&lt;string&gt; transaction = {&quot;8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87&quot;,&quot;fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4&quot;,&quot;6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4&quot;,&quot;e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d&quot;,&quot;c02092b00aa0aea8463c624ccebdb0efdb18347068aa48c3d1b42766ca7e92ba&quot;};

    vector&lt;string&gt; block100000 = {&quot;8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87&quot;,&quot;fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4&quot;,&quot;6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4&quot;,&quot;e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d&quot;};

    vector&lt;string&gt; transaction2 = {&quot;8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87&quot;};

    vector&lt;string&gt; transaction3 = {};
    string merk;
    merk = MKccx(transaction3);
    std::cout &lt;&lt; &quot;MerkleRoot Hash is : &quot; &lt;&lt; merk &lt;&lt; &quot;\n \n&quot;;
    // std::cout &lt;&lt; &quot;Merkle hash of Block 100,000 is : &quot; &lt;&lt; merk &lt;&lt; &quot;\n \n&quot;;

    return 0;
}

</code></pre>
<p><strong><code>SwapPerRound_2bits()</code></strong> - Whatever solution you use for swapping endianness</p>
<p><strong><code>double_Hex_sha256()</code></strong> - Equivalent of sha256(sha256());</p>
<hr />
<hr />
<h2>WONDERING HOW IT ALL COMES TOGETHER??</h2>
<p><em><strong>YOU'LL NEED A JSON LIBRARY TO GET THE TRANSACTIONS INTO YOUR C++ PROGRAM</strong></em></p>
<p><strong>IF YOU DON'T ALREADY HAVE A WORKING JSON PARSER/SERIALIZATION LIBRARY THEN I RECOMMEND <a href="https://github.com/nlohmann/json" rel="nofollow noreferrer">nlohmann json library</a> FOR JSON PARSING &amp; SERIALIZATION.</strong></p>
<p><strong>Just include its single header &quot;.hpp&quot; file in project folder and you're good to go!</strong></p>
<p><em><strong>A little batch script used but nothing advanced.</strong></em></p>
<pre><code>#include &quot;json.hpp&quot; // for json serialization parser
#include &lt;fstream&gt; // for ifstream
#include &lt;stdlib.h&gt; // for system calls
#include &quot;windows.h&quot; // 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 + &quot; &gt;&quot; + 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 = &quot;cd \&quot;C:\\Users\\YOUR DESKTOP NAME\\Desktop\\Z Code\&quot; &amp;&amp; call gt.bat&quot;;
    string filename = &quot;getblocktemplate_Response.json&quot;; // 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(&quot;getblocktemplate_Response.json&quot;); // Open file
    json object = json::parse(file_input); // Parse json data
    file_input.close(); // close file
    vector&lt;string&gt; Txid_Retreiver; // vector for holding transactions

    auto &amp;Array_Txid = object[&quot;transactions&quot;]; // Create object pointing to 'transactions' array
    for(auto &amp;target : Array_Txid) // Traverse through transaction array
        Txid_Retreiver.push_back(target[&quot;txid&quot;].get&lt;std::string&gt;());
    

    merk = MKccx(Txid_Retreiver);
    std::cout &lt;&lt; &quot;MerkleRoot Hash is : &quot; &lt;&lt; merk &lt;&lt; &quot;\n \n&quot;;

    return 0;
}


</code></pre>
<p>And that's pretty much how I pulled it off.</p>
<p>Hope this helps someone.</p>
<p>Cheers....</p>

CC BY-SA 4.0
2022-02-12T03:21:37.710Z
2022-02-12T03:21:37.710Z
AncientTides
<p>The transaction Merkle tree, whose root is stored in the block header, is computed over the individual transactions' <em>txid</em> value (which are the double-SHA256 of their data after stripping the witness).</p>
<p>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' <em>hash</em> value (which are the double-SHA256 of their data including the witness).</p>
<p>I recommend you study the source code of existing mining software, instead of asking questions about every tiny detail of the process.</p>

CC BY-SA 4.0
2021-12-12T15:09:40.787Z
Okay thanks... So which I'm I to feed to the merkleroot function to build a valid merklehash.. Is it **hash** or **txid**.. Remember that I'm manually placing coinbase as index 0 within list of transactions so this is pretty much the lingering difficulties.
AncientTides
CC BY-SA 4.0
2021-12-12T15:12:14.833Z
Also if you noticed, most of my questions are from this angle only..... Its really the only part that both vital and somewhat hard to understand. Every other part I've implemented.... Thanks for your patience and answers.. They've been really helpful.
AncientTides
CC BY-SA 4.0
2021-12-12T15:16:26.957Z
Please re-read my answer. I have answered your question exactly. You need both a Merkle tree of txids, and one of hashes. If these details confuse you, you'll have 100s more questions before you have a functioning miner. You really should look at example mining code instead.
Pieter Wuille
CC BY-SA 4.0
2021-12-12T15:00:55.033Z
2021-12-12T15:00:55.033Z
Pieter Wuille
<p>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...</p>
<p>The transactions within the getblocktemplate each have <a href="https://developer.bitcoin.org/reference/rpc/getblocktemplate.html#:%7E:text=%22transactions%22%20%3A%20%5B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(json%20array,including%20witness%20data)" rel="nofollow noreferrer">these</a> as keys and thier values.</p>
<hr />
<h2>Question</h2>
<p>Which Key value <a href="https://developer.bitcoin.org/reference/rpc/getblocktemplate.html#:%7E:text=%22transactions%22%20%3A%20%5B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(json%20array,including%20witness%20data)" rel="nofollow noreferrer">from the list of contents within each transaction array</a> is my merkleroot function supposed to use to build a merklerot Hash.... Is it <strong><code>data</code></strong> or <strong><code>hash</code></strong> ? Or is it the <strong><code>txid</code></strong>?</p>
<p>Merkleroot needs transaction hash....so is it <a href="https://developer.bitcoin.org/reference/rpc/getblocktemplate.html#:%7E:text=%22hash%22%20%3A%20%22hex%22%2C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(string)%20hash%20encoded%20in%20little%2Dendian%20hexadecimal%20(including%20witness%20data)" rel="nofollow noreferrer">hash</a> Json Key or is it the <a href="https://developer.bitcoin.org/reference/rpc/getblocktemplate.html#:%7E:text=%22data%22%20%3A%20%22hex%22%2C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(string)%20transaction%20data%20encoded%20in%20hexadecimal%20(byte%2Dfor%2Dbyte)" rel="nofollow noreferrer">data</a> Json Key ?</p>
<hr />
<p>Thanks in advance</p>

<json-rpc><merkle-tree><getblocktemplate>
MerkleRoot requires transaction hash to build a merkle tree.... Is that the "hash" key/value within the getblocktemplate response or the "data"?
AncientTides
# MerkleRoot requires transaction hash to build a merkle tree.... Is that the "hash" key/value within the getblocktemplate response or the "data"?

(Asked by: username_0 on 2021-12-12)

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](https://developer.bitcoin.org/reference/rpc/getblocktemplate.html#:%7E:text=%22transactions%22%20%3A%20%5B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(json%20array,including%20witness%20data)) as keys and thier values.

---

## Question

Which Key value [from the list of contents within each transaction array](https://developer.bitcoin.org/reference/rpc/getblocktemplate.html#:%7E:text=%22transactions%22%20%3A%20%5B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(json%20array,including%20witness%20data)) 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](https://developer.bitcoin.org/reference/rpc/getblocktemplate.html#:%7E:text=%22hash%22%20%3A%20%22hex%22%2C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(string)%20hash%20encoded%20in%20little%2Dendian%20hexadecimal%20(including%20witness%20data)) Json Key or is it the [data](https://developer.bitcoin.org/reference/rpc/getblocktemplate.html#:%7E:text=%22data%22%20%3A%20%22hex%22%2C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(string)%20transaction%20data%20encoded%20in%20hexadecimal%20(byte%2Dfor%2Dbyte)) Json Key ?

---

Thanks in advance

**Tags:** json-rpc, merkle-tree, getblocktemplate


---

## 2 answers

### Answer by username_0 on 2022-02-12. Score: 0 | Accepted answer

## Just as [username_1](https://bitcoin.stackexchange.com/users/208/username_1-username_1) 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](https://github.com/nlohmann/json) 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....


---

### Answer by username_1 on 2021-12-12. Score: 1

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.

> **Comments:**
> **username_0**: Okay thanks... So which I'm I to feed to the merkleroot function to build a valid merklehash.. Is it **hash** or **txid**.. Remember that I'm manually placing coinbase as index 0 within list of transactions so this is pretty much the lingering difficulties.  
> **username_0**: Also if you noticed, most of my questions are from this angle only..... Its really the only part that both vital and somewhat hard to understand. Every other part I've implemented.... Thanks for your patience and answers.. They've been really helpful.  
> **username_1**: Please re-read my answer. I have answered your question exactly. You need both a Merkle tree of txids, and one of hashes. If these details confuse you, you'll have 100s more questions before you have a functioning miner. You really should look at example mining code instead.  

---

