news 2026/10/12 1:52:29

web3.py 入门实战:用 Python 连接以太坊、配置 Provider 与构建链上应用的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
web3.py 入门实战:用 Python 连接以太坊、配置 Provider 与构建链上应用的完整指南
  • Web3
  • 区块链

【免费下载链接】web3.py

A python interface for interacting with the Ethereum blockchain and ecosystem.

项目地址:https://gitcode.com/gh_mirrors/we/web3.py
点击查看免费下载

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 给出了实用的决策建议:

  1. IPC(本地文件系统 socket):最快且最安全,适合与节点同机部署;
  2. WebSocket:支持远程,速度优于 HTTP,适合跨机器连接;
  3. 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() True

EthereumTesterProvider的实验性定位与构造参数(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_timeout50.0发送请求并等待响应的超时(秒)
subscription_response_queue_size500订阅响应的暂存队列大小
silence_listener_task_exceptionsFalse是否静默监听任务抛出的异常
max_connection_retries5初始化连接时的最大重试次数
request_information_cache_size500请求信息暂存缓存大小,用于按原始请求处理响应

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 给出了发送交易的决策树:

  1. 离线签名 / 发送预签名交易:使用sign_transaction()+send_raw_transaction();
  2. 固定账户高频发送:配置SignAndSendRawMiddlewareBuilder中间件后用send_transaction();
  3. 其他情况:先用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.

项目地址:https://gitcode.com/gh_mirrors/we/web3.py
点击查看免费下载

相关推荐

上一篇:RVC变声器:用10分钟语音训练出你的第一个AI音色模型
下一篇:Windows 11任务栏拖放功能终极修复指南:如何快速恢复高效操作体验

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/12 1:51:59

数据库系统概论经典三表:student、sc、course建表与SQL练习全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/12 1:50:16

数据库设计实战:在线学习系统库表设计与SQL优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/12 1:49:13

Natron Roto 节点 Python 脚本指南:ItemBase 抽象类 API 全面解析

音视频视频处理图形学桌面应用 【免费下载链接】Natron Open-source video compositing software. Node-graph based. Similar in functionalities to Adobe After Effects and Nuke by The Foundry. 项目地址&#xff1a; https://gitcode.com/gh_mirrors/na/Natron 点击查看 …

作者头像 李华