Data·On-Chain Data·Beginner

Blockchain Data Fetcher

Fetch on-chain blockchain metrics including transaction counts, active wallet addresses, network hash rate, gas fees, and mempool data from major blockchain data providers and node RPC endpoints for crypto market analysis.

data-engineeringdata-fetchingtechnical-analysis

Blockchain.info Market Data Acquisition Framework

This notebook defines a standardized protocol for interfacing with the Blockchain.info public REST API to retrieve on-chain metric data for a single chart via a single function call.


1. Dependency Installation

[ ]
!pip install requests pandas
Requirement already satisfied: requests in /usr/local/lib/python3.12/dist-packages (2.32.4)
Requirement already satisfied: pandas in /usr/local/lib/python3.12/dist-packages (2.2.2)
Requirement already satisfied: charset_normalizer<4,>=2 in /usr/local/lib/python3.12/dist-packages (from requests) (3.4.7)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.12/dist-packages (from requests) (3.11)
Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.12/dist-packages (from requests) (2.5.0)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.12/dist-packages (from requests) (2026.2.25)
Requirement already satisfied: numpy>=1.26.0 in /usr/local/lib/python3.12/dist-packages (from pandas) (2.0.2)
Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.12/dist-packages (from pandas) (2.9.0.post0)
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.12/dist-packages (from pandas) (2025.2)
Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.12/dist-packages (from pandas) (2026.1)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.12/dist-packages (from python-dateutil>=2.8.2->pandas) (1.17.0)

2. Library Imports

[ ]
import warnings
warnings.filterwarnings("ignore")

import requests
import pandas as pd
from datetime import datetime

Code Logic

  • warnings.filterwarnings("ignore"): Suppresses non-critical runtime warnings to maintain clean output.
  • requests: Handles HTTP communication with the Blockchain.info public REST endpoint.
  • pandas: Provides the DataFrame structure for tabular time-series data.
  • datetime: Supplies datetime objects for date delta computation.

3. Available Chart Types

Blockchain.info exposes the following chart categories via the https://api.blockchain.info/charts/{chart_name} endpoint. Each chart_name value maps directly into the REST path.

3.1 Market Data

Chart NameDescription
market-priceAverage USD market price across major exchanges
market-capTotal USD value of all circulating Bitcoin
trade-volumeUSD value of Bitcoin traded on major exchanges per day
exchange-volumeTotal BTC volume traded on major exchanges per day

3.2 Blockchain Activity

Chart NameDescription
n-transactionsTotal number of confirmed transactions per day
n-unique-addressesNumber of unique addresses used per day
n-transactions-per-blockAverage number of transactions per block
output-volumeTotal BTC output volume per day
estimated-transaction-volumeEstimated BTC transaction volume per day
estimated-transaction-volume-usdEstimated USD transaction volume per day

3.3 Mining & Network

Chart NameDescription
hash-rateEstimated network hash rate in GH/s
difficultyCurrent mining difficulty target
miners-revenueTotal miner revenue (block reward + fees) in USD
transaction-feesTotal BTC paid in transaction fees per day
transaction-fees-usdTotal USD value of transaction fees per day
cost-per-transactionMiner revenue per transaction in USD
n-orphaned-blocksNumber of orphaned blocks per day

3.4 Supply & Distribution

Chart NameDescription
total-bitcoinsTotal number of BTC in circulation
utxo-countNumber of unspent transaction outputs
bitcoin-days-destroyedMeasure of BTC economic activity (age × volume)
average-block-sizeAverage block size in MB
blocks-sizeTotal size of all blocks per day in MB
[ ]
df_fees = fetch_chart("transaction-fees-usd", START_DATE, END_DATE)

print("--- Average Transaction Fee (USD) ---")
display(df_fees.head())
df_fees.info()
--- Average Transaction Fee (USD) ---
timestamp datetime transaction_fees_usd
0 1704067200 2024-01-01 9.397140e+06
1 1704153600 2024-01-02 6.452516e+06
2 1704240000 2024-01-03 6.429705e+06
3 1704326400 2024-01-04 5.546797e+06
4 1704412800 2024-01-05 5.121602e+06
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 8 entries, 0 to 7
Data columns (total 3 columns):
 #   Column                Non-Null Count  Dtype         
