以太坊 API 文档 Python 编程指南:从入门到实践
以太坊作为全球领先的智能合约平台和去中心化应用(DApp)生态系统,为开发者提供了丰富的可能性,而 Python,凭借其简洁的语法、强大的库支持和广泛的应用场景,成为了与以太坊区块链进行交互的热门语言,本文将为您详细解读如何利用以太坊 API 文档,并结合 Python 进行开发,助您轻松构建与以太坊网络通信的应用程序。
核心概念:以太坊 API 与 Python 的桥梁
在深入代码之前,我们需要理解几个核心概念:
- 以太坊节点 (Ethereum Node):运行以太坊协议的软件实例,如 Geth、OpenEthereum(原 Parity)或 Infura 等远程节点,它维护区块链的状态,处理交易,并提供 API 接口。
- JSON-RPC API:这是以太坊节点最常用的一种 API 标准,它定义了一系列标准的远程过程调用(RPC)方法,允许客户端(如我们的 Python 脚本)通过 HTTP 或 WebSocket 协议与节点进行通信,每个方法通常接收一个 JSON 格式的请求并返回一个 JSON 格式的响应。
- Python 库:直接手动构建 JSON 请求并解析响应虽然可行,但非常繁琐,幸运的是,有许多优秀的 Python 库封装了 JSON-RPC API 的细节,使得与以太坊交互变得异常简单,最常用的库包括 Web3.py。
准备工作:安装 Web3.py
Web3.py 是目前 Python 社区与以太坊交互事实上的标准库,它提供了与以太坊节点交互、智能合约部署与调用、钱包管理等功能。

您需要安装 Web3.py,可以通过 pip 进行安装:
pip install web3
您可能还需要一些额外的库,例如处理以太坊单位(如 Wei, Ether)的 eth-utils:
pip install eth-utils
连接以太坊节点:API 文档的起点
要与以太坊网络交互,第一步是连接到一个以太坊节点,您可以选择运行自己的本地节点,或者使用 Infura、Alchemy 等第三方服务提供的远程节点,对于初学者,使用 Infura 的免费节点是便捷的选择。
获取 Infura 节点 URL:
- 访问 Infura 官网 并注册账号。
- 创建一个新的项目,选择网络(如 Mainnet for Ethereum, Goerli for Testnet)。
- 获取项目的 Project ID,然后构造节点 URL,
https://mainnet.infura.io/v3/YOUR_PROJECT_ID
连接代码示例:

from web3 import Web3
infura_url = "https://mainnet.infura.io/v3/YOUR_PROJECT_ID"
# 创建 Web3 实例
w3 = Web3(Web3.HTTPProvider(infura_url))
# 检查连接是否成功
if w3.is_connected():
print(f"成功连接到以太坊节点!链 ID: {w3.eth.chain_id}")
else:
print("连接失败!请检查节点 URL 和网络连接。")
探索以太坊 API 文档:Web3.py 如何映射 JSON-RPC
虽然 Web3.py 封装了底层细节,但理解其与 JSON-RPC API 的对应关系对于调试和深入学习至关重要,以太坊官方的 JSON-RPC API 文档是所有操作的“圣经”。
以太坊官方 JSON-RPC API 文档参考: https://eth.wiki/json-rpc/API
Web3.py 的方法名和功能与 JSON-RPC 方法高度对应。
| JSON-RPC 方法 | Web3.py 方法/属性示例 | 描述 |
|---|---|---|
eth_blockNumber |
w3.eth.block_number |
获取最新区块号 |
eth_getBalance |
w3.eth.get_balance(account_address) |
获取账户余额 |
eth_getTransactionCount |
w3.eth.get_transaction_count(account_address) |
获取账户交易 nonce |
eth_sendRawTransaction |
w3.eth.send_raw_transaction(signed_tx) |
发送原始交易 |
eth_call |
w3.eth.call(contract_function) |
调用智能合约(不修改状态) |
eth_estimateGas |
w3.eth.estimateGas(transaction) |
估算交易 gas 消耗 |
实战案例:使用 Web3.py 和 API 文档
让我们通过几个常见操作来体会如何结合 API 文档和 Python 进行开发。
获取账户余额

假设我们想查询以太坊主网上某个地址的余额。
from web3 import Web3
# 初始化连接 (同上)
infura_url = "https://mainnet.infura.io/v3/YOUR_PROJECT_ID"
w3 = Web3(Web3.HTTPProvider(infura_url))
if w3.is_connected():
# 要查询的以太坊地址
address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" # Uniswap V2 Router
# 确保地址是 checksum 格式
checksum_address = Web3.to_checksum_address(address)
# 调用 eth_getBalance (对应 Web3.py 的 get_balance)
# 单位是 Wei
balance_wei = w3.eth.get_balance(checksum_address)
# 将 Wei 转换为 Ether (1 Ether = 10^18 Wei)
balance_eth = w3.from_wei(balance_wei, 'ether')
print(f"地址 {checksum_address} 的余额是: {balance_eth} ETH")
发送交易(简化版)
发送交易比查询复杂,需要构造交易对象、签名交易,这里我们只展示构造交易对象的部分,它直接映射到 JSON-RPC 的 eth_sendTransaction 或 eth_sendRawTransaction 参数。
from web3 import Web3
from eth_account import Account # 需要安装: pip install eth-account
# 初始化连接 (同上)
infura_url = "https://mainnet.infura.io/v3/YOUR_PROJECT_ID"
w3 = Web3(Web3.HTTPProvider(infura_url))
if w3.is_connected():
# 发送方和接收方地址
sender_address = "YOUR_SENDER_ADDRESS_WITH_CHECKSUM" # 替换为你的地址 (checksum格式)
receiver_address = "0x742d35Cc6634C0532925a3b844Bc454e4438f44e" # 示例接收地址
# 发送方私钥 (实际项目中务必安全存储,不要硬编码!)
private_key = "YOUR_PRIVATE_KEY" # 替换为你的私钥
# 1. 获取 nonce
nonce = w3.eth.get_transaction_count(sender_address)
# 2. 构造交易字典 (对应 JSON-RPC 交易参数)
transaction = {
'nonce': nonce,
'to': receiver_address,
'value': w3.to_wei(0.01, 'ether'), # 发送 0.01 ETH
'gas': 21000, # 转账交易的最小 gas
'gasPrice': w3.eth.gas_price, # 获取当前建议的 gasPrice
'chainId': w3.eth.chain_id, # 链 ID,防止重放攻击
}
# 3. 签名交易 (使用 eth_account 库)
signed_txn = w3.eth.account.sign_transaction(transaction, private_key)
# 4. 发送交易 (对应 eth_sendRawTransaction)
try:
tx_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction)
print(f"交易已发送! 交易哈希: {w3.to_hex(tx_hash)}")
except Exception as e:
print(f"发送交易失败: {e}")
与智能合约交互
与智能合约交互需要合约的 ABI (Application Binary Interface) 和地址。
# 假设我们有一个简单的 ERC20 代币合约
# 合约地址: 0x6B175474E89094C44Da98b954EedeAC495271d0F (DAI)
# 合约 ABI (简化版,实际 ABI 更长)
erc20_abi = [
{
"constant": True,
"inputs": [{"name": "_owner", "type": "address"}],
"name": "balanceOf",
"outputs": [{"name": "balance", "type": "uint256"}],
"type": "function"
}
]
contract_address = "0x6B175474
