在数字货币领域,及时掌握比特币地址的余额动态是开发者与投资者的常见需求。本文将引导你使用 Python 编写简洁高效的脚本,通过公开 API 查询任意比特币地址的余额,无需依赖第三方钱包应用。
前置知识回顾
在之前的讨论中,我们介绍了如何使用 Python 生成比特币的公私钥对,并将其存储在二维数组中。本文将在该基础上,进一步实现通过 HTTP 请求查询地址余额的功能。
核心代码解析
以下为完整的 Python 实现代码,涵盖密钥生成、地址转换及余额查询全流程:
import secrets
import hashlib
import base58
import ecdsa
import numpy as np
import requests
def generate_private_key():
# 使用加密安全随机数生成器生成 32 字节随机数据
random_bytes = secrets.token_bytes(32)
# 将字节转换为十六进制表示
private_key_hex = random_bytes.hex()
return private_key_hex
def private_key_to_WIF(private_key_hex):
# 添加前缀字节 0x80 表示比特币私钥
prefix_and_key = "80" + private_key_hex
# 计算前缀与密钥的双重 SHA256 哈希
hash_bytes = hashlib.sha256(hashlib.sha256(bytes.fromhex(prefix_and_key)).digest()).digest()
# 取哈希的前 4 字节作为校验和
checksum = hash_bytes[:4].hex()
# 将校验和添加到前缀与密钥末尾
prefix_key_checksum = prefix_and_key + checksum
# 对结果进行 base58 编码
wif_private_key = base58.b58encode(bytes.fromhex(prefix_key_checksum)).decode('utf-8')
return wif_private_key
def private_key_to_public_key(private_key_hex):
# 将私钥从十六进制转换为字节
private_key_bytes = bytes.fromhex(private_key_hex)
# 创建 ECDSA SECP256k1 曲线对象
curve = ecdsa.curves.SECP256k1
# 从私钥字节创建签名密钥
signing_key = ecdsa.SigningKey.from_string(private_key_bytes, curve=curve)
# 从签名密钥获取验证密钥(公钥)
verifying_key = signing_key.get_verifying_key()
# 将公钥转换为未压缩格式,再转换为十六进制
public_key_bytes = b"\x04" + verifying_key.to_string()
public_key_hex = public_key_bytes.hex()
return public_key_hex
def public_key_to_address(public_key_hex):
# 将公钥从十六进制转换为字节
public_key_bytes = bytes.fromhex(public_key_hex)
# 对公钥应用 SHA-256
hash1 = hashlib.sha256(public_key_bytes).digest()
# 对 SHA-256 哈希应用 RIPEMD-160
hash2 = hashlib.new('ripemd160', hash1).digest()
# 添加前缀字节 0x00 表示比特币地址
prefix_and_hash = "00" + hash2.hex()
# 计算前缀与哈希的双重 SHA256 哈希
hash_bytes = hashlib.sha256(hashlib.sha256(bytes.fromhex(prefix_and_hash)).digest()).digest()
# 取哈希的前 4 字节作为校验和
checksum = hash_bytes[:4].hex()
# 将校验和添加到前缀与哈希末尾
prefix_hash_checksum = prefix_and_hash + checksum
# 对结果进行 base58 编码
address = base58.b58encode(bytes.fromhex(prefix_hash_checksum)).decode('utf-8')
return address
# 示例用法:生成 n 个密钥对及地址
n = 5
arr = np.empty((n, 2), dtype=np.object)
for i in range(n):
private_key_hex = generate_private_key()
wif_private_key = private_key_to_WIF(private_key_hex)
public_key_hex = private_key_to_public_key(private_key_hex)
address = public_key_to_address(public_key_hex)
arr[i,0] = wif_private_key
arr[i,1] = address
print(arr)
def check_balance(address):
url = f"https://blockchain.info/q/addressbalance/{address}"
response = requests.get(url)
if response.status_code == 200:
balance = int(response.text)
return balance
else:
print(f"Error {response.status_code}: {response.reason}")
return None
# 查询所有生成地址的余额
for i in range(n):
balance = check_balance(arr[i,1])
print("Balance of Bitcoin address:", arr[i,1], "=", balance)余额查询功能详解
check_balance 函数是整个流程的核心,其工作原理如下:
- 接收参数:函数接受一个参数
address,即待查询的比特币地址。 - 构建请求 URL:使用 Blockchain.info 提供的公开 API 端点,将地址嵌入到
https://blockchain.info/q/addressbalance/{address}格式的 URL 中。 - 发送 HTTP 请求:通过
requests.get()方法向该 URL 发送 GET 请求。 处理响应:
- 若状态码为 200(请求成功),则将返回的文本内容(代表余额的整数字符串)转换为整数并返回。
- 若状态码异常,则打印错误信息并返回
None。
环境配置与依赖安装
执行脚本前,需确保已安装必要的 Python 库。其中 requests 库是用于发起 HTTP 请求的关键依赖,可通过以下命令安装:
pip install requests该库以简洁直观的接口著称,极大简化了 Python 中的 HTTP 客户端操作。
应用场景与注意事项
- 批量地址监控:本脚本特别适用于需要同时追踪多个地址余额变动的场景,如交易所监控或资产管理平台。
- API 限制:公开 API 通常有请求频率限制,高频查询需考虑使用专业 API 服务或搭建本地节点。
- 隐私与安全:查询余额无需私钥,但生成和存储私钥时应确保环境安全,避免泄露。
常见问题
1. 为何选择 Blockchain.info 的 API?
Blockchain.info 提供稳定且免费的比特币区块链数据接口,其地址余额查询端点响应迅速、文档清晰,非常适合初学者和小规模应用。
2. 返回的余额单位是什么?
API 返回的余额数值单位为聪(Satoshi),1 比特币等于 1 亿聪。如需转换为 BTC,需将结果除以 100,000,000。
3. 除了余额,还能获取哪些地址信息?
此类 API 通常还可提供交易历史、未花费输出(UTXO)等详细信息,但需调用不同的端点,且请求格式可能更复杂。
4. 脚本执行出现连接错误怎么办?
首先检查网络连接是否正常,其次确认目标 API 服务是否可用。偶尔的服务端限制或维护可能导致短暂不可用。
5. 如何提升批量查询的效率?
可引入异步请求库(如 aiohttp)或多线程技术来并发处理多个地址的查询,显著减少总等待时间。
6. 生成的私钥是否安全?
代码中使用 secrets 模块生成密码学安全的随机数,符合密钥生成的安全要求。但在生产环境中,建议使用经过更严格审计的专业库。
通过本文介绍的方法,你可以快速构建属于自己的比特币余额查询工具,为更复杂的区块链应用开发奠定基础。