“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 库与区块链进行交互。# [ l2 t) M+ p5 J" b5 K0 ]
Dapps 开发包括三个简单的步骤:3 K3 h/ F$ t1 i: E' a
- 在区块链网络上部署智能合约
- 从部署的智能合约中读取数据
- 将交易发送到部署的智能合约' T5 K( c& O" b+ @
安装
% q- O% l" d3 v
Python 2.7 +5 D% Z( T- I& X: j: S& H/ l
Node.js
Truffle9 o" V0 q- V* N. P4 ]/ v
/ e( B& |# `8 q4 }, ^
6 y: m( {! c% O* x0 j
npm install -g truffle
Pip
npm i pip& p$ A/ J- _0 u( c, {/ o7 z- M! l
web3.py5 Z/ U2 R' _) b2 l2 M5 p3 v# O; V
pip install web3
Infura 项目 API# P z! N2 k4 u& y, v- E. ^
前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。
, l+ _1 T3 B' s$ ~" x+ Z5 i6 U
智能合约8 P) r, a6 [4 A
每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。
- pragma solidity ^0.5.7;
- contract greeter{
- string greeting;! ~) t+ f9 }8 h6 G
- function greet(string memory _greeting)public{& z3 q+ q1 G \, \7 `! T$ t/ I4 ]
- greeting=_greeting;8 f! ]8 ^8 G* [6 G& @$ m8 Z) m: ^9 ]
- }1 z$ o$ ]. b8 e! k- I/ R8 T0 I
- function getGreeting() public view returns(string memory) {
- return greeting;
- }2 J/ J/ E, j5 ^3 }9 D
- }
您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。2 t; j% V/ m- r' a7 h
' b$ p; A# r% k1 n
1. 在区块链网络上部署智能合约5 T, w+ P) x& @, z& G: v! y0 d7 t
2 i) a( j7 U9 R Z8 ^
a) 创建项目:9 K1 W; [6 ]7 W+ [6 u
mkdir pythonDapp$ C! R/ M7 E* Z' c6 E6 C4 b- ?8 u
cd pythonDapp
truffle init j" S% u- X, t! n7 T8 r T, l
成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。 f4 n+ ^, r9 M$ N; B1 _. C
b) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:0 ?( o) w* `" n( A B' `3 D
8 s- x+ n) ]( F2 p5 D9 j! i
truffle compile9 ?, ?" a$ Z; P7 Y& a E5 F U
(or)
truffle.cmd compile #(for windows only)
0 v1 {$ O) q( E# r
上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。
% k" ^4 N1 g+ r% B
c) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。: T+ J/ ?* v2 R7 L! N% A1 P9 |8 U
- import json; r: ?8 S9 t8 V5 j; K6 x) v* u
- from web3 importWeb3, HTTPProvider, p+ ^. V y' s" f- b& B
- from web3.contract importConciseContract, K& {. ~/ d# f$ k
- # web3.py instance
- w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))* \0 g4 S0 c5 P7 {! S5 S
- print(w3.isConnected())
- key="<Private Key here with 0x prefix>"
- acct = w3.eth.account.privateKeyToAccount(key)- }/ C0 I. e1 \5 u* e
- # compile your smart contract with truffle first
- truffleFile = json.load(open('./build/contracts/greeter.json'))7 I0 L9 a( @/ y9 z8 l
- abi = truffleFile['abi']& I4 I6 [7 F4 @0 }5 q1 S
- bytecode = truffleFile['bytecode']
- contract= w3.eth.contract(bytecode=bytecode, abi=abi)
- #building transaction$ R" W8 I7 j+ ~
- construct_txn = contract.constructor().buildTransaction({6 H- r# D4 V/ _% f7 H6 Y* k+ T
- 'from': acct.address,
- 'nonce': w3.eth.getTransactionCount(acct.address),
- 'gas': 1728712,
- 'gasPrice': w3.toWei('21', 'gwei')})2 n" P, m3 g2 Y1 X( a/ T( h
- signed = acct.signTransaction(construct_txn)
- tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)
- print(tx_hash.hex())
- tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)+ C8 a' p" q1 |# o4 J; n
- print("Contract Deployed At:", tx_receipt['contractAddress'])
这是我所做的:
导入的 web3 库和所有其他必需的模块
通过指向 Ropsten Infura 节点启动 web3 提供程序( c3 y3 f" ~+ y5 ~
添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。
使用我们的私钥签署交易并在网络上广播。+ N- k/ d; `9 g: ]$ t2 i0 b6 @
在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。- J7 P, s' N2 b& X. W
2. 向部署的合约发送交易+ \: _& j! y. b( h; t4 [7 p$ @
( m" z5 z) P0 l, w1 l M o
在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。" E8 q# D# h1 e
- import json( ?7 F, }) i: F5 c" W9 s
- from web3 importWeb3, HTTPProvider
- from web3.contract importConciseContract) R+ W, l% \" l5 B9 t# s
- # compile your smart contract with truffle first) C0 e+ k# b* ~7 t9 i
- truffleFile = json.load(open('./build/contracts/greeter.json'))1 I9 @ ]0 l" i8 W6 v7 A
- abi = truffleFile['abi']
- bytecode = truffleFile['bytecode']% ^: r# r3 N4 \& u/ A Y
- # web3.py instance
- w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify/ y5 [2 e+ v" N; f6 p& q
- print(w3.isConnected())
- contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify8 m3 B' c' g& }/ S
- key="<Private key with 0x prefix here>"#modify
- acct = w3.eth.account.privateKeyToAccount(key)
- account_address= acct.address; z. z5 u- O" B! l8 H- i* X
- # Instantiate and deploy contract' I7 y: C8 i, n, M0 X- x7 k
- contract = w3.eth.contract(abi=abi, bytecode=bytecode)
- # Contract instance
- contract_instance = w3.eth.contract(abi=abi, address=contract_address)/ ~+ y. R2 ~' D8 E
- # Contract instance in concise mode
- #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)})% M9 Q5 N# c3 E! k9 E+ T
- #Get tx receipt to get contract address3 S, k1 N" o# l3 G6 k" x/ O
- signed_tx = w3.eth.account.signTransaction(tx, key)4 @9 N7 O8 d; x8 W7 j) k: O
- #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
- hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)
- print(hash.hex())
& O' A* h* W! x+ c- f: X
( F2 M: v: a- P y5 N2 E
这是我所做的:$ z8 X/ _, L) g/ @
导入的 web3 库和所有其他必需的模块
通过指向 Ropsten Infura 节点启动 web3 提供程序
添加了用于签署交易的帐户地址和私钥
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例2 Z0 f4 C( n, [! B$ ~: T& c# i! N. U
创建 tx 对象以添加问候语“hello all my goody people”并建立交易
使用我们的私钥签署交易并在网络上广播。! Q. P% n$ S$ o( a/ t% g# g4 h
在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。( }& Y7 T9 L7 N5 A" o8 }
3. 从部署的智能合约中读取数据
在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。- Z" [5 b2 ~- k- @8 D7 p
- 5 v$ h: {9 j" f& P$ H0 X- d
- import json
- from web3 importWeb3, HTTPProvider- d1 D5 U1 p0 z: `2 f- C0 n
- from web3.contract importConciseContract
- # compile your smart contract with truffle first
- truffleFile = json.load(open('./build/contracts/greeter.json'))
- abi = truffleFile['abi']
- bytecode = truffleFile['bytecode']
- # web3.py instance
- w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))
- print(w3.isConnected())
- contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")
- # Instantiate and deploy contract
- contract = w3.eth.contract(abi=abi, bytecode=bytecode)4 k/ O0 d+ a4 x, s
- # Contract instance& Z) u1 U( l3 {0 B8 E
- contract_instance = w3.eth.contract(abi=abi, address=contract_address)
- # Contract instance in concise mode6 Q( W6 T* w9 f. K8 L2 g
- #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
- # Getters + Setters for web3.eth.contract object ConciseContract6 F% B2 {# f- B5 T+ m9 d% S
- #print(format(contract_instance.getGreeting()))
- print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
- W6 Q1 C) G0 y- f: F3 c' r
这是我所做的:
O8 L* p) m3 m7 R4 u5 O
导入的 web3 库和所有其他必需的模块
通过指向 Ropsten Infura 节点启动 web3 提供程序
通过指向 abi 和 contract_Address 创建合约实例(来自上一步)4 n, w! @3 J P" o% o
调用 getGreeting() 方法并在控制台打印结果
结论$ b2 h* X$ c( V2 O
您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。* l5 |5 P0 E# A6 K$ u) E
参考 @温室小书生室d 《python利用web3.py开发以太坊应用dapp的实战教程》( w P( `+ Y# C7 `* r