---  ------                --------------  -----         
 0   timestamp             8 non-null      int64         
 1   datetime              8 non-null      datetime64[ns]
 2   transaction_fees_usd  8 non-null      float64       
dtypes: datetime64[ns](1), float64(1), int64(1)
memory usage: 324.0 bytes

4. Configuration

[ ]
START_DATE = "2024-01-01"    # Format: YYYY-MM-DD
END_DATE   = "2024-01-08"    # Format: YYYY-MM-DD

BASE_URL   = "https://api.blockchain.info/charts/{chart_name}"

Code Logic

  • START_DATE / END_DATE: ISO 8601 date strings defining the retrieval window applied to all fetch calls below.
  • BASE_URL: Public Blockchain.info chart endpoint. No API key is required. The {chart_name} placeholder is resolved at call time.

5. Data Extraction Function

The fetch_chart function performs a single HTTP GET request to the Blockchain.info charts endpoint, maps the response to a standardized schema, and applies precision-safe type casting.

[ ]
def fetch_chart(chart_name, start_date, end_date):
    start_dt  = datetime.strptime(start_date, "%Y-%m-%d")
    end_dt    = datetime.strptime(end_date,   "%Y-%m-%d")
    days_diff = (end_dt - start_dt).days

    url    = BASE_URL.format(chart_name=chart_name)
    params = {
        "format":   "json",
        "start":    start_date,
        "timespan": f"{days_diff}days",
        "sampled":  "false",
    }

    response = requests.get(url, params=params, timeout=30)
    response.raise_for_status()

    data = response.json().get("values", [])

    if not data:
        return pd.DataFrame()

    column_name = chart_name.replace("-", "_")

    df = pd.DataFrame({
        "timestamp": [int(d["x"])   for d in data],
        "datetime":  pd.to_datetime([d["x"] for d in data], unit="s"),
        column_name: [float(d["y"]) for d in data],
    })

    df = df.astype({"timestamp": "int64", column_name: "float64"})
    df = df.drop_duplicates("timestamp").sort_values("timestamp", ignore_index=True)

    return df

Code Logic

  • datetime.strptime(...): Parses ISO 8601 date strings into datetime objects for delta computation.
  • (end_dt - start_dt).days: Derives the integer day span required by the timespan parameter.
  • BASE_URL.format(chart_name=chart_name): Resolves the {chart_name} placeholder using the provided chart identifier.
  • "format": "json": Instructs the API to return a structured JSON payload.
  • "start": start_date: Anchors the retrieval window to the specified start date.
  • "timespan": f"{days_diff}days": Defines the window width in days. The API returns all data points within this span in a single response — no pagination required.
  • "sampled": "false": Disables API-side data compression, ensuring all available data points are returned.
  • response.raise_for_status(): Raises an HTTPError on any non-2xx response code, surfacing failures immediately.
  • response.json().get("values", []): Extracts the time-series array from the response envelope; defaults to an empty list if the key is absent.
  • chart_name.replace("-", "_"): Converts the hyphenated chart name to a valid DataFrame column identifier (e.g., market-pricemarket_price).
  • [int(d["x"]) for d in data]: Extracts the Unix second timestamp from each data point dict.
  • [float(d["y"]) for d in data]: Extracts the metric value from each data point dict.
  • pd.to_datetime([...], unit="s"): Derives a human-readable datetime column from Unix second timestamps.
  • .astype({...}): Casts columns to typed numerics required for arithmetic computation.
  • .drop_duplicates("timestamp").sort_values(...): Removes duplicate timestamps and enforces chronological ordering.

6. Execution — One Call Per Chart Type

Each cell below demonstrates a single fetch call for one representative chart from each category defined in Section 3.

6.1 Market Data — Price

[ ]
df_price = fetch_chart("market-price", START_DATE, END_DATE)

print("--- Market Price ---")
display(df_price.head())
df_price.info()
--- Market Price ---
timestamp datetime market_price
0 1704067200 2024-01-01 42249.69
1 1704153600 2024-01-02 44176.26
2 1704240000 2024-01-03 44958.98
3 1704326400 2024-01-04 42854.95
4 1704412800 2024-01-05 44190.10
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 8 entries, 0 to 7
Data columns (total 3 columns):
 #   Column        Non-Null Count  Dtype         
---  ------        --------------  -----         
 0   timestamp     8 non-null      int64         
 1   datetime      8 non-null      datetime64[ns]
 2   market_price  8 non-null      float64       
