- Web3
- 区块链
【免费下载链接】web3.py
A python interface for interacting with the Ethereum blockchain and ecosystem.
web3.py 是 Ethereum 官方维护的 Python 库,用于与以太坊区块链及生态进行交互,是构建去中心化应用(dapp)、发送交易、部署与调用智能合约、读取区块数据的核心工具。本文以项目根目录 README.md 为主线,结合仓库内 docs/quickstart.rst、docs/overview.rst、docs/providers.rst 等官方文档与web3包源码,系统讲解安装方式、Provider 连接机制、首次链上查询、中间件体系与交易流程,让你读完即可独立上手开发。
一、web3.py 是什么
web3.py 为开发者提供了一套完整的 Python 接口,覆盖以太坊交互的主要场景:读取区块与账户数据、签名与发送交易、部署和调用智能合约、订阅链上事件等。根据 README.md 的定位说明,它的典型用途包括:
- 构建去中心化应用(dapps);
- 与智能合约交互(部署、读取、执行函数);
- 读取区块、余额、交易等链上数据;
- 探索更多以太坊生态能力(如 ENS 域名解析)。
仓库 setup.py 中给出的官方描述为:web3: A Python library for interacting with Ethereum,项目当前版本为8.0.0-beta.2,要求Python 3.10 及以上版本(python_requires=">=3.10, <4"),采用 MIT 许可证。
从 web3/init.py 的导出清单可以看到库的核心公开 API 面貌:
- 入口对象:
Web3(同步)与AsyncWeb3(异步),以及账户工具Account; - Provider 家族:
HTTPProvider、AsyncHTTPProvider、IPCProvider、AsyncIPCProvider、WebSocketProvider、EthereumTesterProvider、AsyncEthereumTesterProvider、AutoProvider,以及基础类BaseProvider、JSONBaseProvider、PersistentConnectionProvider。
其中同步/异步双轨 API 是 web3.py 的一大特点:Web3用于常规同步调用,AsyncWeb3配合await用于高并发异步场景。
二、安装与运行环境准备
根据 README.md,安装非常简单:
python -m pip install web3为了更好的实践体验,建议在独立虚拟环境中安装(官方 docs/quickstart.rst 也强调优先使用 virtualenv),避免依赖冲突。
可选扩展包(extras)
仓库 setup.py 定义了若干 extras,可按需安装:
| extras | 用途 | 主要依赖 |
|---|---|---|
tester | 使用EthereumTesterProvider进行本地测试/原型开发 | eth-tester[py-evm]、py-geth |
dev | 开发者环境(含构建、文档、测试工具) | build、sphinx、pytest、tox、pre-commit、mypy等 |
docs | 构建 Sphinx 文档 | sphinx、sphinx_rtd_theme、towncrier |
test | 运行测试套件 | pytest、pytest-asyncio、hypothesis、flaky等 |
例如测试环境:
python -m pip install "web3[tester]"开发环境完整安装(官方 docs/contributing.rst 中推荐):
python -m pip install -e ".[dev]" pre-commit install核心依赖
web3.py建立在以太坊 Python 生态的多个底层库之上(见 setup.py 的install_requires):eth-abi(ABI 编解码)、eth-account(账户与签名)、eth-utils(工具函数)、hexbytes(十六进制字节对象)、requests(HTTP Provider 底层)、aiohttp(异步 HTTP)、websockets(WebSocket Provider 底层)、pydantic(类型校验)等。
环境变量建议
docs/quickstart.rst 提示:开发环境建议设置PYTHONWARNINGS=default,否则部分弃用警告(deprecation warning)不会显示。
三、认识 Provider:web3.py 如何连接以太坊
web3.py 本身不包含以太坊节点,它需要连接一个节点(本机或远程)才能工作。这种连接在 web3.py 中称为Provider:Provider 负责生成 JSON-RPC 请求,并通过 HTTP、WebSocket 或 IPC socket 将请求提交给节点、取回响应(参见 docs/providers.rst)。
内置 Provider 一览
根据 web3/providers/init.py 的导出与 docs/overview.rst 的说明,库内置以下 Provider:
HTTPProvider:连接 http/https 的 JSON-RPC 服务器(同步);AsyncHTTPProvider:上述服务器的异步版本;IPCProvider:连接 IPC socket 的 JSON-RPC 服务器(同步);AsyncIPCProvider:通过持久连接异步连接 IPC socket;WebSocketProvider:通过持久连接异步连接 WebSocket 服务器;EthereumTesterProvider/AsyncEthereumTesterProvider:集成eth-tester的本地测试 Provider;AutoProvider:自动探测可用 Provider(默认)。
如何选择连接方式
docs/providers.rst 给出了实用的决策建议:
- IPC(本地文件系统 socket):最快且最安全,适合与节点同机部署;
- WebSocket:支持远程,速度优于 HTTP,适合跨机器连接;
- HTTP:兼容性最好,绝大多数节点都支持。
选型原则:能与节点同机运行就选 IPC;必须连接异机节点就选 WebSocket;节点不支持 WebSocket 时退而用 HTTP。
通过环境变量指定 Provider
另一种零代码方式:在启动脚本前设置WEB3_PROVIDER_URI环境变量,web3.py 会优先尝试该 Provider。支持的格式(docs/providers.rst):
file:///path/to/node/rpc-json/file.ipc http://192.168.1.2:8545 https://node.ontheweb.com ws://127.0.0.1:8546底层实现在 web3/providers/auto.py:load_provider_from_environment()读取该变量,load_provider_from_uri()根据 scheme 分派——file对应IPCProvider,http/https对应HTTPProvider。
四、快速上手:三种典型连接方式
1. 测试环境:EthereumTesterProvider
如果只是学习或快速原型验证,官方推荐使用eth-tester测试 Provider:它自带预充值测试以太币的账户,且每笔交易会立即被打包进区块,无需真实节点。需要先安装扩展依赖:
python -m pip install "web3[tester]"然后(代码取自 docs/quickstart.rst):
>>> from web3 import Web3, EthereumTesterProvider >>> w3 = Web3(EthereumTesterProvider()) >>> w3.is_connected() TrueEthereumTesterProvider的实验性定位与构造参数(ethereum_tester、api_endpoints)详见 docs/providers.rst,其默认 RPC 端点定义在 web3/providers/eth_tester/defaults.py。
2. 本地节点:IPC / HTTP / WebSocket
运行自己的以太坊节点(如 Geth)是官方建议的最安全方式。Geth 默认在8545端口提供 HTTP 服务、8546端口提供 WebSocket 服务。连接示例:
>>> from web3 import Web3, AsyncWeb3 # IPCProvider: >>> w3 = Web3(Web3.IPCProvider('./path/to/filename.ipc')) >>> w3.is_connected() True # HTTPProvider: >>> w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545')) >>> w3.is_connected() True # AsyncHTTPProvider: >>> w3 = AsyncWeb3(AsyncWeb3.AsyncHTTPProvider('http://127.0.0.1:8545')) >>> await w3.is_connected() True # -- 持久连接 Provider -- # # WebSocketProvider: >>> w3 = await AsyncWeb3(AsyncWeb3.WebSocketProvider('ws://127.0.0.1:8546')) >>> await w3.is_connected() True # AsyncIPCProvider: >>> w3 = await AsyncWeb3(AsyncWeb3.AsyncIPCProvider('./path/to/filename.ipc')) >>> await w3.is_connected() True不指定ipc_path时,IPCProvider/AsyncIPCProvider会按操作系统使用默认路径(docs/providers.rst):
- Linux / FreeBSD:
~/.ethereum/geth.ipc - macOS:
~/Library/Ethereum/geth.ipc - Windows:
\\.\pipe\geth.ipc
3. 远程节点
最快上手的方式是使用远程节点服务商提供的端点,把端点 URL 直接传给 Provider:
>>> from web3 import Web3, AsyncWeb3 >>> w3 = Web3(Web3.HTTPProvider('https://<your-provider-url>')) >>> w3 = AsyncWeb3(AsyncWeb3.AsyncHTTPProvider('https://<your-provider-url>')) >>> w3 = await AsyncWeb3(AsyncWeb3.WebSocketProvider('wss://<your-provider-url>'))远程场景下节点不掌握你的私钥,交易需要在本地签名后发送(详见后文交易章节)。
五、Provider 配置深入
HTTPProvider
构造签名(docs/providers.rst):
HTTPProvider(endpoint_uri, request_kwargs={}, session=None, exception_retry_configuration=ExceptionRetryConfiguration())endpoint_uri:RPC 端点完整 URI,如'https://localhost:8545';80/443 端口可省略;request_kwargs:透传给每次 HTTP POST 请求的关键字参数,常用于设置超时;session:自定义requests.Session,可调整连接池大小;exception_retry_configuration:异常重试配置实例,设为None可禁用重试。
超时与连接池配置示例:
>>> from web3 import Web3 >>> w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:8545", request_kwargs={'timeout': 60})) >>> import requests >>> adapter = requests.adapters.HTTPAdapter(pool_connections=20, pool_maxsize=20) >>> session = requests.Session() >>> session.mount('http://', adapter) >>> session.mount('https://', adapter) >>> w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:8545", session=session))注意:同一进程内同一 URL 建议只创建一个HTTPProvider(底层会复用 TCP/IP 连接);不同 URL 的多个 Provider 则互不影响。
AsyncHTTPProvider
异步 HTTP Provider 底层基于aiohttp,可通过cache_async_session()传入自定义aiohttp.ClientSession:
>>> from aiohttp import ClientSession >>> from web3 import AsyncWeb3, AsyncHTTPProvider >>> w3 = AsyncWeb3(AsyncHTTPProvider(endpoint_uri)) >>> custom_session = ClientSession() >>> await w3.provider.cache_async_session(custom_session) >>> # 结束时断开 >>> w3.provider.disconnect()持久连接 Provider:WebSocketProvider 与 AsyncIPCProvider
这两个 Provider 继承自PersistentConnectionProvider基类(web3/providers/persistent/init.py),支持eth_subscription订阅、异步收发与自动重连。基类可配置项(docs/providers.rst):
| 参数 | 默认值 | 说明 |
|---|---|---|
request_timeout | 50.0 | 发送请求并等待响应的超时(秒) |
subscription_response_queue_size | 500 | 订阅响应的暂存队列大小 |
silence_listener_task_exceptions | False | 是否静默监听任务抛出的异常 |
max_connection_retries | 5 | 初始化连接时的最大重试次数 |
request_information_cache_size | 500 | 请求信息暂存缓存大小,用于按原始请求处理响应 |
WebSocketProvider(endpoint_uri, websocket_kwargs={}, use_text_frames=False)额外支持:use_text_frames=True时以文本帧发送数据,兼容不支持二进制通信的服务器。
推荐使用async with上下文管理器建立连接,退出时自动关闭:
>>> import asyncio >>> from web3 import AsyncWeb3 >>> from web3.providers.persistent import WebSocketProvider >>> async def subscription_example(): ... async with AsyncWeb3(WebSocketProvider("ws://127.0.0.1:8546")) as w3: ... subscription_id = await w3.eth.subscribe("newHeads") ... async for response in w3.socket.process_subscriptions(): ... print(f"{response}\n") ... if some_condition: ... await w3.eth.unsubscribe(subscription_id) ... break ... latest_block = await w3.eth.get_block("latest") ... print(f"Latest block: {latest_block}") >>> asyncio.run(subscription_example())连接后的核心交互接口是w3.socket(PersistentConnection实例),其 API 包括:subscriptions(当前活跃订阅)、process_subscriptions()(异步迭代订阅消息)、send()/recv()/make_request()(原始收发)。官方建议优先使用各模块的标准方法(如w3.eth.get_block("latest")),避免直接调用原始收发接口——因为原始响应不经过 formatter 格式化和中间件处理。
快捷 Provider:gethdev 与 AutoProvider
连接本地geth --dev(Proof of Authority)开发实例时,可直接使用快捷入口(web3/auto/gethdev.py),它默认注入ExtraDataToPOAMiddleware中间件:
>>> from web3.auto.gethdev import w3 >>> w3.is_connected() True >>> from web3.auto.gethdev import async_w3 >>> await async_w3.provider.connect() >>> await async_w3.is_connected() True此外,不显式传 Provider 创建Web3()时会默认使用AutoProvider(web3/providers/auto.py),它按顺序尝试:WEB3_PROVIDER_URI环境变量 →IPCProvider→HTTPProvider,找到第一个可连接的即作为活跃 Provider。
六、第一次链上查询:读取区块信息
连接建立后,w3实例即可访问以太坊数据。最典型的入门操作是读取最新区块(完整示例见 docs/quickstart.rst):
>>> w3.eth.get_block('latest') {'difficulty': 1, 'gasLimit': 6283185, 'gasUsed': 0, 'hash': HexBytes('0x53b983fe73e16f6ed8178f6c0e0b91f23dc9dad4cb30d0831f178291ffeb8750'), 'logsBloom': HexBytes('0x0000...'), 'miner': '0x0000000000000000000000000000000000000000', 'number': 0, 'parentHash': HexBytes('0x0000...'), 'receiptsRoot': HexBytes('0x56e8...'), 'size': 622, 'stateRoot': HexBytes('0x1f5e...'), 'timestamp': 0, 'totalDifficulty': 1, 'transactions': [], 'transactionsRoot': HexBytes('0x56e8...'), 'uncles': []}返回结果是AttributeDict(由默认中间件AttributeDictMiddleware提供,见 web3/middleware/init.py):它像dict一样支持键访问,同时允许属性访问,且不可修改(docs/web3.eth.rst):
>>> block = w3.eth.get_block('latest') >>> block['number'] # 键访问 0 >>> block.number # 属性访问 0 >>> block.number = 1 # 会抛出 TypeError:数据不可变web3.eth命名空间是最常用的 API 集合(web3/eth/init.py),常用能力包括:
- 读取数据:
get_balance、get_transaction、get_block、get_code、get_storage_at、get_transaction_count、get_proof等; - 发送交易:
send_transaction、sign_transaction、send_raw_transaction、replace_transaction、wait_for_transaction_receipt、estimate_gas等; - 事件与过滤:
subscribe、filter、get_logs、get_filter_changes、uninstall_filter等; - 常用属性:
block_number、gas_price、max_priority_fee、accounts、syncing、default_account、default_block(默认'latest')。
七、Web3 基础工具 API
Web3/BaseWeb3类(web3/main.py)内置了一批高频工具方法,覆盖编码、地址、单位换算与哈希场景:
- 编码解码:
to_bytes()、to_hex()、to_int()、to_text()、to_json()、is_encodable(); - 地址工具:
is_address()、is_checksum_address()、to_checksum_address()(校验和地址); - 货币换算:
to_wei(number, unit)、from_wei(number, unit)——例如w3.to_wei(3, 'ether')返回 3 ETH 对应的 Wei; - 密码学哈希:
keccak()(支持text=、hexstr=、bytes、int多种入参)、solidity_keccak()。
八、中间件(Middleware)体系
中间件是 web3.py 扩展与定制请求的关键机制,其思想是"洋葱模型":请求从最外层进入、层层经过中间件到达 Provider(节点),响应再按相反顺序返回(docs/middleware.rst)。中间件可以修改请求与响应、提前返回结果,甚至让请求不触达 Provider。
默认已启用的中间件(web3/middleware/init.py)包括:AttributeDictMiddleware(属性字典)、ValidationMiddleware(参数校验)、GasPriceStrategyMiddleware(gas 价格策略)、ENSNameToAddressMiddleware(ENS 域名解析)、FormattingMiddlewareBuilder(数据格式化)、PythonicMiddleware等。
运行时可通过w3.middleware_onion调整(docs/overview.rst):
add(middleware, name=None):添加到最外层;inject(middleware, name=None, layer=None):注入到指定层;replace(...)/remove(...)/clear(...):替换、移除、清空。
典型用法——给指定账户自动签名交易(docs/transactions.rst):
from web3.middleware import SignAndSendRawMiddlewareBuilder import os # 注意:切勿把私钥写进代码,请使用环境变量 pk = os.environ.get('PRIVATE_KEY') acct2 = w3.eth.account.from_key(pk) w3.middleware_onion.inject(SignAndSendRawMiddlewareBuilder.build(acct2), layer=0) # 之后来自 acct2 的交易会在中间件层自动签名: tx_hash = w3.eth.send_transaction({ "from": acct2.address, "value": 3333333333, "to": some_address, })中间件的组合逻辑见 web3/middleware/init.py 中的combine_middleware与async_combine_middleware:它们按逆序把各中间件包装在 provider 请求函数外层。
九、发送交易:两种主流路径
docs/transactions.rst 给出了发送交易的决策树:
- 离线签名 / 发送预签名交易:使用
sign_transaction()+send_raw_transaction(); - 固定账户高频发送:配置
SignAndSendRawMiddlewareBuilder中间件后用send_transaction(); - 其他情况:先用
w3.eth.account.from_key(pk)加载账户,再send_transaction()。
测试环境下的快捷发送
EthereumTesterProvider的测试账户由 eth-tester 自动签名:
from web3 import Web3, EthereumTesterProvider w3 = Web3(EthereumTesterProvider()) acct1 = w3.eth.accounts[0] # eth-tester 预置测试以太币 some_address = "0x0000000000000000000000000000000000000000" tx_hash = w3.eth.send_transaction({ "from": acct1, "to": some_address, "value": 123123123123123 }) tx = w3.eth.get_transaction(tx_hash) assert tx["from"] == acct1真实网络:本地签名后发送
# 加载账户(私钥从环境变量读取) acct = w3.eth.account.from_key(os.environ['PRIVATE_KEY']) # 方式一:send_transaction(配合签名中间件) tx_hash = w3.eth.send_transaction({ "from": acct.address, "to": some_address, "value": w3.to_wei(1, 'ether'), }) # 方式二:sign + send_raw_transaction(离线签名) signed = acct.sign_transaction({ "from": acct.address, "to": some_address, "value": w3.to_wei(1, 'ether'), "nonce": w3.eth.get_transaction_count(acct.address), "gas": 21000, "gasPrice": w3.eth.gas_price, }) tx_hash = w3.eth.send_raw_transaction(signed.raw_transaction)发送后可用w3.eth.wait_for_transaction_receipt(tx_hash)等待并获取交易回执。
十、智能合约、ENS 与批量请求
合约部署与调用
web3.py 支持部署、读取、执行已部署合约(docs/overview.rst)。部署需要先编译合约拿到 ABI 与 bytecode:
ExampleContract = w3.eth.contract(abi=abi, bytecode=bytecode) tx_hash = ExampleContract.constructor().transact() tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) tx_receipt.contractAddress # 部署后的合约地址 # 加载已部署合约并调用函数 deployed_contract = w3.eth.contract(address=tx_receipt.contractAddress, abi=abi) deployed_contract.functions.myFunction(42).transact() # 只读调用(本地执行,不上链) deployed_contract.functions.getMyValue().call() # 42 deployed_contract.caller().getMyValue() # 42(ContractCaller 简洁写法)合约对象的关键 API:Contract.address、Contract.abi、Contract.bytecode、Contract.functions、Contract.events、Contract.constructor()、Contract.encode_abi()等。仓库内置了多份 Solidity 测试合约源码供参考,见 web3/_utils/contract_sources/。
ENS 域名解析
web3.py 内置ens模块(docs/ens_overview.rst),可将ethereum.eth这类可读域名解析为地址。w3.ens实例按需自动创建(基于ENS.from_web3(w3)),例如:
>>> w3.ens.address('ethereum.eth') '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'也支持独立创建:from ens.auto import ns(自动探测)或ENS(provider)、ENS.from_web3(w3);异步场景使用AsyncENS。
批量请求
JSON-RPC 支持批量请求,可用一个请求携带多个调用以减少与节点的往返(docs/web3.main.rst):
with w3.batch_requests() as batch: batch.add(w3.eth.get_block(6)) batch.add(w3.eth.get_block(4)) batch.add(w3.eth.get_block(2)) responses = batch.execute() assert len(responses) == 3十一、继续深入:仓库文档地图
README 指向的官方文档站点内容在本仓库 docs/ 目录下均有对应源文件,可按需深读:
- docs/quickstart.rst:5 分钟上手教程;
- docs/overview.rst:全功能概览;
- docs/providers.rst:各 Provider 完整配置;
- docs/transactions.rst:交易发送决策树与示例;
- docs/middleware.rst:中间件体系详解;
- docs/web3.eth.rst:
web3.ethAPI 全量参考; - docs/ens_overview.rst:ENS 使用指南;
- docs/release_notes.rst:版本变更日志;
- docs/migration.rst:跨大版本迁移指南(如 v6 → v7 的 WebSocketProvider 演进)。
仓库测试套件位于 tests/,例如 tests/core/web3-module/test_import_and_version.py 验证了web3.__version__的存在与类型;集成测试在 tests/integration/ 下(含 Geth HTTP/IPC/WS 场景)。若要参与贡献,可阅读根目录 CONTRIBUTING.md 与 docs/contributing.rst。
至此,你已经掌握了 web3.py 的安装、Provider 选型与配置、首次链上查询、中间件机制和交易发送全流程。下一步建议直接运行一个EthereumTesterProvider示例,再逐步切换到本地 Geth 或远程节点,把本文的代码片段改造成自己的第一个 dapp 应用。
- Web3
- 区块链
【免费下载链接】web3.py
A python interface for interacting with the Ethereum blockchain and ecosystem.
相关推荐
为什么选择LLMs-Zero-to-Hero:初学者到大模型专家的快速通道 🚀
为什么选择LLMs Zero to Hero:初学者到大模型专家的快速通道 🚀 LLMs Zero to Hero是一个专为 大模型初学者 设计的开源项目,提
大模型人工智能预训练示例工程教程TabPFN-3与scikit-learn无缝集成:5个实际案例展示其强大功能
TabPFN 3与scikit learn无缝集成:5个实际案例展示其强大功能 TabPFN 3作为一款革命性的表格预测基础模型,通过其与scikit lear
Newton与Python集成:脚本控制与自动化仿真的完整指南
Newton与Python集成:脚本控制与自动化仿真的完整指南 Newton是一款基于NVIDIA Warp构建的开源GPU加速物理仿真引擎,专为机器人学家和仿
物理引擎机器人
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考