Skip to content

Talking to Your Node with bitcoin-cli

Your running node exposes a JSON-RPC interface: you send a method name plus arguments, it returns JSON. bitcoin-cli is just a thin wrapper that POSTs to that interface and prints the reply. Every GUI wallet, block explorer, and dashboard is ultimately calling the same RPCs you’re about to call by hand. Learning them means you can ask the chain anything and trust the answer, because it’s coming from your own full node — not a website that could be lying.

Terminal window
bitcoin-cli help # list every RPC, grouped
bitcoin-cli help getblock # full docs for one command

The node documents itself. When you forget an argument, ask it — don’t guess.

The chain is addressed two ways: by height (an integer, 0 = genesis) and by block hash (the unique fingerprint). getblockhash converts height → hash; getblock fetches the block.

Terminal window
# Height 700000 -> its block hash
bitcoin-cli getblockhash 700000
0000000000000000000590fc0f3eba193a278534220b2b37e9849e1a770ca959
Terminal window
# Fetch that block (verbosity 1 = header fields + list of txids)
bitcoin-cli getblock 0000000000000000000590fc0f3eba193a278534220b2b37e9849e1a770ca959
{
"hash": "0000000000000000000590fc0f3eba193a278534220b2b37e9849e1a770ca959",
"confirmations": 112346,
"height": 700000,
"version": 536870912,
"merkleroot": "1e3f...c0d2",
"time": 1631323081,
"nonce": 2821664981,
"bits": "170d21b9",
"previousblockhash": "0000000000000000000a...8f1c",
"nTx": 1276,
"tx": ["6dcf...e1a4", "9a02...77bd", "..."]
}

Every field here maps to something you’ve studied: merkleroot is the Merkle root committing to all nTx transactions; bits is the encoded difficulty target; previousblockhash is the link that chains this block to its parent. This is the block header, live. Pass verbosity 2 to expand every transaction inline.

Read a transaction: raw bytes, then decode

Section titled “Read a transaction: raw bytes, then decode”

A transaction on the wire is a blob of hex. getrawtransaction fetches the blob; decoderawtransaction parses it into JSON. (With txindex=1 you can look up any txid; otherwise only ones in your wallet.)

Terminal window
# Get the raw hex of a transaction
bitcoin-cli getrawtransaction 6dcf...e1a4
0200000001a3b2...88ac00000000
Terminal window
# Parse those bytes into structured fields
bitcoin-cli decoderawtransaction 0200000001a3b2...88ac00000000
{
"txid": "6dcf...e1a4",
"version": 2,
"locktime": 0,
"vin": [
{ "txid": "f0a1...92cc", "vout": 0,
"scriptSig": { "asm": "3045...01 02ab..." }, "sequence": 4294967293 }
],
"vout": [
{ "value": 0.04200000, "n": 0,
"scriptPubKey": { "address": "bc1q...k8", "type": "witness_v0_keyhash" } },
{ "value": 0.00789550, "n": 1,
"scriptPubKey": { "address": "bc1q...9d", "type": "witness_v0_keyhash" } }
]
}

You can read every field now: vin are the inputs (each pointing at a prior output by txid:vout), vout are the new outputs with their locking scripts. This is exactly the structure from transaction anatomy. A handy shortcut: passing true as the second arg to getrawtransaction returns the decoded JSON directly.

This is the RPC that reveals what “spendable” really means. The node keeps a live set of all Unspent Transaction Outputs. gettxout asks: is this specific output (txid + index) still unspent right now?

Terminal window
# Is output #0 of this transaction still unspent?
bitcoin-cli gettxout 6dcf...e1a4 0
{
"bestblock": "0000000000000000000223...e9a1",
"confirmations": 142,
"value": 0.04200000,
"scriptPubKey": { "address": "bc1q...k8", "type": "witness_v0_keyhash" },
"coinbase": false
}

If it returns null, that output has already been spent (or never existed). This is profound: “your balance” is nothing but the sum of UTXOs whose locking scripts your keys can satisfy. The node doesn’t store balances — it stores unspent outputs. See UTXO set vs. the chain for why this distinction matters.

Transactions that are valid but not yet mined sit in the mempool. getmempoolinfo summarizes it:

Terminal window
bitcoin-cli getmempoolinfo
{
"size": 14207,
"bytes": 8123456,
"usage": 41553120,
"mempoolminfee": 0.00001000,
"minrelaytxfee": 0.00001000
}

size is how many transactions are queued; mempoolminfee is the current price of admission (transactions paying less are dropped when it fills). The mempool is the fee market in action — miners pick the highest-fee transactions first. To list the actual txids, use getrawmempool. Read more in the network section’s coverage of the P2P protocol and how transactions propagate before confirmation.

Each of these RPCs is a question your node answers from its own verified copy of the ledger. You ask “is this output spent?” and get the truth — not because you trust a server, but because your node independently rebuilt the UTXO set from genesis. That’s how untrusting strangers share one ledger: each can interrogate it directly and get the same answer.

  1. Use getblockhash + getblock to fetch block 0 (genesis). What’s unusual about its previousblockhash?
  2. Pick any txid, run getrawtransaction <txid> true, and identify each input’s txid:vout reference. What prior outputs is it spending?
  3. Run gettxout on an output you know was spent. What do you get back, and why?
  4. Check getmempoolinfo. What is mempoolminfee right now, and what does it tell you about demand for block space?
  5. Run bitcoin-cli help getblock. What does verbosity level 2 add over level 1?