Skip to content

Latest commit

 

History

History
142 lines (99 loc) · 4.31 KB

Examples-from-Building-Transactions.md

File metadata and controls

142 lines (99 loc) · 4.31 KB

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;

}