Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
2795 1 0
什么是 DApp
; B* _, H! U) Z+ o
% I; l$ k1 D2 q$ ?; f“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 库与区块链进行交互。" z3 i# S. V6 |1 g8 F  U! q

9 o! {9 L5 t  j8 t7 R( p& oDapps 开发包括三个简单的步骤:/ G: l$ h# y+ Z: ]
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约9 {7 [% A5 l1 W0 o5 m  T: z) ~7 G5 c
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。
% b0 n! I, o8 K& i- ^0 y3 X! V" K) e3 E, u
安装( c4 i& t8 }  c. V
/ Y& @& @5 r. `
Python 2.7 +0 j# E- D" w! M( t$ y- r
Node.js
( |+ V* j& Q( l3 MTruffle2 i" l+ b8 F# H& ~& Y
1 T, m- C7 R2 N# M; e

& k! m+ h6 o, P; K  x5 s9 `  Nnpm install -g truffle
& B" u4 i$ u, ?- QPip
) ?5 ?% k6 {3 }3 ?& t: u( V$ _npm i pip4 F4 n% x2 [0 x7 q$ s6 Y
web3.py
& b, a9 P5 j8 }pip install web3: r7 a  Y" x' E5 I
4 G, q% M  m7 U" w: k

9 k- m6 e& @- O% R# V- j2 s& GInfura 项目 API
  D% m) z' J7 N( E! y前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。& {; e5 v. n/ v

! N8 m& }. ^# Y) e智能合约' d. G2 K2 A: r4 K

! U/ |- [$ a% G" W2 F# Y; F每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。
  b1 O4 k; {* q; y  ~
5 \2 n* Y7 K$ x' ~3 Z; h
  1. pragma solidity ^0.5.7;
    5 i* w, ]& u3 E  E+ ^7 n, N
  2. contract greeter{
    2 F& B; H% v4 F9 x6 f
  3.     string greeting;) y( n8 A* z9 s& z
  4.     function greet(string memory _greeting)public{
    + }! T3 a9 M. A1 W$ e- S4 j' B
  5.         greeting=_greeting;
    0 ~. F4 e/ _  S+ R0 c7 t- G$ w% J  X
  6.     }# T5 h% t4 k8 u& Q$ n
  7.     function getGreeting() public view returns(string memory) {
    7 c) `2 z" K/ l- L
  8.         return greeting;
    $ K. w( I4 V! l9 T3 i7 i6 {
  9.     }$ {. H% p8 R) u+ a" _) E
  10. }
    2 C: ?7 C/ q) X  I- S  F1 m- W% e( [
复制代码

. r0 u2 h2 B+ R" i6 J5 c6 a2 p, y8 e: f  L: n
您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。4 {$ X0 c& N9 D! s$ k+ u+ S& W1 E, f
% _/ D( _- l! h$ W) Z) v
1. 在区块链网络上部署智能合约
6 r; C7 S: {9 {" U6 O( }9 W
( t- R: U1 |  X, Qa) 创建项目:
5 v/ Q/ g$ U* {/ Y
6 r* _0 `" C. [/ e/ D5 Qmkdir pythonDapp
1 ?6 B% R; L2 t6 p, R7 Y% b- J% Rcd pythonDapp
" |- M& Z; Q; i2 K- ttruffle init
* n* s7 \/ P$ A, r9 a
+ j+ p9 H" M# x! m4 r
: l4 L: M; C+ |3 _6 }& N成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。+ v( S9 p" r6 ~3 s% E6 ^9 X; _& B
, i/ z& X  x9 V5 [% i7 r# x
b) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:( ]$ n" q) W* w  D
0 T" d4 s. E' m. M3 k

7 H0 d7 K0 G. J# s# w3 f) j+ ^9 D
6 T4 b, a4 j6 k/ j5 T( struffle compile3 T* g0 _: y" P& |: W! N7 x
(or)
7 |% L  L" m; s! e" gtruffle.cmd compile #(for windows only)9 K( `- D; V0 Z' c( E

: p1 |3 z7 ]! i& c$ x; s/ ~1 H2 B; A2 d% x( w2 M+ d
上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。
8 H$ {' ^8 e3 w3 {- t& A5 G6 _
1 ^, [9 i1 C; J! e+ {c) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。% o& [/ `' O) i( F

- |% }/ g9 L! [4 {- E7 d
  1. import json
    ! R3 T' P" u' F3 N; A
  2. from web3 importWeb3, HTTPProvider
    8 t1 n' P' {3 i, D6 W0 r
  3. from web3.contract importConciseContract
    ! ]. y6 f0 y! R; b( i* w
  4. # web3.py instance
    . W& r+ X* M; K& r
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))
    6 p# [4 A: W( w4 q: y4 v
  6. print(w3.isConnected())7 v/ L9 h2 L- |/ I7 H
  7. key="<Private Key here with 0x prefix>"
    - X/ l8 x& g6 \: e, k" o: _! g( u
  8. acct = w3.eth.account.privateKeyToAccount(key)) i' f1 Z: h. D$ `- q) `0 V5 {9 H
  9. # compile your smart contract with truffle first6 e0 a$ D% W) u. X5 G6 a# I$ `
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))" |0 \# a: u# c4 m+ _
  11. abi = truffleFile['abi']
      _& m4 \, h. h. m2 I: y9 r
  12. bytecode = truffleFile['bytecode']
    2 P' |4 e" y# a2 n7 ?" g$ i
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi)& ^& i2 s7 y/ ^; S  u
  14. #building transaction
    ' l, N6 B/ _, m% P7 P
  15. construct_txn = contract.constructor().buildTransaction({
    / \( p" j1 |, J' E; @- U2 y
  16. 'from': acct.address,& @, M) g+ @3 Q% i
  17. 'nonce': w3.eth.getTransactionCount(acct.address),  m& Z/ p' P* |" V2 {
  18. 'gas': 1728712,. y2 ?  t$ q# f
  19. 'gasPrice': w3.toWei('21', 'gwei')})1 u' a1 m* e- s
  20. signed = acct.signTransaction(construct_txn)
    % h% o' T; |  L' @1 L( F$ l3 r, i0 r
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction), h3 c$ K. o) N' O: }0 \1 w
  22. print(tx_hash.hex())
    & k5 _& @: ]) z8 V
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
    2 k  ~. h& l4 o3 e
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码