dtypes: datetime64[ns](1), float64(1), int64(1)
memory usage: 324.0 bytes

6.2 Market Data — Trade Volume

[ ]
df_volume = fetch_chart("trade-volume", START_DATE, END_DATE)

print("--- Trade Volume (USD) ---")
display(df_volume.head())
df_volume.info()
--- Trade Volume (USD) ---
timestamp datetime trade_volume
0 1704067200 2024-01-01 1.204915e+08
1 1704153600 2024-01-02 1.914118e+08
2 1704240000 2024-01-03 4.996471e+08
3 1704326400 2024-01-04 5.142611e+08
4 1704412800 2024-01-05 3.149481e+08
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 8 entries, 0 to 7
Data columns (total 3 columns):
 #   Column        Non-Null Count  Dtype         
---  ------        --------------  -----         
 0   timestamp     8 non-null      int64         
 1   datetime      8 non-null      datetime64[ns]
 2   trade_volume  8 non-null      float64       
dtypes: datetime64[ns](1), float64(1), int64(1)
memory usage: 324.0 bytes

6.3 Blockchain Activity — Confirmed Transactions

[ ]
df_txn = fetch_chart("n-transactions", START_DATE, END_DATE)

print("--- Confirmed Transactions Per Day ---")
display(df_txn.head())
df_txn.info()
--- Confirmed Transactions Per Day ---
timestamp datetime n_transactions
0 1704067200 2024-01-01 657752.0
1 1704153600 2024-01-02 367319.0
2 1704240000 2024-01-03 502749.0
3 1704326400 2024-01-04 482557.0
4 1704412800 2024-01-05 420884.0
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 8 entries, 0 to 7
Data columns (total 3 columns):
 #   Column          Non-Null Count  Dtype         
---  ------          --------------  -----         
 0   timestamp       8 non-null      int64         
 1   datetime        8 non-null      datetime64[ns]
 2   n_transactions  8 non-null      float64       
dtypes: datetime64[ns](1), float64(1), int64(1)
memory usage: 324.0 bytes

6.4 Blockchain Activity — Unique Addresses

[ ]
df_addr = fetch_chart("n-unique-addresses", START_DATE, END_DATE)

print("--- Unique Active Addresses Per Day ---")
display(df_addr.head())
df_addr.info()
--- Unique Active Addresses Per Day ---
timestamp datetime n_unique_addresses
0 1704067200 2024-01-01 624628.0
1 1704153600 2024-01-02 550846.0
2 1704240000 2024-01-03 677059.0
3 1704326400 2024-01-04 675009.0
4 1704412800 2024-01-05 645934.0
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 8 entries, 0 to 7
Data columns (total 3 columns):
 #   Column              Non-Null Count  Dtype         
---  ------              --------------  -----         
 0   timestamp           8 non-null      int64         
 1   datetime            8 non-null      datetime64[ns]
 2   n_unique_addresses  8 non-null      float64       
dtypes: datetime64[ns](1), float64(1), int64(1)
memory usage: 324.0 bytes

6.5 Mining & Network — Hash Rate

[ ]
df_hash = fetch_chart("hash-rate", START_DATE, END_DATE)

print("--- Network Hash Rate (GH/s) ---")
display(df_hash.head())
df_hash.info()
--- Network Hash Rate (GH/s) ---
timestamp datetime hash_rate
0 1704067200 2024-01-01 5.548140e+08
1 1704153600 2024-01-02 4.689073e+08
2 1704240000 2024-01-03 5.655523e+08
3 1704326400 2024-01-04 6.085056e+08
4 1704412800 2024-01-05 4.939634e+08
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 8 entries, 0 to 7
Data columns (total 3 columns):
 #   Column     Non-Null Count  Dtype         
---  ------     --------------  -----         
 0   timestamp  8 non-null      int64         
 1   datetime   8 non-null      datetime64[ns]
 2   hash_rate  8 non-null      float64       
dtypes: datetime64[ns](1), float64(1), int64(1)
memory usage: 324.0 bytes

6.6 Mining & Network — Miner Revenue

[ ]
df_revenue = fetch_chart("miners-revenue", START_DATE, END_DATE)

