2

I am coding a program that connects to bitcoin-qt as local server. For building the blockheader i need the merkleroot, to build the merkle root, i need the coinbase transaction (which is not provided when connecting directly to bitcoin-qt) i understand that i must use createrawtransaction to build it manullay as below:

createrawtransaction '[{"txid":"00000...000000000000","vout":0}]' '{"BTC ADRESS":6.5}'

My question is: In BTC ADRESS i put any adress that i choose from my bitcoin-qt wallet?

And if i double hash the given hex result returned to me, without adding any other transaction, this can be the merkleroot (with only the coinbase transaction) and use it to build the blockheader?

1 Answer 1

0

My question is: In BTC ADRESS i put any adress that i choose from my bitcoin-qt wallet?

Yes!! You would basically use a generated receiving address belonging to your btc wallet and use that as your value within the createrawtransaction address parameter field.

Although you would need to call the getnewaddress command via any means available to you after which you can make use of it.

.

Assuming that you've already changed directory to where your bitcoin-cli or bitcoind executable file is located

CMD approach would look something like this:

bitcoin-cli getnewaddress which would display newly generated address in the cmd terminal window.

bitcoin-cli getnewaddress > newlygenerated_BTC_address.txt which would store the output into a text file

To make things more dynamic you would need to write a batch script to handle aspects that your programming language isn't able to handle. But hopefully you get the idea.





And if i double hash the given hex result returned to me, without adding any other transaction, this can be the merkleroot (with only the coinbase transaction) and use it to build the blockheader?

Yes. You would insert the double hashed result of the raw transaction data as the merkleroot without swapping it( That will be done later when swapping the blockheader for mining). If you swap twice, you'll end up with an incorrect coinbase hash.

Other than that, you would need to correct and insert a few things.

Assuming hex response of createrawtransaction produces -> 02000000010000000000000000000000000000000000000000000000000000000000000000ffffff7f00ffffffff0140be402500000000160014f68d712fa6f49cdfaaa1707a9d0234e2aabb3f1100000000

:::


02000000010000000000000000000000000000000000000000000000000000000000000000ffffff7f00ffffffff0140be402500000000160014f68d712fa6f49cdfaaa1707a9d0234e2aabb3f1100000000

____________________________________________________________________

02000000 - Tx version -- 8 bytes
____________________________________________________________________

01 - input count -- 2 bytes
____________________________________________________________________

0000000000000000000000000000000000000000000000000000000000000000 - txid -- 64 bytes
____________________________________________________________________

ffffff7f - vout -- 8 bytes
____________________________________________________________________

00 - size of scriptsig -- MAX OF 100 bytes
____________________________________________________________________

 - scriptsig size is missing - hexadecimal value
 - byte push is missing - hexadecimal value
 - block height (little endian) is missing - hexadecimal value
 - arbitrary data(extranonce/message) is missing - hexadecimal value
____________________________________________________________________

ffffffff - input sequence -- 8 bytes
____________________________________________________________________

01- number of output -- 2 bytes
____________________________________________________________________

40be402500000000 - reward/Output Value -- 16 bytes
____________________________________________________________________

160014f68d712fa6f49cdfaaa1707a9d0234e2aabb3f11 - scriptPubkey -- 46 bytes (dynamic in length)
____________________________________________________________________

00000000  - locktime
____________________________________________________________________


My C++ solution :


bHeight - Block height as given by **```getblocktemplate```** response 
Headers needed - sstream, string, iostream.
Namespaces used - using std::stringstream, using std::string.


string SwapBlockHeight(string data)
{
    string bits; // global return variable
    if(data.size() == 5)
    {
        string byte1, byte2, byte3;
        byte3 = data.substr(5, 2);
        byte2 = data.substr(3, 2);
        byte1 = data.substr(1, 2);
        bits = byte3 + byte2 + byte1;
    }
    else if(data.size() == 6)
    {
        string byte1, byte2, byte3;
        byte3 = data.substr(4, 2);
        byte2 = data.substr(2, 2);
        byte1 = data.substr(0, 2);
        bits = byte3 + byte2 + byte1;
    }
    else if(data.size() == 8)
    {
        string byte1, byte2, byte3, byte4;
        byte4 = data.substr(6, 2);
        byte3 = data.substr(4, 2);
        byte2 = data.substr(2, 2);
        byte1 = data.substr(0, 2);
        bits = byte4 + byte3 + byte2 + byte1;
    }
    return bits;
}



string GETLittleEndian_BlockHeight(uint32_t bHeight)
{
    string reversedDATA;
    char i[25];
    sprintf(i, "%x", bHeight);
    stringstream aa;
    aa << i;
    aa >> reversedDATA;
    // reversedDATA = SwapBlockHeight(reversedDATA);
    // Optimized approach of above function call is applied below
    // Assuming hex conversion result is = "1d34f589"
    string byte;

    // Optimized approach
    for (int i = 0, k = 0; i < reversedDATA.length()/2; i++)
    {
        byte += reversedDATA.substr(k, 2);
        k+=2;
    }
    reversedDATA = byte; // or you could just return byte itself
    // reversedDATA.length()/2 - because we will be done with our goal in half the total size.

    return reversedDATA;
}


Bytepush = "03";
Blockheight_littleEndian = GETLittleEndian_BlockHeight(bHeight);
ArbitraryData = "abcdefgh"; // Anything within 100 bytes .. 1 char == 2 bytes

scriptsig_Size = Bytepush.length() + Blockheight_littleEndian.length() + ArbitraryData.length();

// ALL VALUES ARE HEXADECIMAL


LOOKING FOR JSON PARSER/SERIALIZATION??

  1. Get nlohmann json library
  2. Include in project folder

A little batch script used but nothing too 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 
// std::cout << ifstream(Output_FileName).rdbuf(); // print to console -- FOR DEBUGGING ONLY!!
} // 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



uint32_t Get_BLOCK_HEIGHT_asInteger()
{
    uint32_t f;
    ifstream file_input("getblocktemplate_Response.json");
    json object = json::parse(file_input); // Parse json data
    file_input.close(); // close streamer
    f = object.at("height");
    return f;
}

WHATS INSIDE THE .BAT FILE??

gt.bat

@echo off
cd "C:\Users\YOUR DESKTOP NAME\Desktop\Z Code" && bitcoin-cli getblocktemplate {\"rules\":[\"segwit\"]}

rem or

cd "C:\Users\YOUR DESKTOP NAME\Desktop\Z Code" && bitcoin-cli getblocktemplate {\"rules\":[\"segwit\"]} 

Rem copy file created to destination folder
copy "C:\Users\YOUR DESKTOP NAME\Desktop\Z Code\getblocktemplate_Response.json" "C:\Users\YOUR DESKTOP NAME\Desktop\Z Code\COINBASE ONLY\BITCOIN_Miner"

NOTE!! - Copying of json file from one path to another is only needed if your gt.bat is not located in your project root folder along with header files. This would cause errors later on because in as much as the json file was created and holds block template response, it won't be found UNLESS you tell the json reader to go into whichever folder where it will be generated and get it from there.

It's a lot more than requested but others might find the info useful. I'll create a repository on github later.

Ignore what you don't need.

Cheers

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.