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


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

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

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

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

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

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

    pip install web3
  • 钱包与私钥(可选,用于发送交易):如果你需要发送交易或部署合约,你需要一个以太坊钱包(如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.functions.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限制根据合约方法复杂度调整
          '
    标签: 热门 推荐
    返回栏目