替换成你的Infura项目ID或节点URL

Python与以太坊的桥梁:如何用Python调用以太坊网络**


以太坊作为全球领先的智能合约平台,其生态系统日益庞大,吸引了无数开发者和企业,而Python,凭借其简洁的语法、丰富的库支持和强大的社区,成为了与区块链技术交互的热门选择,本文将详细介绍如何使用Python调用以太坊网络,包括连接节点、读取数据、发送交易以及与智能合约交互等核心操作。

准备工作:环境搭建与依赖安装

在开始之前,我们需要准备以下几样东西:

  1. 以太坊节点:Python脚本需要通过一个以太坊节点来与以太坊网络通信,你可以选择:

    • 本地节点:使用Geth或OpenEthereum等客户端在自己电脑上运行一个全节点或轻节点,这对硬件有一定要求。
    • Infura或Alchemy等第三方服务:这是更便捷的选择,它们提供远程的以太坊节点接口,你只需要注册获取一个HTTP或WebSocket的URL即可,对于开发和小型应用来说,免费套餐通常足够。
    • 本地测试网节点:在开发测试阶段,强烈建议在本地运行一个测试网节点(如Ropsten, Goerli, Sepolia),或者使用Infura/Alchemy提供的测试网端点,避免消耗真实的ETH。
  2. Python环境:确保你的系统已安装Python 3.6或更高版本。

  3. 安装Web3.py库:Web3.py是以太坊官方Python库,提供了与以太坊节点交互的完整API,它是Python调用以太坊事实上的标准。

    pip install web3
  4. 钱包与私钥(可选,用于发送交易):如果你需要发送交易或部署合约,你需要一个以太坊钱包(如MetaMask)和对应的私钥。请务必妥善保管私钥,切勿泄露!

连接到以太坊节点

使用Web3.py连接到以太坊节点是第一步,以连接到Infura的HTTP节点为例:

from web3 import Web3
infura_url = "https://mainnet.infura.io/v3/YOUR_PROJECT_ID"
w3 = Web3(Web3.HTTPProvider(infura_url))
# 检查连接是否成功
print(f"是否连接成功: {w3.is_connected()}")
# 获取当前区块号
print(f"当前区块号: {w3.eth.block_number}")

如果你使用的是本地节点(如Geth默认端口8545),URL可以是 http://127.0.0.1:8545

读取以太坊数据

连接成功后,我们可以轻松读取以太坊上的数据。

  1. 获取账户余额
    # 替换成你想查询的以太坊地址
    address = "0x742d35Cc6634C0532925a3b844Bc454e4438f44e"

确保地址是校验过的格式

checksum_address = w3.to_checksum_address(address)

balance_wei = w3.eth.get_balance(checksum_address) balance_eth = w3.from_wei(balance_wei, 'ether')

print(f"地址 {checksum_address} 的余额是: {balance_eth} ETH")


2.  **获取交易详情**:
```python
# 替换成你想查询的交易哈希
tx_hash = "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060"
tx_details = w3.eth.get_transaction(tx_hash)
print(f"交易详情: {tx_details}")
  1. 获取合约事件日志:这将在后续智能合约交互部分详细说明。

发送交易(转账)

发送交易比读取数据复杂,因为它需要签名和支付Gas费。

  1. 准备私钥和地址

    # 替换成你的私钥(请勿在代码中硬编码私钥,使用环境变量或配置文件管理!)
    private_key = "YOUR_PRIVATE_KEY"
    sender_address = w3.eth.account.from_key(private_key).address
    checksum_sender_address = w3.to_checksum_address(sender_address)
  2. 获取Nonce:Nonce是账户发送的交易序号,必须按顺序递增。

    nonce = w3.eth.get_transaction_count(checksum_sender_address)
  3. 构建交易

    # 接收方地址
    receiver_address = w3.to_checksum_address("0x1234567890123456789012345678901234567890")
    # 转账金额(以Wei为单位)
    value = w3.to_wei(0.01, 'ether')
    # Gas价格(Gwei)
    gas_price = w3.eth.gas_price
    # Gas限制
    gas_limit = 21000  # 转账ETH的典型Gas限制
    transaction = {
        'to': receiver_address,
        'value': value,
        'gas': gas_limit,
        'gasPrice': gas_price,
        'nonce': nonce,
        'chainId': 1  # 主网chainId,测试网请使用对应的chainId,如Goerli是5
    }
  4. 签名交易

    signed_tx = w3.eth.account.sign_transaction(transaction, private_key)
  5. 发送交易并等待确认

    tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
    print(f"交易已发送,哈希: {tx_hash.hex()}")
    # 等待交易被打包
    tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
    print(f"交易收据: {tx_receipt}")

与智能合约交互

这是Python调用以太坊最强大的功能之一,你需要合约的ABI(Application Binary Interface)和地址。

  1. 获取合约ABI和地址

    • ABI:是合约的接口描述,通常在编译Solidity合约时生成(JSON格式)。
    • 地址:已部署的合约地址。
  2. 加载合约

    # 假设我们有一个简单的ERC20代币合约的ABI(简化示例)
    # 实际使用时请替换为你的完整ABI
    token_abi = """
    [
        {"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"type":"function"},
        {"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"type":"function"},
        {"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_address = w3.to_checksum_address("0xYourContractAddressHere")
    # 加载合约
    contract = w3.eth.contract(address=contract_address, abi=token_abi)
  3. 调用合约的纯函数(读取数据,不修改状态)

    # 获取代币名称
    token_name = contract.func
    随机配图
    tions.name().call() print(f"代币名称: {token_name}") # 查询某个地址的代币余额 address_to_check = "0x742d35Cc6634C0532925a3b844Bc454e4438f44e" token_balance = contract.functions.balanceOf(address_to_check).call() print(f"地址 {address_to_check} 的代币余额: {token_balance}")
  4. 调用合约的修改函数(发送交易,修改状态): 这与发送ETH转账类似,需要构建交易、签名并发送。

    # 假设我们要调用transfer函数进行代币转账
    receiver_address = w3.to_checksum_address("0x1234567890123456789012345678901234567890")
    amount_to_transfer = 1000 * 10**18  # 假设代币精度是18位小数
    # 获取nonce
    nonce = w3.eth.get_transaction_count(checksum_sender_address)
    # 构建调用合约的交易
    build_tx = contract.functions.transfer(
        receiver_address,
        amount_to_transfer
    ).build_transaction({
        'from': checksum_sender_address,
        'nonce': nonce,
        'gas': 200000,  # Gas限制根据合约方法复杂度调整
        '
本文由用户投稿上传,若侵权请提供版权资料并联系删除!