比特幣網路數據 API 整合教學

學習使用 API 獲取比特幣網路數據,包括區塊、記憶池、費用估算等,建立個人監控儀表板。

比特幣網路數據 API 整合教學

本教學介紹如何透過 API 獲取比特幣網路的即時數據,用於建立個人儀表板或自動化監控系統。同時深入探討比特幣 P2P 網路的運作機制,幫助開發者理解數據背後的系統架構。

比特幣 P2P 網路運作機制

節點發現與連接

比特幣網路採用點對點(P2P)架構,每個節點通過 TCP 連接與其他節點通訊,預設使用端口 8333(主網)或 18333(測試網)。

節點發現流程

比特幣節點通過 DNS 種子(DNS Seed)獲取初始對等節點列表。比特幣社區維護多個 DNS seed,解析這些域名可獲得一批比特幣節點的 IP 地址:

seed.bitcoin.sipa.be
dnsseed.bluematt.me
dnsseed.bitcoin.dashjr.org
seed.bitcoinstats.com

節點啟動後會嘗試連接到這些 DNS 种子解析出的 IP 地址,建立初始連接。首次連接成功後,節點會相互交換已知節點列表,逐步擴展其對等網路。

地址傳播機制(Addr)

節點通過 addr 消息相互分享已知節點的 IP 地址和端口。當收到新地址時,節點會驗證地址的有效性並將其添加到本地資料庫,然後在後續通信中向其他節點傳播這些地址。這種機制確保了網路的去中心化和節點發現的彈性。

交易傳播機制

比特幣交易的傳播遵循「泛洪算法」(Flooding Algorithm)的變體,確保交易在整個網路中快速傳播。

交易傳播流程

1. 用戶廣播交易到一個或多個相連節點
2. 接收節點驗證交易有效性
3. 驗證通過後,節點將交易轉發給所有相連節點(除了來源節點)
4. 重複步驟 2-3,直到交易被大多數節點接收

交易驗證清單

節點在轉發交易前會執行以下驗證:

記憶池(MemPool)管理

驗證通過但尚未確認的交易會被保存在記憶池中。節點的記憶Pool 有大小限制(預設 300MB),當記憶Pool 滿時,會根據手續費率選擇性地剔除低費用交易。記憶Pool 中的交易會持續被廣播和驗證,直到被確認收入區塊或因超時被清除。

區塊傳播與同步

區塊的傳播比交易更為重要,因為它涉及比特幣共識機制的核心。

區塊傳播機制

比特幣使用「區塊傳播協議」(Block Propagation Protocol)來高效傳播新区块。2016 年引入的 Compact Block Relay 協議大幅減少了區塊傳輸的頻寬使用:

原始區塊傳輸:
- 需要傳輸完整區塊(約 1-2MB)
- 延遲較高,頻寬消耗大

Compact Block Relay:
- 只傳輸區塊頭和交易 ID 列表
- 接收節點從記憶Pool 匹配交易
- 缺失的交易再單獨請求
- 通常只需傳輸數十KB

區塊同步流程

新節點加入網路時需要同步整個區塊鏈。同步過程如下:

1. 下載區塊頭鏈(Headers Sync)
   - 從對等節點獲取所有區塊頭
   - 建立最长標頭鏈

2. 區塊同步(Block Sync)
   - 並行下載區塊數據
   - 驗證每個區塊的工作量證明
   - 驗證交易有效性

3. 初始區塊下載完成(IBD)
   - 節點開始接收新交易和區塊

區塊驗證過程

每個區塊都必須通過嚴格的共識驗證:

P2P 協議消息類型

比特幣 P2P 協議使用多種消息類型進行通信:

消息類型功能
version交換協議版本和節點資訊
verack確認版本握手
addr傳播節點地址
inv廣告可用對象(交易/區塊)
getdata請求特定對象
block發送完整區塊
tx發送交易
merkleblock發送 Merkle 證明的區塊
cmpctblock壓縮區塊(Compact Block)
getheaders請求區塊頭
ping連接存活檢測

常用比特幣 API 服務

免費 API 服務

1. Blockchain.info API

比特幣區塊鏈數據的知名服務商。

基本端點

GET https://blockchain.info/stats
GET https://blockchain.info/blocks/{hash}
GET https://blockchain.info/rawaddr/{address}

費用:免費版本有頻率限制

2. mempool.space API

專注於比特幣記憶池數據的開源 API。

主要端點

GET https://mempool.space/api/blocks/tip/hash
GET https://mempool.space/api/mempool
GET https://mempool.space/api/fees/recommended
GET https://mempool.space/api/address/{address}

特色

3. Blockstream API

Blockstream 提供的比特幣與 Liquid 網路數據 API。

端點

GET https://blockstream.info/api/blocks/tip/hash
GET https://blockstream.info/api/block/{hash}
GET https://blockstream.info/api/address/{address}/txs

付費 API 服務

4. CoinGecko API

提供比特幣價格與市場數據。

5. CryptoCompare API

