How to send a Bitcoin transaction

With Tatum, you can choose from two options how to send a Bitcoin transaction:

  • Enter a list of blockchain addresses from which the assets will be sent

  • Enter specific Unspent Transaction Outputs (UTXO) which will be used to send the assets

Before you start

Ensure that you fully understand how Bitcoin transactions work and how the transaction fees are charged.

How Bitcoin transactions work

The Bitcoin blockchain is not account-based but transaction-based. You operate with a list of previously received transactions and the assets within them. This means that you can use multiple transactions in one transaction as a source of your assets, not just one specific address. To learn more, see this Investopedia article.

  • When you enter a list of addresses, all incoming transactions that have not been used previously are used as a source.

  • When you enter a list of UTXOs, only specific unspent transactions that belong to you are used.

All of the assets that belong to the specific transaction are used as input, not only a fraction of them. To learn more about Bitcoin transactions, check out this article.

Before you actually make a transaction and send BTC, make sure that:

  • You know how much BTC you want to send and to whom.

  • You have defined a list of recipient addresses with the specific amounts that each address is to receive.

How transaction fees are charged

The sum of the assets that you send must be bigger than the sum of the assets that are expected to be received, and the difference must be sufficient to cover the transaction fee that will be paid to the network.

In other words, you must send more funds than expected to cover the transaction fees. This works similar to international wire transfers where you have to pay fees to the banks that handle your transaction.

For example, you want send 9 BTC to three recipients, each of which should receive 3 BTC. To cover the fees, you must send (3*3)+1=10 BTC. The fee will be 1 BTC.

You may not always be able to control exactly how much BTC is available to be sent, especially when you send assets from multiple addresses.

The difference between the sum of the assets that you send and the sum of the assets that are expected to be received may be considerable. You may not want to spend it all on the transaction fee.

In this situation, you can explicitly specify the fee amount that you are willing to pay and the blockchain address where any extra funds remaining after covering the fee will be sent.

Make a Bitcoin transaction

Use the API for sending BTC to Bitcoin addresses.

The following sample request shows how to send BTC from a list of addresses and from a list of UTXOs, with the fee amount set to 0.00001 BTC (the fee parameter) and the specified address to return any extra funds to (the changeAddress parameter):

import { TatumBtcSDK } from '@tatumio/btc';
import { YOUR_API_KEY_HERE } from '@tatumio/shared-testing-common';

const btcSDK = TatumBtcSDK({ apiKey: YOUR_API_KEY_HERE });

// If the source is a list of blockchain addresses

const bodyFromAddress = {
  fromAddress: [
    {
      address: 'mhuKgqf7SLRWPX8Sfrqn68i5YcdWsFMRXF',
      privateKey: 'cNkXKkQ4YoNS2LmnvhtGqWBQKg7oo3BRaowPhSDPvTRjxXyGG6yr',
    },
    {
      address: 'yxtely677ucyrrwt0k6ehzrm2gkztb1q9x2gqftthj',
      privateKey: 'cQ1YZMep3CiAnMTA9y62ha6BjGaaTFsTvtDuGmucGvpAVmS89khV',
    },
  ],
  to: [
    {
      address: 'n1XD955iuticPuKoJJr8XfAjDw2gYadNrR',
      value: 0.00015,
    },
    {
      address: 'mgSXLa5sJHvBpYTKZ62aW9z2YWQNTJ59Zm',
      value: 0.000009,
    },
  ],
  fee: '0.00001',
  changeAddress: 'tb1q9x2gqftyxterwt0k6ehzrm2gkzthjly677ucyr',
};

// If the source is a list of UTXOs

