How to Execute Bitcoin Transactions Using a Full Node

If you’ve followed our complete guide series, you’ve already compiled Bitcoin Core from source, configured an RPC node, and synced the blockchain. This tutorial builds on that foundation to execute a Bitcoin transaction using your node.

Note: As covered previously, Bitcoin Core and its RPC APIs evolve rapidly. This guide uses Bitcoin v0.18 on Ubuntu.

Step-by-Step Bitcoin Transaction Process

Here’s the core workflow for creating transactions:

  1. Retrieve UTXOs (Unspent Transaction Outputs)
  2. Create Raw Transaction
  3. Sign the Transaction
  4. Broadcast to Network

1. Retrieving UTXOs

The critical first step involves fetching spendable outputs using the listunspent RPC method. Many users encounter issues here—the API might return empty results because:

👉 Bitcoin wallets only track UTXOs for addresses they control. If your address wasn’t generated by or imported into the node’s wallet, the node won’t recognize its UTXOs.

Wallet Address Association Explained

Early Bitcoin versions used an account-based model, where addresses belonged to named accounts. Modern versions (v0.17+) replaced this with:

  • Wallet-level management (identified by name)
  • Label-based address grouping within wallets

An address is unassociated if:
– It wasn’t generated by your wallet (getnewaddress)
– Its private key wasn’t imported (importprivkey)

How to Associate an Address

Import the private key using:
bash
bitcoin-cli importprivkey "your_private_key" "" true

The rescan parameter rebuilds the UTXO index—this may take hours for addresses with long histories.

Alternative UTXO Access Methods
  1. Transaction Indexing: Launch node with txindex=1 (required for block explorers)
  2. Watch-only Wallets: Import addresses without private keys (read-only)

Most tutorials use getnewaddress to avoid these complexities since wallet-generated addresses are automatically associated.

2. Creating Raw Transactions

Use createrawtransaction to draft transactions. Key considerations:

  • Inputs must exceed outputs (the difference becomes miner fees)
  • Missing change addresses create overpayment fees (use fundrawtransaction for automated change)

Example:
bash
bitcoin-cli createrawtransaction '[{"txid":"input_txid","vout":0}]' '{"recipient_address":amount}'

This outputs an unsigned hex string.

3. Transaction Signing

Two signing methods exist in v0.18:

Method Command Requires
Wallet Signing signrawtransactionwithwallet Imported private key
Manual Signing signrawtransactionwithkey Private key provided

Successful signing returns:
json
{
"hex": "signed_hex",
"complete": true
}

Warning: "complete":true doesn’t guarantee validity. Always verify PrevTX parameters if broadcasting fails.

4. Broadcasting Transactions

Submit signed transactions with:
bash
bitcoin-cli sendrawtransaction "signed_hex"

Common Broadcasting Issues

  • High Fees: Add allowhighfees=true for transactions without change addresses
  • Missing Inputs: Usually indicates signature errors (recheck step 3)

👉 For test environments, use regtest mode to avoid real asset loss. Below is a complete regtest workflow:

Complete Regtest Example

“`bash

Start private chain

bitcoind -printtoconsole -regtest

Generate blocks to fund wallet

bitcoin-cli -regtest generatetoaddress 101 $(bitcoin-cli -regtest getnewaddress)

Create transaction

bitcoin-cli -regtest createrawtransaction \
‘[{“txid”:”funding_txid”,”vout”:0}]’ \
‘{“recipient_address”:20}’

Sign and broadcast

bitcoin-cli -regtest signrawtransactionwithwallet “unsigned_hex”
bitcoin-cli -regtest sendrawtransaction “signed_hex”
“`

Pro Tips

  1. Configuration Consistency: Ensure bitcoin.conf and CLI parameters don’t conflict
  2. RPC Authentication: Bitcoin Core uses HTTP Basic Auth (username/password in bitcoin.conf)
  3. Testing Priority: Always use regtest mode for development—instant mining and zero risk

Frequently Asked Questions

Why can’t my node see UTXOs for my address?

The address must be either:
– Generated by your wallet (getnewaddress)
– Imported with its private key (importprivkey)

How do I avoid excessive miner fees?

Use fundrawtransaction to automatically handle change addresses instead of manual createrawtransaction.

What does “complete”:true mean in signing results?

It confirms the node accepted your signing parameters, but doesn’t validate transaction feasibility. Always cross-check inputs.

Why does my transaction fail to broadcast?

Common causes:
– Insufficient fee (use estimatesmartfee)
– Invalid signatures (re-sign with correct PrevTX data)
– High fee without allowhighfees flag

Can I use curl instead of bitcoin-cli?

Yes! All CLI commands are JSON-RPC calls. Example: