使用 Python 操作 Ethereum:用 web3.py 探索链上世界

·

如果你想用 Python 快速切入区块链开发,web3.py 是最容易上手的利器之一。它不需要你把整块链同步到本地,也无需承担运行节点的巨大硬盘开销,只要一条 HTTP 或 WebSocket 连接,就能把 Ethereum 当成一个“远程数据库”,轻松读取余额、调用智能合约,甚至签署并推送交易。本文将带你从零开始,完成环境配置、节点连接、ERC20 合约读取、交易签名与上链的完整流程,同时融入真实可跑的代码片段、踩坑提醒与常见疑难解答。


web3.py 与 pyethereum 的核心差异

维度web3.pypyethereum
作用轻量级客户端,连接外部节点完整节点,需同步区块链
存储需求几乎为零数百 GB 起跳
使用场景快速开发、教学、数据分析挖矿、网桥、深度验证
启动速度分钟级同步链数据需小时至天

结论:若你只想“用链”,而不想“做链”,web3.py 是最佳之选。


一步步搭建 web3.py 环境

1. 依赖安装

pip install web3

Windows 用户注意:如果编译失败,记得先装 Visual C++ Build Tools

2. Windows 额外步骤

进入 Visual Studio Build Tools 页面,勾选“C++ 生成工具”,大约占用 6–8 GB 硬盘,安装完成后 rerun pip


秒连 Ethereum 节点

web3.py 本身不是节点,必须对接现成节点。你有两种主流方案:

  1. 自建节点:geth 或 Erigon,全节点同步耗时耗盘。
  2. 托管节点:Infura、Alchemy、QuickNode 等。

初学者推荐 Infura,注册后免费获取 API Key,省去复杂同步。示例连接 Ropsten(测试网):

import os
from web3 import Web3, HTTPProvider

INFURA_ROPSTEN = "https://ropsten.infura.io/v3"
def get_w3():
    key = os.getenv("INFURA_API_KEY")
    if not key:
        raise ValueError("请先设置环境变量 INFURA_API_KEY")
    return Web3(HTTPProvider(f"{INFURA_ROPSTEN}/{key}"))

w3 = get_w3()
print("连接测试:", w3.isConnected())

运行结果会打印 True,即已成功对接。👉不想自己拉节点?在线一键签 tx


读取任意 ERC20 代币信息

步骤拆解

  1. 准备 ABI 文件:可在 OpenZeppelin GitHub 下载标准模板。
  2. 地址校验:Ethereum 采用 checksum address,防止大小写拼写错误;w3.toChecksumAddress() 自动转换。
  3. 构造合约实例:传入地址 + ABI 即可。

运行示例

import json
from web3.exceptions import BadFunctionCallOutput

# 第 1 步:加载 ABI
with open("erc20.abi.json") as f:
    abi = json.load(f)

# 第 2 步:地址校验
token_addr = w3.toChecksumAddress("0x4e470dc7321e84ca96fcaedd0c8abcebbaeb68c6")

# 第 3 步:构建合约
contract = w3.eth.contract(address=token_addr, abi=abi)

# 第 4 步:读取链上数据
name     = contract.functions.name().call()
symbol   = contract.functions.symbol().call()
decimals = contract.functions.decimals().call()
supply   = contract.functions.totalSupply().call() / 10 ** decimals

print(f"Token: {name} ({symbol}), 总供给: {supply:,.2f}")

输出:

Token: KyberNetwork (KNC), 总供给: 210,000,000.00

签署并推送交易

读取是免费的,写入则需要 发送交易并支付 Gas。以下示例把 1 枚代币从一个地址转到同地址(演示目的)。

  1. 环境变量准备:

    export INFURA_API_KEY=your_infura_key
    export ETHEREUM_ACCOUNT=0xYourAccount
    export ETHEREUM_PKEY=YourPrivateKeyWithout0x
  2. 代码实现:
# 账户、nonce、gas 预检
from_account = w3.toChecksumAddress(os.getenv("ETHEREUM_ACCOUNT"))
w3.eth.default_account = from_account
nonce   = w3.eth.get_transaction_count(from_account)
amount  = w3.toWei("1", "ether")

# 计算所需 gas
tx_function = contract.functions.transfer(
    Web3.toChecksumAddress("0x000000000000000000000000000000000000dEaD"),
    amount
)
gas = tx_function.estimateGas({'from': from_account})

# 构建原始交易
tx = tx_function.buildTransaction({
    'nonce': nonce,
    'gas': gas,
    'gasPrice': w3.toWei('5', 'gwei'),
    'chainId': 3  # 3 = Ropsten
})

# 私钥签名
signed = w3.eth.account.sign_transaction(tx, private_key=os.getenv("ETHEREUM_PKEY"))
tx_hash = w3.eth.send_raw_transaction(signed.rawTransaction)

print("Tx hash:", tx_hash.hex())

使用 tx_hash 可在 Ropsten Etherscan(https://ropsten.etherscan.io/tx/<tx_hash>)实时追踪状态。👉玩转链上收发,简单快捷就在这里


常见疑问 FAQ

Q1:Python 签名是否会暴露私钥?
A:只要私钥保存在环境变量或 .env 文件,不提交代码仓库,就基本安全。生产场景建议使用密钥管理服务(KMS 或 Vault)。

Q2:为何 estimateGas 结果偏高?
A:estimateGas 默认按最大可能调用套路估算,真实值通常低 10–30%。你可在实际部署后通过 历史平均 gasUsed × 1.1 调整。

Q3:Infura 免费额度耗尽怎么办?
A:可换 QuickNode、Alchemy,或者自建全节点。练手阶段调用量有限,几乎不可能用完。

Q4:如何切到以太坊主网?
A:把 Chain ID 改成 1,HTTPProvider 换成主网节点即可。但注意 Ropsten 是免费的,主网每一步都是真金白银。

Q5:ABI 如何生成?
A:使用 solc --bin --abi YourContract.sol 或部署时在 Remix IDE 里一键下载,也可用 Hardhat/Foundry 自动生成。

Q6:调试合约遇到回滚(revert)怎么办?
A:收集 tx_receipt.logs,结合 remix-debug 或在链上工具(如 Tenderly)查看 revert message,再做 ABI 解压。


延伸阅读

By now,你已经能在本地笔记本里完成 以太坊主网或测试网的所有基础交互。下一步,把今天学到的读取、签名、推送流程封装成 CLI 工具或 Web API,立即开启你的区块链创业、数据监控或 DeFi Bot 之旅。祝你编码愉快!