Skip to content

Examples from Building Transactions

Kulpreet Singh edited this page Feb 10, 2019 · 2 revisions

All examples from the building transactions documentation chapter are shown here in full. The specific examples referenced in the subsections are wrapped in the functions listed below.

Populating Transaction Object

  • build_transaction()

Libbitcoin API: Version 3.

Script below is ready-to-compile: g++ -std=c++11 -o build_tx build_tx_examples.cpp $(pkg-config --cflags libbitcoin-system --libs libbitcoin-system)

#include <bitcoin/system.hpp>
#include <string.h>
#include <iostream>

using namespace bc;
using namespace bc::system;
using namespace wallet;
using namespace chain;
using namespace machine;


void build_transaction() {

    // ******* part 1 *******

    // Instantiate tx object.
    transaction tx;

    // ******* part 2 *******.

    // Version 1.
    uint32_t version = 1u;
    tx.set_version(version);

    // Print version in serialised format.
    auto serialised_version = to_little_endian(tx.version());
    std::cout << encode_base16(to_chunk(serialised_version));

    //******* part 3 *******

    // Previous TX hash.
    std::string prev_tx_string_0 = "ca05e6c14fe816c93b91dd4c8f00e60e4a205da85741f26326d6f21f9a5ac5e9";
    hash_digest prev_tx_hash_0;
    decode_hash(prev_tx_hash_0,prev_tx_string_0);

    // Previous UXTO index.
    uint32_t index0 = 0;
    output_point uxto_tospend_0(prev_tx_hash_0, index0);

    // Build input_0 object.
    input input_0;
    input_0.set_previous_output(uxto_tospend_0);
    input_0.set_sequence(0xffffffff);

    // Additional input objects can be created for additional inputs

    // All input objects can then be added to transaction
    tx.inputs().push_back(input_0);        //first input
    // tx.inputs().push_back(input_1);     //second input
                                           //...nth input

    // Input script will be added later.


    // ******* part 4 *******

    // Destination Address
    auto my_address_raw = "mmbmNXo7QZWU2WgWwvrtnyQrwffngWScFe";
    payment_address my_address1(my_address_raw);

    // Create Output output script/scriptPubKey from template:
    operation::list output_script_0=script::to_pay_key_hash_pattern(my_address1.hash());

    // Define Output amount
    std::string btc_amount_string_0 = "1.295";
    uint64_t satoshi_amount_0;
    decode_base10(satoshi_amount_0, btc_amount_string_0, btc_decimal_places); // btc_decimal_places = 8

    // Create output_0 object
    output output_0(satoshi_amount_0, output_script_0);

    // Above can be repeated for other outputs

    // Add outputs to TX
    tx.outputs().push_back(output_0);     //first output
    // tx.outputs().push_back(output_1);   //second output
    // tx.outputs().push_back(output_n);   //...nth output

    // ******* part 5 *******

    // We rebuild our P2PKH script manually:
    operation::list my_own_p2pkh;
    my_own_p2pkh.push_back(operation(opcode::dup));
    my_own_p2pkh.push_back(operation(opcode::hash160));
    operation op_pubkey = operation(to_chunk(my_address1.hash()));
    my_own_p2pkh.push_back(op_pubkey); //includes hash length prefix
    my_own_p2pkh.push_back(operation(opcode::equalverify));
    my_own_p2pkh.push_back(operation(opcode::checksig));

    // The two operation lists are equivalent
    std::cout << (my_own_p2pkh == output_script_0) << std::endl;

    // ******* part 6 *******

    // Signer: Secret > Pubkey > Address
    auto my_secret0 = base16_literal(
        "3eec08386d08321cd7143859e9bf4d6f65a71d24f37536d76b4224fdea48009f");
    ec_private my_private0(my_secret0, ec_private::testnet, true);
    ec_compressed pubkey0= my_private0.to_public().point();
    payment_address my_address0 = my_private0.to_payment_address();

    // Signature
    endorsement sig_0;
    script prev_script_0 = script::to_pay_key_hash_pattern(my_address0.hash());
    uint8_t input0_index(0u);
    script::create_endorsement(sig_0, my_secret0, prev_script_0, tx,
        input0_index, 0x01);

    // Create input script
    operation::list sig_script_0;
    sig_script_0.push_back(operation(sig_0));
    sig_script_0.push_back(operation(to_chunk(pubkey0)));
    script my_input_script_0(sig_script_0);

    // Add input script to first input in transaction
    tx.inputs()[0].set_script(my_input_script_0);

    // Print serialised transaction
    std::cout << encode_base16(tx.to_data()) << std::endl;

}


int main() {

    build_transaction();

    return 0;

}

Libbitcoin Menu

Clone this wiki locally