const bodyFromUTXO = {
  fromUTXO: [
    {
      txHash: '887dd5221800c65ada2a2081e65a14b5421b30600d4ab112421a44b17ded6ed4',
      index: 0,
      privateKey: 'cNkXKkQ4YoNS2LmnvhtGqWBQKg7oo3BRaowPhSDPvTRjxXyGG6yr',
    },
    {
      txHash: 'b2dc763cf75373ad14c984c07846f5425c20ddf34606debb0a148cd770528ef9',
      index: 1,
      privateKey: 'cNUHqqs67WVhMZP9hH3i9nLQ1BGEasA87y6N6SQMsfYaBaPi9SEs',
    },
  ],
  to: [
    {
      address: 'n1XD955iuticPuKoJJr8XfAjDw2gYadNrR',
      value: 0.00015,
    },
    {
      address: 'mgSXLa5sJHvBpYTKZ62aW9z2YWQNTJ59Zm',
      value: 0.000009,
    },
  ],
  fee: '0.00001',
  changeAddress: 'tb1q9x2gqftyxterwt0k6ehzrm2gkzthjly677ucyr',
};


const txDataFromAddress = await btcSDK.transaction.sendTransaction(bodyFromAddress, { testnet: true });
const txDataFromUTXO = await btcSDK.transaction.sendTransaction(bodyFromUTXO, { testnet: true });

When using this API, you must sign the transaction with the private key of the blockchain address from which the fee will be deducted.

Providing the private key in the API is not a secure way of signing transactions, because the private key can be stolen or exposed. Your private keys should never leave your security perimeter. You should use the private keys only for testing a solution you are building on the testnet of a blockchain.

For signing transactions on the mainnet, we strongly recommend that you use the Tatum Key Management System (KMS) and provide the signature ID instead of the private key in the API. Alternatively, you can use the Tatum JavaScript client.

The API returns the ID of the transaction, from which you can get information about the transaction:

{
  "txId": "962e4ad3781e7036ff3af6d880744fd3f06131c32d1085254da3cfa77b0e933f"
}

Once you have the transaction ID, get the details of the transaction.

Get the transaction details

Use the API for getting a Bitcoin transaction by its hash.

The following sample request shows how to get the details of the Bitcoin transaction:

import { TatumBtcSDK } from '@tatumio/btc';
import { YOUR_API_KEY_HERE } from '@tatumio/shared-testing-common';

const btcSDK = TatumBtcSDK({ apiKey: YOUR_API_KEY_HERE });

const tx = await btcSDK.blockchain.getTransaction(
  '962e4ad3781e7036ff3af6d880744fd3f06131c32d1085254da3cfa77b0e933f',
)

The API returns the detailed information about the transaction:

{
  "txid": "962e4ad3781e7036ff3af6d880744fd3f06131c32d1085254da3cfa77b0e933f",
  "hash": "962e4ad3781e7036ff3af6d880744fd3f06131c32d1085254da3cfa77b0e933f",
  "size": 374,
  "vsize": 374,
  "version": 2,
  "locktime": 0,
  "vin": [
    {
      "txid": "b2dc763cf75373ad14c984c07846f5425c20ddf34606debb0a148cd770528ef9",
      "scriptSig": {
        "asm": "30450...c238a",
        "hex": "48304...c238a"
      },
      "sequence": 4294967295,
      "vout": 0
    },
    {
      "txid": "b2dc763cf75373ad14c984c07846f5425c20ddf34606debb0a148cd770528ef9",
      "scriptSig": {
        "asm": "30450...c238a",
        "hex": "48304...c238a"
      },
      "sequence": 4294967295,
      "vout": 1
    }
  ],
  "vout": [
    {
      "value": 6e-7,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 0a21a...7d3a9 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a9140a21a1144fd4f6892c111c00141932608d17d3a988ac",
        "type": "PUBKEYHASH",
        "reqSigs": 1,
        "addresses": [
          "mgSXLa5sJHvBpYTKZ62aW9z2YWQNTJ59Zm"
        ]
      }
    },
    {
      "value": 0.000006,
      "n": 1,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 0a21a...7d3a9 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a9140a21a1144fd4f6892c111c00141932608d17d3a988ac",
        "type": "PUBKEYHASH",
        "reqSigs": 1,
        "addresses": [
          "mgSXLa5sJHvBpYTKZ62aW9z2YWQNTJ59Zm"
        ]
      }
    }
  ],
  "blockhash": null,
  "confirmations": 0,
  "time": 1605903228,
  "blocktime": 0,
  "hex": "02000...00000"
}

Last updated