Parsing and Analyzing Bitcoin Blocks
How to retrieve, decode, and analyze Bitcoin block data using Bitcoin Core RPC. Extract transactions, calculate statistics, and build block explorers with getblock, getblockstats, and related commands.
Retrieving Block Data
Bitcoin Core provides multiple levels of detail when querying blocks. The getblock command accepts a verbosity parameter that controls what you get back:
Verbosity 0 returns the raw block as a hex-encoded string. This is compact but requires parsing the binary block format yourself.
Verbosity 1 (default) returns a JSON object with block header fields and an array of transaction IDs. This is the most common level for applications that need to know which transactions are in a block.
Verbosity 2 returns the full JSON with decoded transaction data included. This is the most detailed but also the largest response — for blocks with thousands of transactions, the response can be several megabytes.
To get a block, you need its hash. Use getblockhash with a height to convert block numbers to hashes, or getbestblockhash for the latest block.
Block Headers
The block header is an 80-byte structure that contains the essential metadata. getblockheader returns this data without the full transaction list, making it much lighter than getblock.
Key header fields: version (protocol rules the block follows), previousblockhash (links to the parent block), merkleroot (cryptographic commitment to all transactions), time (miner-reported timestamp), bits (encoded difficulty target), and nonce (the value the miner adjusted to find a valid hash).
The confirmations field tells you how many blocks have been built on top of this one. More confirmations means higher certainty that the block is permanent.
For applications that need to track the chain but don't need transaction details, polling getblockheader is efficient.
Block Statistics
getblockstats computes detailed statistics for any block. This command does analysis that would otherwise require parsing every transaction:
avgfee and avgfeerate — average transaction fee and fee rate in the block. totalfee — total fees collected by the miner. txs — number of transactions. ins and outs — total inputs and outputs across all transactions. avgtxsize — average transaction size. segwit_txs — number of SegWit transactions. subsidy — the block reward (currently 3.125 BTC after the 2024 halving).
This is invaluable for fee market analysis, block space utilization studies, and building analytics dashboards. You can request specific stats by name to reduce computation if you only need a few fields.
Chain-Level Analysis
For broader analysis beyond individual blocks, getchaintxstats computes statistics over a window of blocks: total transaction count, transaction rate per second, and the time window covered.
getblockfilter retrieves BIP 157 compact block filters, which allow light clients to efficiently determine whether a block contains transactions relevant to them without downloading the full block. If you're building a lightweight application, this is far more efficient than scanning every block.
For tracking chain reorganizations and forks, getchaintips returns all known chain tips, including orphaned branches. The status field tells you whether each tip is active (part of the best chain), valid-fork (valid but not the best chain), or invalid.
Building a Block Explorer
To build a basic block explorer with Bitcoin Core RPC:
Start with getblockcount to know the current chain height. Iterate through blocks using getblockhash and getblock. For each block, extract the transaction IDs and use getrawtransaction with verbose=true to decode each transaction.
For search functionality, you need txindex=1 in your bitcoin.conf — without it, getrawtransaction only works for transactions in your wallet or in the UTXO set.
Performance tip: getblock with verbosity 2 is faster than calling getblock followed by getrawtransaction for each transaction, because it avoids the per-transaction lookup overhead. For high-throughput applications, consider using the ZMQ notification interface (getzmqnotifications) to receive new blocks in real-time instead of polling.