零基础用 Python 开发区块链(五):Web3 进阶
在本系列文章的前几篇中,我们已经了解了区块链的基础概念以及如何用 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 调用智能合约函数
部署完成后,我们可以调用合约的 set 和 get 函数:
# 获取部署的合约对象
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)平台等。
希望你通过本篇教程,能够在区块链开发的道路上迈出坚实的一步!
更多推荐
所有评论(0)