在本系列文章的前几篇中,我们已经了解了区块链的基础概念以及如何用 Python 开发一个简单的区块链。接下来,我们将进入 Web3 进阶篇,讲解如何使用 Python 与区块链进行更加复杂的交互,特别是如何使用 Web3 库与以太坊(Ethereum)进行交互。Web3 是连接区块链和开发者的桥梁,我们将探讨如何通过 Web3 与智能合约交互、查询区块链上的信息以及进行交易。

1. 了解 Web3

Web3 是指去中心化的网络协议,尤其是在区块链和智能合约应用方面的协议。Web3 允许开发者与区块链节点交互,查询区块链上的信息,发送交易,以及调用智能合约。

web3.py 是 Python 的一个库,允许我们与以太坊区块链进行交互。使用 web3.py,我们可以轻松地连接到以太坊节点(例如本地节点、Infura 节点等)、查询账户余额、发送交易、部署和调用智能合约等。

2. 安装和配置 Web3.py

2.1 安装 Web3.py

首先,我们需要安装 web3.py 库。你可以使用 pip 来安装:

pip install web3

2.2 连接到以太坊节点

Web3 需要与一个以太坊节点连接,通常可以通过以下几种方式:

  • 本地以太坊节点(例如使用 Ganache 或 Geth)
  • 公共以太坊节点(例如 Infura 提供的节点)
连接到本地节点
from web3 import Web3

# 连接到本地 Ganache 节点
w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))

# 检查连接是否成功
if w3.isConnected():
    print("成功连接到本地节点")
else:
    print("连接失败")
连接到 Infura 节点

Infura 是一个提供公共以太坊节点的服务平台,允许开发者不需要运行自己的节点就能与以太坊区块链进行交互。

首先,你需要注册一个 Infura 账户,创建一个项目并获得 API 密钥。

from web3 import Web3

# 连接到 Infura
infura_url = 'https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID'
w3 = Web3(Web3.HTTPProvider(infura_url))

if w3.isConnected():
    print("成功连接到 Infura 节点")
else:
    print("连接失败")

3. 查询区块链上的信息

使用 Web3,我们可以非常方便地查询区块链上的各种信息,如账户余额、交易信息等。

3.1 查询账户余额

# 使用地址查询账户余额
address = '0x742d35Cc6634C0532925a3b844Bc454e4438f44e'  # 示例地址
balance = w3.eth.get_balance(address)

# 将余额从 Wei 转换为 Ether(1 Ether = 10^18 Wei)
balance_in_ether = w3.fromWei(balance, 'ether')

print(f'地址 {address} 的余额是: {balance_in_ether} ETH')

3.2 查询区块信息

你可以查询区块的最新状态或指定区块的信息:

# 获取最新的区块信息
latest_block = w3.eth.get_block('latest')
print(f"最新区块的哈希: {latest_block['hash'].hex()}")
print(f"最新区块的区块号: {latest_block['number']}")

4. 发送交易

发送交易是与区块链交互的重要操作,Web3 允许我们从一个账户向另一个账户发送 ETH。

4.1 发送 ETH

# 发送 ETH 交易

from_account = '0xYourFromAddress'
to_account = '0xYourToAddress'
private_key = '0xYourPrivateKey'  # 使用私钥进行签名
amount_in_ether = 0.1  # 发送的 ETH 数量

# 将 ETH 转换为 Wei
amount_in_wei = w3.toWei(amount_in_ether, 'ether')

# 获取当前 nonce(该账户的交易计数)
nonce = w3.eth.get_transaction_count(from_account)

# 创建交易
transaction = {
    'to': to_account,
    'value': amount_in_wei,
    'gas': 2000000,
    'gasPrice': w3.toWei('20', 'gwei'),
    'nonce': nonce,
    'chainId': 1  # 以太坊主网的 chainId 为 1
}

# 使用私钥签署交易
signed_transaction = w3.eth.account.sign_transaction(transaction, private_key)

# 发送交易
transaction_hash = w3.eth.send_raw_transaction(signed_transaction.rawTransaction)

# 打印交易哈希
print(f"交易发送成功,交易哈希: {transaction_hash.hex()}")

4.2 等待交易确认

你可以通过 wait_for_transaction_receipt() 方法等待交易确认:

# 等待交易被挖矿确认
receipt = w3.eth.wait_for_transaction_receipt(transaction_hash)

print(f"交易成功,交易详情: {receipt}")

5. 智能合约交互

Web3 还允许我们与智能合约进行交互。我们可以调用合约的函数,发送交易,获取合约的状态等。

5.1 部署智能合约

首先,你需要编写并部署一个智能合约(通常使用 Solidity 编写)。在这里我们通过 Web3 部署一个简单的合约:

pragma solidity ^0.4.17;

contract SimpleStorage {
    uint public storedData;

    constructor() public {
        storedData = 100;
    }

    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}

然后,我们可以用 Python 来部署并与这个合约交互。

from web3 import Web3
from solcx import compile_standard

# 编译 Solidity 合约
contract_source_code = '''
pragma solidity ^0.4.17;

contract SimpleStorage {
    uint public storedData;

    constructor() public {
        storedData = 100;
    }

    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}
'''

compiled_sol = compile_standard({
    "language": "Solidity",
    "sources": {
        "SimpleStorage.sol": {
            "content": contract_source_code
        }
    },
    "settings": {
        "outputSelection": {
            "*": {
                "*": ["abi", "evm.bytecode"]
            }
        }
    }
})

# 获取 ABI 和字节码
abi = compiled_sol['contracts']['SimpleStorage.sol']['SimpleStorage']['abi']
bytecode = compiled_sol['contracts']['SimpleStorage.sol']['SimpleStorage']['evm']['bytecode']['object']

# 设置合约地址和创建合约对象
w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))
w3.eth.default_account = w3.eth.accounts[0]

# 创建合约对象
SimpleStorage = w3.eth.contract(abi=abi, bytecode=bytecode)

# 部署合约
tx_hash = SimpleStorage.constructor().transact()
tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash)

# 获取合约地址
contract_address = tx_receipt.contractAddress
print(f"合约部署成功,合约地址: {contract_address}")

5.2 调用智能合约函数

部署完成后,我们可以调用合约的 setget 函数:

# 获取部署的合约对象
contract = w3.eth.contract(address=contract_address, abi=abi)

# 调用 `get` 函数获取存储的数据
stored_data = contract.functions.get().call()
print(f"合约存储的数据: {stored_data}")

# 调用 `set` 函数设置新的值
tx_hash = contract.functions.set(200).transact()
w3.eth.wait_for_transaction_receipt(tx_hash)

# 再次调用 `get` 函数查看更新后的数据
updated_data = contract.functions.get().call()
print(f"更新后的合约数据: {updated_data}")

6. 总结

在本篇文章中,我们深入了解了如何使用 web3.py 库与以太坊区块链进行交互,包括:

  • 连接本地或远程以太坊节点(例如 Infura)
  • 查询账户余额和区块信息
  • 发送交易并等待确认
  • 与智能合约交互,包括部署合约和调用合约方法

这些操作是构建区块链应用的基础,了解如何与智能合约交互后,你可以开始开发更加复杂的区块链应用,如去中心化应用

(DApps)、去中心化金融(DeFi)平台等。

希望你通过本篇教程,能够在区块链开发的道路上迈出坚实的一步!

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