区块链技术的兴起催生了大量去中心化应用(DApp),而与区块链交互是开发这些应用的核心能力。对于Python开发者来说,**Web3.py**库是连接以太坊区块链的利器------它提供了完整的API,让你可以轻松查询区块数据、发送交易、与智能合约交互。本文将从基础到实战,带你掌握Web3.py的核心用法。
一、Web3.py是什么?为什么需要它?
Web3.py是以太坊官方推荐的Python库,用于与以太坊区块链节点通信。无论是开发DApp后端、编写区块链数据分析工具,还是自动化智能合约交互,Web3.py都能满足需求。其核心功能包括:
-
连接以太坊节点(本地节点或Infura等公共节点)
-
查询区块链数据(区块、交易、账户余额等)
-
签名并发送交易(转账、调用合约等)
-
与智能合约交互(读取状态、执行方法)
二、环境准备:安装与基础配置
1. 安装Web3.py
使用pip安装核心库,同时建议安装eth-account用于账户管理:
bash
pip install web3 eth-account
2. 连接以太坊节点
与区块链交互需要连接一个以太坊节点。如果你没有本地节点,可以使用**Infura**提供的公共节点(免费注册获取API密钥):
-
注册Infura:https://infura.io/
-
创建项目后,获取测试网(如Sepolia)或主网的RPC地址(格式:
https://sepolia.infura.io/v3/``你的API密钥)
三、基础操作:查询区块链数据
让我们从最简单的区块链查询开始,熟悉Web3.py的基本用法。
1. 初始化Web3实例
python
from web3 import Web3
# 连接Infura的Sepolia测试网节点(替换为你的API密钥)
infura_url = "https://sepolia.infura.io/v3/你的API密钥"
w3 = Web3(Web3.HTTPProvider(infura_url))
# 检查连接是否成功
if w3.is_connected():
print("✅ 已成功连接到以太坊测试网")
else:
print("❌ 连接失败,请检查节点地址")
2. 查询区块信息
获取最新区块号、指定区块的详细数据:
python
# 获取最新区块号
latest_block_number = w3.eth.block_number
print(f"最新区块号:{latest_block_number}")
# 获取指定区块的详细信息(full_transactions=True表示返回完整交易数据)
block = w3.eth.get_block(latest_block_number, full_transactions=True)
print(f"区块哈希:{block['hash'].hex()}") # 哈希需转为十六进制字符串
print(f"区块包含的交易数:{len(block['transactions'])}")
print(f"区块时间戳:{block['timestamp']}") # 时间戳可转为北京时间
3. 查询账户余额
以太坊中余额以wei为单位(1 ETH = 10^18 wei),Web3.py提供了单位转换工具:
python
# 示例账户(Sepolia测试网的一个公开账户)
address = "0x742d35Cc6634C0532925a3b844Bc454e4438f44e"
# 获取余额(单位:wei)
balance_wei = w3.eth.get_balance(address)
# 转换为ETH
balance_eth = w3.from_wei(balance_wei, "ether")
print(f"账户 {address} 的余额:{balance_eth} ETH")
四、进阶实战:发送以太坊交易
发送交易是与区块链交互的核心功能,包括ETH转账、调用智能合约等。以下示例演示如何向指定地址转账测试网ETH(需先在Sepolia测试网 faucet获取测试ETH)。
1. 准备发送账户
需要一个包含私钥的账户(**注意:私钥绝对不能泄露!**):
python
from eth_account import Account
# 你的私钥(仅测试用,生产环境需用安全方式存储)
private_key = "你的私钥(64位十六进制字符串)"
# 从私钥创建账户
account = Account.from_key(private_key)
sender_address = account.address
print(f"发送账户地址:{sender_address}")
print(f"发送账户余额:{w3.from_wei(w3.eth.get_balance(sender_address), 'ether')} ETH")
2. 构建并发送交易
python
# 接收地址
recipient_address = "0x接收地址"
# 构建交易参数
transaction = {
"to": recipient_address,
"value": w3.to_wei(0.001, "ether"), # 转账0.001 ETH(转为wei)
"gas": 21000, # 简单转账的固定gas限制
"gasPrice": w3.eth.gas_price, # 获取当前gas价格
"nonce": w3.eth.get_transaction_count(sender_address), # 防止交易重复
"chainId": 11155111 # Sepolia测试网的chainId(主网为1)
}
# 用私钥签名交易
signed_txn = w3.eth.account.sign_transaction(transaction, private_key)
# 发送交易并获取交易哈希
tx_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction)
print(f"交易已发送,哈希:{tx_hash.hex()}")
# 等待交易确认(可选,最多等待60秒)
tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash, timeout=60)
if tx_receipt["status"] == 1:
print(f"✅ 交易确认成功,区块号:{tx_receipt['blockNumber']}")
else:
print("❌ 交易失败")
关键参数说明:
-
nonce:账户发送的交易序号,必须递增,防止交易被重复处理; -
gas:交易允许消耗的最大gas量(简单转账固定为21000); -
gasPrice:每单位gas的价格(以wei为单位),可通过w3.eth.gas_price获取当前网络建议值; -
chainId:指定区块链网络(防止交易被发送到其他网络)。
五、智能合约交互:以ERC20代币为例
智能合约是区块链上的程序,Web3.py可以通过合约ABI(应用二进制接口)与合约交互。以下以ERC20代币合约为例,演示查询余额和转账操作。
1. 准备合约信息
需要合约地址和ABI(可从Etherscan获取,或从合约源代码编译):
python
# 示例:Sepolia测试网上的一个ERC20代币合约(USDC测试币)
contract_address = "0x5FbDB2315678afecb367f032d93F642f64180aa3"
# ERC20合约的简化ABI(包含balanceOf和transfer方法)
erc20_abi = [
{
"constant": True,
"inputs": [{"name": "_owner", "type": "address"}],
"name": "balanceOf",
"outputs": [{"name": "balance", "type": "uint256"}],
"type": "function"
},
{
"constant": False,
"inputs": [
{"name": "_to", "type": "address"},
{"name": "_value", "type": "uint256"}
],
"name": "transfer",
"outputs": [{"name": "success", "type": "bool"}],
"type": "function"
}
]
# 创建合约实例
contract = w3.eth.contract(address=contract_address, abi=erc20_abi)
2. 读取合约状态(查询代币余额)
python
# 查询发送账户的代币余额
token_balance_wei = contract.functions.balanceOf(sender_address).call()
# ERC20代币通常有18位小数,转换为可读单位
token_balance = token_balance_wei / (10 **18)
print(f"账户 {sender_address} 的代币余额:{token_balance} USDC")
3. 执行合约方法(代币转账)
python
# 转账目标地址和数量(转账1 USDC,需转为最小单位:1 * 10^18)
to_address = "0x接收地址"
amount = 1 * (10** 18) # 1 USDC
# 构建转账交易
transfer_txn = contract.functions.transfer(to_address, amount).build_transaction({
"from": sender_address,
"gas": 100000, # 代币转账的gas通常比ETH转账高
"gasPrice": w3.eth.gas_price,
"nonce": w3.eth.get_transaction_count(sender_address)
})
# 签名并发送交易(与ETH转账流程相同)
signed_transfer_txn = w3.eth.account.sign_transaction(transfer_txn, private_key)
transfer_tx_hash = w3.eth.send_raw_transaction(signed_transfer_txn.rawTransaction)
print(f"代币转账交易哈希:{transfer_tx_hash.hex()}")
# 等待确认
transfer_receipt = w3.eth.wait_for_transaction_receipt(transfer_tx_hash)
if transfer_receipt["status"] == 1:
print("✅ 代币转账成功")
六、常见问题与最佳实践
-
私钥安全:绝对不要将私钥硬编码在代码中,生产环境应使用加密存储(如AWS KMS、HashiCorp Vault)或硬件钱包(如MetaMask通过Web3连接)。
-
网络选择:开发阶段优先使用测试网(Sepolia、Goerli),避免在主网进行调试操作。
-
Gas优化 :复杂合约交互需估算gas消耗,可使用
contract.functions.method().estimate_gas()获取建议值。 -
错误处理:区块链操作可能因网络拥堵、gas不足等失败,务必添加异常捕获:
pythontry: # 发送交易代码 except Exception as e: print(f"交易失败:{str(e)}")
七、总结与扩展学习
Web3.py为Python开发者打开了区块链世界的大门,本文介绍的查询区块、发送交易、合约交互是核心基础。后续可探索更多高级功能:
-
事件监听(通过
contract.events.EventName().create_filter()跟踪合约事件) -
批量交易处理(使用
web3.middleware处理高并发) -
与DeFi协议交互(如Uniswap、Aave等,需参考其合约ABI)
官方文档是最好的学习资源:Web3.py官方文档,配合以太坊测试网实践,能快速掌握区块链开发技能。
如果你有具体的应用场景(如NFT铸造、链上数据分析),可以基于本文的基础进一步扩展,Web3.py的灵活性足以支持各种区块链创新应用~