关键词:web3.py、web3.eth、Ethereum RPC API、AttributeDict、合约交互、gas 估算、交易撤回
web3.eth 是 web3.py 与以太坊节点进行交互的核心入口,它通过统一的封装屏蔽了底层 Ethereum JSON-RPC 差异,使开发者能够用“Python思维”读取链上数据、广播交易、监听事件与调试合约。本文依据 web3.py 7.12.0 官方文档精炼而来,去芜存菁,拆分属性、方法、过滤器和合约四大模块,并穿插实战示例与高频问答,助你从入门到生产落地一步到位。
1. 入门须知:Eth 实例与 AttributeDict
web3.eth 本身就是 Eth 类的实例,默认返回的数据结构为 AttributeDict,你可以像读对象属性一样取值,又能保持字典特性,但数据不可变。示例:
>>> block = w3.eth.get_block('latest')
>>> block.number # 像访问属性
2206939
>>> block['number'] # 像访问字典
2206939
>>> block.number = 2206940 # 禁止修改
TypeError: This data is immutable ...如要在 IDE 获得完整类型提示,建议关闭 AttributeDictMiddleware 或采用 dict(block) 手动解包。
2. 核心属性一览
| 属性名 | RPC 方法 | 典型用途 |
|---|---|---|
default_account | — | 默认交易发起地址 |
default_block | — | 查询数据时的默认区块标识,默认为 'latest' |
block_number | eth_blockNumber | 最新区块高度 |
chain_id | eth_chainId | 当前链 ID(EIP-155),助你在多链环境快速识别 |
gas_price | eth_gasPrice | 实时 gasPrice,单位 Wei |
max_priority_fee | eth_maxPriorityFeePerGas | EIP-1559 小费建议 |
accounts | eth_accounts | 节点托管钱包地址列表 |
syncing | eth_syncing | 同步状态,布尔或字典 |
3. 高频方法总览
3.1 查询类
get_balance(account, block_identifier)– 指定区块查询地址余额。get_transaction_count(account, ...)– 获取 nonce。get_storage_at(address, position, ...)– 读取合约槽位值。get_code(address, ...)– 拉取 runtime bytecode。get_proof(address, positions, ...)– Merkle 证明,验证轻节点状态。get_block(block_identifier, full_transactions=False)– 区块全量数据或仅哈希列表。get_transaction(tx_hash)/get_raw_transaction(tx_hash)– 查询单笔交易/原始字节。get_transaction_receipt(tx_hash)– 交易回执,看status知失败与否。wait_for_transaction_receipt(..., timeout=120)– 轮询直至上链,写脚本省心。
3.2 模拟与估算
estimate_gas(transaction_dict)– 为未发送交易估计 gas 消耗。create_access_list(...)– 生成 EIP-2930 accessList,降低稀缺状态访问费用。simulateV1(payload, block_identifier)– Getheth_simulateV1预览完整区块状态。call(transaction_dict, ...)– 离线读合约函数返回值。fee_history(block_count, newest_block, reward_percentiles)– EIP-1559 费用历史,绘制 gas 成本曲线。
3.3 发送交易
send_transaction(tx_dict)– 本地节点签名并广播。send_raw_transaction(signed_bytes)– 广播外部已签名交易。sign_transaction(tx_dict)– 本地签名不得广播,配合send_raw_transaction。replace_transaction(tx_hash, new_tx_dict)/modify_transaction(...)– 替换/局部修改待打包交易(更高 gasPrice 或调整小费)。
3.4 事件过滤
filter(filter_params)– 新建日志、区块或 pending 交易过滤器。get_filter_changes(filter_id)/get_filter_logs(filter_id)– 轮询增量日志或完整日志。get_logs(filter_params)– 临时过滤器,“查询-卸载”一步到位。
4. 常用示例
示例 1:批量查询余额并估算 gas
accounts = w3.eth.accounts
balances = [w3.eth.get_balance(a) for a in accounts]
total = sum(balances)
tx = {
'from': accounts[0],
'to': accounts[1],
'value': w3.to_wei(0.01, 'ether')
}
gas = w3.eth.estimate_gas(tx)
print("gas 估算:", gas)示例 2:动态手续费替换交易
tx_hash = w3.eth.send_transaction({
'from': w3.eth.accounts[1],
'to': w3.eth.accounts[0],
'value': 10**15,
'maxFeePerGas': 20*10**9, # 20 gwei
'maxPriorityFeePerGas': 1*10**9,
})
# 需求突变,提高小费加速
new_hash = w3.eth.modify_transaction(
tx_hash,
maxPriorityFeePerGas=4*10**9,
maxFeePerGas=30*10**9
)5. FAQ:高频疑难解析
Q1:AttributeDict 与 dict 用哪个更好?
A:日常编码用 AttributeDict 可读性高;重 IDE 类型提示或大工程建议解包为 dict。
Q2:如何设置默认链?
A:w3 = Web3(Web3.HTTPProvider("https://mainnet.infura.io/v3/xxx")); w3.eth.default_block = "safe",即可一次配置多次复用。
Q3:EIP-1559 gas 比 Legacy 省多少?
A:在拥堵网络可省 5%~20%。官方建议优先 maxFeePerGas 与 maxPriorityFeePerGas。
Q4:get_proof 有什么用?轻节点如何验证?
A:返回某地址在特定区块的账户与存储证明,可用 Merkle Patricia Trie 核验;示例代码已给出,配合轻节点实现无状态验证。
Q5:run_out_of_gas 的常见原因?
A:估算不准、accessList 缺失、state_override 未覆盖复杂前置状态,或为极复杂计算预留过小 gas。
Q6:如何通过过滤器监听合约事件?
A:先 contract.events.EventName.create_filter(...) 拿到 Filter 对象,再轮询 get_new_entries() 或使用 WebSocket 的订阅 API。
6. 结语与下一步
通过本文,你已掌握 web3.eth 全部常用接口及其背后的 Ethereum RPC 语义。下一步可深度研读 合约章节,将“写 Solidity + 读 Python”闭环打通,或结合事件过滤器构建实时后端。保持对 EIP-1559、EIP-2930 等协议演进的关注,才能在未来 gas 机制、账户抽象浪潮中立于不败之地。