Python与以太坊:搭建你的第一个去中心化应用(DApp)后端**
以太坊作为全球领先的智能合约平台,为去中心化应用(DApps)的开发提供了强大的基础设施,而Python,以其简洁的语法、丰富的库生态和易用性,成为了与以太坊交互和搭建DApp后端的理想选择,本文将带你了解如何使用Python与以太坊进行交互,并搭建一个简单的DApp后端环境。
为什么选择Python与以太坊交互
在众多编程语言中,Python在以太坊生态中占据了一席之地,主要原因包括:
- 简洁易学:Python的语法清晰,接近自然语言,降低了开发门槛,使得开发者可以更专注于业务逻辑而非复杂的语言细节。
- 丰富的库支持:存在多个成熟的Python库(如Web3.py、Web3.py的衍生库或特定框架)用于与以太坊节点交互、部署智能合约、调用合约方法等。
- 强大的社区:Python拥有庞大的开发者社区,遇到问题时容易找到解决方案和帮助。
- 快速开发:Python的动态类型和丰富的第三方库使得原型开发和迭代速度非常快。
搭建Python以太坊开发环境
要使用Python与以太坊交互,我们需要搭建一个包含Python环境、以太坊节点(或连接到远程节点)以及必要库的开发环境。
安装Python
如果你的系统中尚未安装Python,请从Python官网下载并安装最新稳定版本(推荐3.8及以上),安装时请确保勾选“Add Python to PATH”选项。
安装Web3.py库
Web3.py是以太坊官方推荐的Python库,用于与以太坊网络进行交互,打开终端或命令提示符,执行以下命令安装:
pip install web3
如果需要特定版本或有其他依赖,可以通过pip install web3==版本号来安装。
选择以太坊节点连接方式
Python脚本需要连接到一个以太坊节点才能读取区块链数据、发送交易等,主要有两种方式:
-
本地运行以太坊节点:
- Geth:Go语言实现的以太坊客户端,你可以从Geth官网下载并安装,安装后,可以通过命令行启动一个全节点或快照节点,并开启RPC服务(
--http --http.addr 0.0.0.0 --http.port 8545 --http.api eth,net,web3,personal),注意,同步全节点需要大量时间和磁盘空间。 - Parity:Rust语言实现的以太坊客户端,现已Open Source并更名为OpenEthereum,同样可以下载安装并启动RPC服务。
- Ganache:一个个人以太坊区块链,用于开发,它非常轻量级,可以瞬间创建多个账户,并预设大量以太币,非常适合开发和测试,你可以从Ganache官网下载桌面版,或使用其命令行版本。
- Geth:Go语言实现的以太坊客户端,你可以从Geth官网下载并安装,安装后,可以通过命令行启动一个全节点或快照节点,并开启RPC服务(
-
**连接到远程节点服务(推荐初学者):
- 对于开发者来说,运行本地全节点资源消耗较大,连接到远程节点服务是更便捷的选择,许多服务商提供免费的以太坊节点RPC URL,
- Infura:https://infura.io/
- Alchemy:https://www.alchemy.com/
- QuickNode:https://www.quicknode.com/
- 注册这些服务后,你可以获得一个唯一的HTTP或WebSocket RPC URL,在你的Python代码中使用这个URL连接到以太坊网络。
- 对于开发者来说,运行本地全节点资源消耗较大,连接到远程节点服务是更便捷的选择,许多服务商提供免费的以太坊节点RPC URL,
使用Python与以太坊交互基础
安装好环境后,我们就可以开始使用Python进行一些基本的以太坊操作了。
连接到以太坊节点
from web3 import Web3
# Ganache默认RPC URL通常是 "HTTP://127.0.0.1:7545"
# Infura提供的URL类似 "https://mainnet.infura.io/v3/YOUR_PROJECT_ID"
infura_url = "https://mainnet.infura.io/v3/YOUR_PROJECT_ID" # 替换成你自己的Infura ID
ganache_url = "HTTP://127.0.0.1:7545"
# 连接到Ganache本地节点(示例)
w3 = Web3(Web3.HTTPProvider(ganache_url))
# 检查连接是否成功
if w3.is_connected():
print(f"成功连接到以太坊节点!链ID: {w3.eth.chain_id}")
else:
print("连接失败!")
# 连接到Infura主网(示例)
# w3 = Web3(Web3.HTTPProvider(infura_url))
# if w3.is_connected():
# print(f"成功连接到Infura主网!链ID: {w3.eth.chain_id}")
# else:
# print("连接失败!")
获取账户信息
# 获取节点上的第一个账户(通常是Ganache创建的第一个测试账户)
account = w3.eth.accounts[0]
print(f"默认账户地址: {account}")
# 获取账户余额
balance = w3.eth.get_balance(account)
# 余额通常是以wei为单位,转换为ether
balance_in_ether = w3.from_wei(balance, 'ether')
print(f"账户余额: {balance_in_ether} ETH")
发送交易(需要私钥)
发送交易需要发送方的私钥。请务必妥善保管私钥,切勿泄露!
from web3 import Account
# 假设我们有一个账户的私钥(仅用于示例,实际中应安全存储)
private_key = "0x你的私钥" # 替换成你的私钥,注意"0x"前缀
# 从私钥获取账户对象
sender_account = Account.from_key(private_key)
sender_address = sender_account.address
print(f"发送方地址: {sender_address}")
# 获取nonce(每个交易的序列号)
nonce = w3.eth.get_transaction_count(sender_address)
# 构建交易
# 假设我们要转账到另一个地址(这里用第一个账户作为示例接收方)
receiver_address = w3.eth.accounts[1]
value_in_wei = w3.to_wei(0.01, 'ether') # 转账0.01 ETH
gas_price = w3.eth.gas_price # 获取当前建议的gas价格
gas_limit = 21000 # 转账ETH的典型gas限制
transaction = {
'nonce': nonce,
'to': receiver_address,
'value': value_in_wei,
'gas': gas_limit,
'gasPrice': gas_price,
'chainId': w3.eth.chain_id # 确保交易在正确的链上执行
}
# 签名交易
signed_txn = w3.eth.account.sign_transaction(transaction, private_key)
# 发送交易
tx_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction)
print(f"交易发送中,交易哈希: {tx_hash.hex()}")
# 等待交易被打包
receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
print(f"交易收据: {receipt}")
与智能合约交互
智能合约是以太坊的核心,要使用Python与智能合约交互,你需要:
- 智能合约的ABI(Application Binary Interface):这是合约与外界交互的接口,通常以JSON格式提供。
- 智能合约的地址:部署到以太坊网络后的合约地址。
- 合约实例:使用Web3.py和ABI、地址创建合约实例。
# 假设我们有一个简单的存储合约(Storage.sol)部署在本地测试网
# SPDX-License-Identifier: MIT
# pragma solidity ^0.8.0;
# contract Storage {
# uint256 public storedData;
#
# function set(uint256 x) public {
# storedData = x;
# }
#
# function get() public view returns (uint256) {
# return storedData;
# }
# }
# 假设这个合约已经部署,地址为 0x5FbDB2315678afecb367f032d93F642f64180aa3 (Truffle默认部署地址之一)
# ABI是简化的,实际使用时需要完整的ABI
contract_address = "0x5FbDB2315678afecb367f032d93F642f64180aa3"
# 简化的ABI,包含get和set函数的selector
abi = [
{
"inputs": [],
"name": "get",
"outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}],
"stateMutability": "view",
"
本文转载自互联网,具体来源未知,或在文章中已说明来源,若有权利人发现,请联系我们更正。本站尊重原创,转载文章仅为传递更多信息之目的,并不意味着赞同其观点或证实其内容的真实性。如其他媒体、网站或个人从本网站转载使用,请保留本站注明的文章来源,并自负版权等法律责任。如有关于文章内容的疑问或投诉,请及时联系我们。我们转载此文的目的在于传递更多信息,同时也希望找到原作者,感谢各位读者的支持!