6 V* ^& e, K4 C5 `0 Q6 l& q
“DApp”代表去中心化应用程序。与传统应用程序一样,去中心化应用程序也有前端(客户端)和后端(服务器端)。DApp 的用户界面可以用任何语言编写(就像传统应用程序一样),并且可以调用其后端。那么,Dapps 与传统应用程序有何不同?DApp 的后端代码运行在分散的对等网络(即区块链)上。您可能听说过 BitTorrent、Tor、Popcorn Time——它们是在点对点网络上运行但不在区块链上运行的 DApp。区块链 DApp 有自己的后端代码,称为智能合约,可以部署到区块链(最常见的是以太坊)。智能合约定义了整个 DApp 的逻辑。它是使用区块链作为后端的命脉。那么Python 开发人员可以在哪里利用它?重点来了——web3。Web3 是一组库,允许您与本地或远程以太坊区块链进行交互。简单地说,web3 是与您的后端(区块链)通信的桥梁。幸运的是,以太坊开发人员已经制作了一个 python 库 web3.py 用于与以太坊进行交互。它的 API 源自 web3 的 JavaScript 版本。因此,除了 web3.js,我们也可以通过 web3.py 库与区块链进行交互。
Dapps 开发包括三个简单的步骤:
- 在区块链网络上部署智能合约
- 从部署的智能合约中读取数据
- 将交易发送到部署的智能合约
安装0 U3 C1 H6 G1 R+ E0 w0 A
8 v; \ k9 x) v9 g! ^
Python 2.7 +
Node.js
Truffle
# c& H% Z& h! W
( i, }* U2 E" j7 w1 r3 U# J5 p
npm install -g truffle: q* \! U' y |. v0 R: p" Q8 T; |
Pip# U1 D) j6 W! d( X# I+ J( H
npm i pip
web3.py6 s3 y2 I. g! K( m/ P. T: E3 L, ^
pip install web3
1 `- {5 P) D- s1 @. D
Infura 项目 API
前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。
8 }* I* H Y3 p1 y" d* U1 K6 w
智能合约+ {9 q6 V3 v2 E( Y' I2 ~
每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。
3 x: _/ E: D0 X/ T
- pragma solidity ^0.5.7;, Z' ?$ A- M( X- ]% R9 `
- contract greeter{
- string greeting;- n i7 ]- I9 O6 X# D
- function greet(string memory _greeting)public{0 G5 r8 |4 v+ [% \" l% N* z
- greeting=_greeting;, p1 a, E* v% r6 `6 F$ [+ N
- }
- function getGreeting() public view returns(string memory) {/ `" I3 I/ Q; @2 a+ _( l) Q2 ?9 q
- return greeting;
- }3 T* \$ G! G3 a% _
- }$ \4 C3 u# o$ _/ I1 R6 W
2 Z. X' R- B6 T1 L) G, q; K
您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。7 f& r7 i3 c; Y9 i
1. 在区块链网络上部署智能合约
, B8 o* E6 X# C1 K! ]3 e
a) 创建项目:/ x4 u" [. s% R0 D9 v. `
/ \4 x9 e( D7 f0 a' J* f
mkdir pythonDapp
cd pythonDapp
truffle init, d6 ~6 F% n" k4 t0 q& b$ T
+ O k! F+ Z8 X
成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。
b) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:, q1 s# o; n) t; Q, j2 C6 c
# A5 I V# G. I; i) a. f3 g2 X' {
truffle compile
(or)
truffle.cmd compile #(for windows only)
$ D/ o1 p6 b" x6 P8 {
上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。
8 I8 w/ W* e* Q, Z
c) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。
- import json
- from web3 importWeb3, HTTPProvider+ J! [; Z4 P- g1 P$ B
- from web3.contract importConciseContract
- # web3.py instance
- w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))
- print(w3.isConnected())* j( w( Z$ }! R7 h
- key="<Private Key here with 0x prefix>"
- acct = w3.eth.account.privateKeyToAccount(key). t9 R/ w! \5 ~0 ] x# k9 X$ A
- # compile your smart contract with truffle first0 t. L6 H/ [0 Q, l( b) A$ N, ?0 z
- truffleFile = json.load(open('./build/contracts/greeter.json'))/ X% z0 I. r8 f# ?: C( J
- abi = truffleFile['abi']
- bytecode = truffleFile['bytecode']! f7 [1 i3 g0 i5 q' {9 z, p/ p
- contract= w3.eth.contract(bytecode=bytecode, abi=abi)9 b: I$ T" z$ S% f1 }% W# Y
- #building transaction
- construct_txn = contract.constructor().buildTransaction({
- 'from': acct.address,
- 'nonce': w3.eth.getTransactionCount(acct.address),4 A3 b+ L, E3 _
- 'gas': 1728712,2 {) Y g8 v3 [- B4 I' N
- 'gasPrice': w3.toWei('21', 'gwei')}) M: q5 g7 r8 d/ j* j1 P; e" X' u
- signed = acct.signTransaction(construct_txn)
- tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)
- print(tx_hash.hex())+ W0 Z$ d- ^1 P6 a, L
- tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
- print("Contract Deployed At:", tx_receipt['contractAddress'])
这是我所做的:# O+ P6 ^# V8 C0 M* K' x4 A
- @4 V. n1 q8 r7 ^0 U9 b
导入的 web3 库和所有其他必需的模块
通过指向 Ropsten Infura 节点启动 web3 提供程序( Z" k: S% Q5 o/ m; U% |- m
添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。
使用我们的私钥签署交易并在网络上广播。
在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。* p, u- c" c; c3 s' h1 K
2. 向部署的合约发送交易
5 }! u, o" [; d
在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。1 z/ ]7 f2 U. S0 h: }
- import json2 |9 E7 ^* k S
- from web3 importWeb3, HTTPProvider$ x" r8 `0 \, ~8 p
- from web3.contract importConciseContract
- # compile your smart contract with truffle first( O# Q, {/ ~5 g
- truffleFile = json.load(open('./build/contracts/greeter.json'))
- abi = truffleFile['abi']
- bytecode = truffleFile['bytecode']
- # web3.py instance
- w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify
- print(w3.isConnected())
- contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify7 m& w J4 f1 F6 g2 m
- key="<Private key with 0x prefix here>"#modify
- acct = w3.eth.account.privateKeyToAccount(key)
- account_address= acct.address
- # Instantiate and deploy contract- K% U3 j. o, ~0 }& {
- contract = w3.eth.contract(abi=abi, bytecode=bytecode)7 ~6 e' R t: ]1 z7 E
- # Contract instance- m+ D% l- ]5 \0 Q. I W8 i) ~- w
- contract_instance = w3.eth.contract(abi=abi, address=contract_address)
- # Contract instance in concise mode/ L8 ]+ D- q8 J
- #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
- tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})3 n4 l# e: h, |0 n& B, E; X# Y/ c; _
- #Get tx receipt to get contract address
- signed_tx = w3.eth.account.signTransaction(tx, key)+ @( }! H( v) G5 L& n% M& T
- #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
- hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)& h* R# E4 t) O! D* I0 ~
- print(hash.hex())
这是我所做的:
1 O# |0 p* c" F; R, H( K
导入的 web3 库和所有其他必需的模块
通过指向 Ropsten Infura 节点启动 web3 提供程序
添加了用于签署交易的帐户地址和私钥" z, h( r; M& i+ n4 f
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
创建 tx 对象以添加问候语“hello all my goody people”并建立交易5 \ q q8 B7 F
使用我们的私钥签署交易并在网络上广播。
在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。2 ]2 E4 ^2 _. h9 ~4 }" ~
3. 从部署的智能合约中读取数据
% G' Y8 ?1 u' ]2 \ \, u
在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。. D$ Q1 z4 `: r6 d* J/ c8 M
- ! z& E" A! h& x+ s2 |- D
- import json/ \3 C1 C1 C( _2 t
- from web3 importWeb3, HTTPProvider
- from web3.contract importConciseContract/ S2 K! z7 l, _- a6 v8 m
- # compile your smart contract with truffle first* J9 f3 E" z) C: N
- truffleFile = json.load(open('./build/contracts/greeter.json'))
- abi = truffleFile['abi']' C, Z; G7 x8 p, {0 M0 o
- bytecode = truffleFile['bytecode']
- # web3.py instance
- w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))
- print(w3.isConnected()). I- j- J& E; w) I3 i# b6 o& J
- contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")
- # Instantiate and deploy contract& }5 G5 r! B$ z0 P1 |8 m6 O
- contract = w3.eth.contract(abi=abi, bytecode=bytecode)+ K3 P1 A2 _6 N8 i
- # Contract instance5 D0 V; T% i0 ^ [0 N8 y
- contract_instance = w3.eth.contract(abi=abi, address=contract_address)
- # Contract instance in concise mode
- #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
- # Getters + Setters for web3.eth.contract object ConciseContract$ |4 B& A7 G9 J- {
- #print(format(contract_instance.getGreeting()))) `: M0 k+ j3 u4 G
- print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
- M. w, R+ G% W. X" y1 T( a9 R
这是我所做的:' h4 o7 \ q! @. g$ y& X
导入的 web3 库和所有其他必需的模块, B2 F4 N% m; S7 J% ~
通过指向 Ropsten Infura 节点启动 web3 提供程序
通过指向 abi 和 contract_Address 创建合约实例(来自上一步)1 M& d' X7 w: y
调用 getGreeting() 方法并在控制台打印结果
结论/ t# B8 v0 P1 Q& l8 p0 l, q
您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。
5 M, m& C3 \8 t" u/ @. T
2 h- m8 P, A' [8 v. t
参考 @温室小书生室d 《python利用web3.py开发以太坊应用dapp的实战教程》5 J. ^$ E5 V4 z5 E. u8 [* J. p7 T