全面的加密貨幣市場數據 API。

實際整合範例

Node.js 獲取區塊數據

const axios = require('axios');

async function getBitcoinStats() {
  try {
    const response = await axios.get('https://blockchain.info/stats');
    return {
      hashrate: response.data.hash_rate,
      blocks: response.data.n_blocks,
      difficulty: response.data.difficulty,
      transactions: response.data.txes_total
    };
  } catch (error) {
    console.error('Error fetching data:', error.message);
  }
}

getBitcoinStats().then(console.log);

Python 獲取費用估算

import requests
import json

def get_fees():
    url = "https://mempool.space/api/fees/recommended"
    response = requests.get(url)
    data = response.json()
    return {
        "fastestFee": data["fastestFee"],
        "halfHourFee": data["halfHourFee"],
        "hourFee": data["hourFee"],
        "economyFee": data["economyFee"]
    }

if __name__ == "__main__":
    fees = get_fees()
    print(json.dumps(fees, indent=2))

獲取記憶池數據

async function getMempool() {
  const url = 'https://mempool.space/api/mempool';
  const response = await fetch(url);
  const data = await response.json();

  return {
    count: data.count,
    vsize: data.vsize,
    totalFee: data.total_fee,
    maxFee: data.maxFee,
    minFee: data.minFee
  };
}

自建比特幣節點 API

如果你需要更完整的數據控制,可以運行自己的比特幣節點並使用 RPC API。

Bitcoin Core RPC 基本設定

# bitcoin.conf 設定
server=1
rpcuser=your_username
rpcpassword=your_password
rpcport=8332

使用 RPC 獲取網路數據

# 獲取網路資訊
bitcoin-cli getnetworkinfo

# 獲取算力資訊
bitcoin-cli getmininginfo

# 獲取連接數
bitcoin-cli getconnectioncount

# 獲取區塊鏈資訊
bitcoin-cli getblockchaininfo

Python 整合範例

from bitcoinrpc.authproxy import AuthServiceProxy
import settings

rpc_connection = AuthServiceProxy(
    f"http://{settings.RPC_USER}:{settings.RPC_PASSWORD}@127.0.0.1:8332"
)

# 獲取網路資訊
network_info = rpc_connection.getnetworkinfo()

# 獲取記憶池資訊
mempool_info = rpc_connection.getmempoolinfo()

# 獲取難度
difficulty = rpc_connection.getdifficulty()

建立簡單監控儀表板

前端顯示(HTML + JavaScript)

<!DOCTYPE html>
<html>
<head>
  <title>比特幣網路監控</title>
  <style>
    body { font-family: Arial; padding: 20px; }
    .metric { margin: 10px 0; padding: 10px; background: #f0f0f0; }
    .value { font-size: 24px; font-weight: bold; color: #f7931a; }
  </style>
</head>
<body>
  <h1>比特幣網路狀態</h1>

  <div class="metric">
    <div>建議費用 (sat/vB)</div>
    <div class="value" id="fees">載入中...</div>
  </div>

  <div class="metric">
    <div>記憶池交易數</div>
    <div class="value" id="mempool-count">載入中...</div>
  </div>

  <div class="metric">
    <div>最新區塊</div>
    <div class="value" id="blocks">載入中...</div>
  </div>

  <script>
    async function updateStats() {
      // 獲取費用
      const fees = await fetch(
        'https://mempool.space/api/fees/recommended'
      ).then(r => r.json());
      document.getElementById('fees').textContent =
        `最快: ${fees.fastestFee} | 中等: ${fees.halfHourFee}`;

      // 獲取記憶池
      const mempool = await fetch(
        'https://mempool.space/api/mempool'
      ).then(r => r.json());
      document.getElementById('mempool-count').textContent = mempool.count;

      // 獲取最新區塊
      const blocks = await fetch(
        'https://mempool.space/api/blocks/tip/hash'
      ).then(r => r.text());
      document.getElementById('blocks').textContent = blocks.substring(0, 16) + '...';
    }

    updateStats();
    setInterval(updateStats, 60000); // 每分鐘更新
  </script>
</body>
</html>

API 使用最佳實踐

頻率限制處理

錯誤處理

async function fetchWithRetry(url, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await fetch(url);
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      return await response.json();
    } catch (error) {
      if (i === retries - 1) throw error;
      await new Promise(r => setTimeout(r, 1000 * Math.pow(2, i)));
    }
  }
}

安全性考量

常見問題

Q: 免費 API 有何限制?

A: 通常有每分鐘請求次數限制,適合開發測試,生產環境建議使用付費方案或自建節點。

Q: 如何選擇合適的 API?

A: 考慮以下因素:數據需求、頻率限制、費用、穩定性、是否需要開源。

Q: 自建節點需要多少資源?

A: 完整節點需要約 600GB 儲存空間和穩定網路頻寬。


相關文章

延伸閱讀與來源

這篇文章對您有幫助嗎?

評論

發表評論

注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。

目前尚無評論,成為第一個發表評論的人吧!