$ [7 \) T3 l  {" J
$ S% |2 B" d7 _- E6 ^; `8 T" m! N  \* ^) B1 R. r
这是我所做的:( F, Z4 Z5 W3 \' C. v$ L) d* z; H

& y$ a  ?/ z; \7 ^3 h! }导入的 web3 库和所有其他必需的模块9 d( T) U- v, u8 u1 _- H
通过指向 Ropsten Infura 节点启动 web3 提供程序! \& W9 d3 D9 c
添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。# M4 S$ B9 _. q
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例# M# c$ t, g4 N" p7 \1 c9 \. n
添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。& j8 H5 D8 `( J; X- }
使用我们的私钥签署交易并在网络上广播。
( O6 r+ U0 D* `- J. b& s, N- {在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。
- E/ f; ^: w5 S) ]5 V/ s+ {2. 向部署的合约发送交易
1 L! a- d% n/ u# I5 X$ `# w( c8 S" R0 M" `$ ?9 C5 i$ H/ Z
在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。
7 o' z  R- }: |- D+ T
  1. import json& g, s4 |* |. K: S
  2. from web3 importWeb3, HTTPProvider
    4 I2 D4 E- Q+ h& v; \
  3. from web3.contract importConciseContract6 G7 f4 [! b* i$ m6 w
  4. # compile your smart contract with truffle first
    ; P" K# N$ s; R! V
  5. truffleFile = json.load(open('./build/contracts/greeter.json'))
    ; o) ^. X; D7 p+ Z4 Q
  6. abi = truffleFile['abi']' j  o8 y% Z; U
  7. bytecode = truffleFile['bytecode']
    2 N) y( J) Y8 I! t: u  e
  8. # web3.py instance
    # [; x% o* T. ^
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify# ^& m$ X7 x& J% h5 F, U
  10. print(w3.isConnected())/ l: V% d% k/ F" ^2 B  W  e
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify
    . d0 u" j. h/ ~( j7 x' v' H& K
  12. key="<Private key with 0x prefix here>"#modify
    6 K2 p% ~- U7 x7 e. R
  13. acct = w3.eth.account.privateKeyToAccount(key)/ K$ X$ s' h9 Q
  14. account_address= acct.address. m! ^7 S3 |1 s: B8 q
  15. # Instantiate and deploy contract
    & k1 A3 T, |+ d$ _
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    ! Z$ b2 n9 p& y) H* ]8 G
  17. # Contract instance8 Y' }4 |4 q9 y8 i+ p0 @  u
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)% U9 x$ }4 ^' T. u" d
  19. # Contract instance in concise mode
    % J$ V( c+ Y5 V" |  V; m
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    . V) e* e  h. e& H
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})
    % L& n2 E$ X! ~/ z. t8 [  M0 a- k! u
  22. #Get tx receipt to get contract address
    ) ]; V: E; b0 U
  23. signed_tx = w3.eth.account.signTransaction(tx, key); \0 ~, V# ~3 Z9 G; S
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
    $ v( R8 P, ?7 P+ j/ d
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)
    $ ~- M# f4 P8 \  Y
  26. print(hash.hex())