print("--- Miner Revenue (USD) ---")
display(df_revenue.head())
df_revenue.info()
--- Miner Revenue (USD) ---
timestamp datetime miners_revenue
0 1704067200 2024-01-01 5.087515e+07
1 1704153600 2024-01-02 4.351777e+07
2 1704240000 2024-01-03 4.994274e+07
3 1704326400 2024-01-04 5.174221e+07
4 1704412800 2024-01-05 4.291799e+07
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 8 entries, 0 to 7
Data columns (total 3 columns):
 #   Column          Non-Null Count  Dtype         
---  ------          --------------  -----         
 0   timestamp       8 non-null      int64         
 1   datetime        8 non-null      datetime64[ns]
 2   miners_revenue  8 non-null      float64       
dtypes: datetime64[ns](1), float64(1), int64(1)
memory usage: 324.0 bytes

6.7 Mempool — Unconfirmed Transactions

[ ]
df_mempool = fetch_chart("mempool-size", START_DATE, END_DATE)

print("--- Mempool Size (Unconfirmed Transactions) ---")
display(df_mempool.head())
df_mempool.info()
--- Mempool Size (Unconfirmed Transactions) ---
timestamp datetime mempool_size
0 1704067200 2024-01-01 00:00:00 82038643.0
1 1704068100 2024-01-01 00:15:00 83151660.0
2 1704069000 2024-01-01 00:30:00 82448230.0
3 1704069900 2024-01-01 00:45:00 82636299.0
4 1704070800 2024-01-01 01:00:00 82265967.5
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 673 entries, 0 to 672
Data columns (total 3 columns):
 #   Column        Non-Null Count  Dtype         
---  ------        --------------  -----         
 0   timestamp     673 non-null    int64         
 1   datetime      673 non-null    datetime64[ns]
 2   mempool_size  673 non-null    float64       
dtypes: datetime64[ns](1), float64(1), int64(1)
memory usage: 15.9 KB

6.8 Supply — Total BTC in Circulation

[ ]
df_supply = fetch_chart("total-bitcoins", START_DATE, END_DATE)

print("--- Total BTC in Circulation ---")
display(df_supply.head())
df_supply.info()
--- Total BTC in Circulation ---
timestamp datetime total_bitcoins
0 1704068978 2024-01-01 00:29:38 19586168.75
1 1704069091 2024-01-01 00:31:31 19586175.00
2 1704070161 2024-01-01 00:49:21 19586181.25
3 1704070760 2024-01-01 00:59:20 19586187.50
4 1704071678 2024-01-01 01:14:38 19586193.75
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1010 entries, 0 to 1009
Data columns (total 3 columns):
 #   Column          Non-Null Count  Dtype         
---  ------          --------------  -----         
 0   timestamp       1010 non-null   int64         
 1   datetime        1010 non-null   datetime64[ns]
 2   total_bitcoins  1010 non-null   float64       
dtypes: datetime64[ns](1), float64(1), int64(1)
memory usage: 23.8 KB

6.9 Supply — UTXO Count

[ ]
df_utxo = fetch_chart("utxo-count", START_DATE, END_DATE)

print("--- Unspent Transaction Output Count ---")
display(df_utxo.head())
df_utxo.info()
--- Unspent Transaction Output Count ---
timestamp datetime utxo_count
0 1704068978 2024-01-01 00:29:38 154349387.0
1 1704069091 2024-01-01 00:31:31 154348604.0
2 1704070161 2024-01-01 00:49:21 154349266.0
3 1704070760 2024-01-01 00:59:20 154353682.0
4 1704071678 2024-01-01 01:14:38 154355956.0
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1010 entries, 0 to 1009
Data columns (total 3 columns):
 #   Column      Non-Null Count  Dtype         
---  ------      --------------  -----         
 0   timestamp   1010 non-null   int64         
 1   datetime    1010 non-null   datetime64[ns]
 2   utxo_count  1010 non-null   float64       
dtypes: datetime64[ns](1), float64(1), int64(1)
memory usage: 23.8 KB

Conclusion

This notebook provides a robust framework for retrieving various Bitcoin blockchain metrics from the Blockchain.info API. The fetch_chart function standardizes the data acquisition process, allowing for easy and consistent access to market data, blockchain activity, mining and network statistics, and supply and distribution metrics. This allows for rapid exploration and analysis of on-chain data for various research or analytical purposes.