复制代码

- W4 l  H' v" m6 l, w- e
2 G: ]1 `2 o) h( D' o3 \
7 |3 o2 v4 q2 ~* _这是我所做的:1 P* x( N& O+ D/ Z3 Z! S* I

9 _# U. z/ U! Q0 y# w导入的 web3 库和所有其他必需的模块: C1 A$ r5 P* C" ]
通过指向 Ropsten Infura 节点启动 web3 提供程序* `6 I$ m6 [: E0 Z0 Y  F5 Z
添加了用于签署交易的帐户地址和私钥- a* ]0 s) j! ^# c% I; B
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例7 ~7 {; d; \4 C! J2 e; ^" A
创建 tx 对象以添加问候语“hello all my goody people”并建立交易- S- \# G% e% y* D# Y5 Q* i
使用我们的私钥签署交易并在网络上广播。' O4 o% e0 i1 N0 B  Y3 W# }
在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。* ]( A( a0 [8 K& @, J* H% M) o, v' _# G
3. 从部署的智能合约中读取数据7 i; `4 ^, ]0 s- ^# U

) S4 f$ S2 c3 x6 A% Q) K在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。
  S) }1 Q# `( {& ~' X, f* C6 s
  1. + q$ [/ I9 X/ K% P6 S2 h- l% I$ x0 M
  2. import json
    $ B6 J8 l8 [( H% [4 `1 P7 {  `; ?
  3. from web3 importWeb3, HTTPProvider( T, j4 ~% y( X: Q8 @. n
  4. from web3.contract importConciseContract
    0 H" C, k- x# x* J
  5. # compile your smart contract with truffle first
    ( K( C  M" g6 r" a' l- m! \3 `" y
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))
    - I1 |, D+ `! I2 P* F
  7. abi = truffleFile['abi']
    + I% ~; Q- C' D4 A6 Q
  8. bytecode = truffleFile['bytecode']
    6 X  i/ D. y2 y5 [6 n
  9. # web3.py instance" C& K+ z/ K( }' ^! e: O" Y9 R0 W
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))
    3 @6 e9 B0 e8 B1 Z' V2 W. I! R
  11. print(w3.isConnected())2 M; R. u) v# n- i9 h# [  P. e: o
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")
    % o5 @! M: n4 O6 R
  13. # Instantiate and deploy contract
    8 d, {, q  o( x1 R6 }
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    5 y" ~  F. \- u/ s5 m+ j  |: q
  15. # Contract instance
    : @8 @/ s* M5 b! w
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)! s& `: U9 q( f+ x/ t' C
  17. # Contract instance in concise mode
    9 z2 _7 _4 k  j+ M  I
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)1 B2 p4 h4 _, n( |& {# @
  19. # Getters + Setters for web3.eth.contract object ConciseContract+ |$ k! }" a# j1 d5 _9 [' s: U
  20. #print(format(contract_instance.getGreeting()))
    4 w! w1 t1 T" ?  b* S
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码
) u! B) g3 B7 v0 {

: w" }% L( p2 |# X" S" B) G* r# n# v% L- i) \0 c$ q
这是我所做的:
) |8 D* m; E3 C" C/ C6 A1 k7 Q. x& k2 r& H. i% F- c7 l/ g
导入的 web3 库和所有其他必需的模块+ r: e/ k5 m+ I  Y# y+ Y! L
通过指向 Ropsten Infura 节点启动 web3 提供程序
7 d3 J4 y7 ~- p; L9 Q; C5 K* w通过指向 abi 和 contract_Address 创建合约实例(来自上一步)3 I$ E7 F0 F0 |# ~* r
调用 getGreeting() 方法并在控制台打印结果$ b! G3 t: Z: E' r& ?
结论" i  T$ H( N1 C& x& C/ x+ _, v
% s; R) M) L5 p
您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。
7 v& `# P% P( z5 m) W; _) B- r2 ^0 c% Y; t6 G: }8 ^7 o4 m( W4 Y

; a( D/ l& w. a  s  g( @参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程+ I* `8 @) _2 W4 k) r  ?
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13