Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
2719 1 0
什么是 DApp4 c. z2 A1 N( y5 H. ^+ A

6 h! X/ ]) G: u% \1 `9 v  r: @5 k“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 库与区块链进行交互。0 t2 g) h4 u/ r5 _9 W, y& ^; D6 Y. g

7 v! q- Z5 v3 A0 u' XDapps 开发包括三个简单的步骤:. u. C0 M6 z/ b+ e8 Y) e
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约
    ; ~) a7 L$ \! u
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。
8 J! R4 ]! D& W; T. V" F+ M; R2 X; I. T) [. Y0 ~0 G
安装- c3 m) Y* j& U/ z

6 ]: R2 j. q8 q# m# N! f, J! BPython 2.7 +8 @& z/ b! y1 ^" |1 T
Node.js- b/ e4 e$ P1 u, H0 a  e6 M
Truffle
" f- T2 J! I, n) w2 e" t, O  }0 L) ?- i8 `) M9 V

& D* G0 l! m' J$ l- @npm install -g truffle
' _! L; O# s4 e+ P- K$ }" FPip
! J/ f$ v$ F" n( {# r+ U6 g5 Pnpm i pip
, a7 E. b, W) j9 S: Mweb3.py
* \( _8 B, d3 K' b0 ppip install web3- N1 d3 r* b. i! N
/ h- \, b' p" d1 w% j% f
7 D$ e' s, ]0 ~1 A  V
Infura 项目 API
% G* u" e5 ?( q8 R5 @2 H7 |前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。4 j; x1 u! A5 b7 |" F- f

1 f! t7 c2 N& W  U- s5 Z. ]. v智能合约
& `$ A7 ?2 u8 _. @. }: S
: O( [, I4 H7 k7 V每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。* H- k& J7 F& Y1 G8 }& z# ^4 _
  d6 N) g' X. d- G
  1. pragma solidity ^0.5.7;3 X6 P9 W, H* p5 {! a' K, M
  2. contract greeter{/ o2 F1 C$ ]6 o3 }" E
  3.     string greeting;  P2 C2 b+ [8 c
  4.     function greet(string memory _greeting)public{
    . m, o# Q  W7 F$ s3 r
  5.         greeting=_greeting;
    0 g6 m" C, A) t8 F. W# B0 J* a
  6.     }
    9 K. R/ t9 \; I8 u
  7.     function getGreeting() public view returns(string memory) {
    / J+ P- m2 @; x/ }6 C
  8.         return greeting;
    # Y1 F8 w4 V- S" e
  9.     }, }$ I2 ~) Z7 U$ W: W
  10. }
    " j. Q+ T6 M0 D: i
复制代码
) X6 D8 ]1 \; ]: t+ ~# Q
) i  a/ i1 e$ \% Q9 K( I# y! Z% ]
您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。
2 L* y1 I# O; s- d, o
8 [5 s! A+ V+ C1 G' l1. 在区块链网络上部署智能合约/ z& |" D$ r0 y
% O% }. H2 ?9 @, `
a) 创建项目:
+ a: N! s8 `& `% [' D8 v4 p, G% Z
mkdir pythonDapp
+ U4 [# [) ]# b& `, [cd pythonDapp
- s* E# a3 t; H: Ytruffle init, q8 J# A# k+ Z/ p& _$ A

) g7 r* P: u0 T: Y
6 B. m# \! d  Q0 V& i成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。- }# @* O& b: t4 h6 m

. c- q5 N! Z" q4 K2 H3 u* P4 Mb) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:
5 M  v; v# G, D% N; R: {6 A+ p/ Q3 O# r- i# ?( d+ v& D9 k- m

) G/ E, i! |0 c: p6 A6 i3 X  O, \: F) F: B( L
truffle compile9 _: N" O5 x7 t" o! K5 U
(or)
# ~( {, C1 h# S8 H& }truffle.cmd compile #(for windows only)
% @- l5 w; N! H4 `9 K) Y" c* a& ?  R5 @! W, a0 o
& U1 s; ~4 E% x) u/ i) K+ n" F
上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。. p# |8 C# j& t+ B& @2 @

! l( P. Q$ y3 Wc) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。
5 E4 d' v1 f) t3 f* j9 I
( f( K2 ^8 X. v7 r0 P8 F4 Z
  1. import json1 ~* M( @/ r9 \2 ?
  2. from web3 importWeb3, HTTPProvider
    1 g/ X. I( n3 @! a! D3 j# @( J$ v
  3. from web3.contract importConciseContract# H9 W, R0 Y( @$ |) k8 P/ z
  4. # web3.py instance
    6 J9 ?6 z5 V! P' B, N. J( u
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))& o0 s1 G* E5 _" B
  6. print(w3.isConnected())* u" C$ O% I4 w
  7. key="<Private Key here with 0x prefix>"3 E+ ^$ P4 L* p2 O/ Y% j! d- |
  8. acct = w3.eth.account.privateKeyToAccount(key)" x. Z4 a9 B7 U3 I2 n
  9. # compile your smart contract with truffle first+ g* P: [: n( C3 B8 N! g( J
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))
    8 ^5 a# S) E% s" ~
  11. abi = truffleFile['abi']
    2 r  E' Z& _' U* S1 ]0 Y
  12. bytecode = truffleFile['bytecode']# T* h7 O/ p0 ~$ U6 g% N+ c
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi)* s2 B; T2 Q! g, s) ~
  14. #building transaction( g$ ~1 T0 |: [0 u2 e0 S1 c9 `
  15. construct_txn = contract.constructor().buildTransaction({4 x. Y: q# Z9 ]/ c) T( N7 U
  16. 'from': acct.address,
    ( x& u2 k2 u% e
  17. 'nonce': w3.eth.getTransactionCount(acct.address),3 Q" e0 o0 L. I6 _& v5 l
  18. 'gas': 1728712,
    " E5 q( V% W; {+ E1 x
  19. 'gasPrice': w3.toWei('21', 'gwei')})2 a) V. [* Q. @' x% l
  20. signed = acct.signTransaction(construct_txn)
    $ a$ w; k  Z* k3 N# c2 h
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)# P& ]7 W4 ^/ C$ w
  22. print(tx_hash.hex())
    9 ]. N7 }: d$ \6 |4 h( M* o
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)8 ?4 Z& l, m7 L5 g& X
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码

+ t5 \' F5 J, S- d/ x/ d5 ?' a9 k6 i; @* x9 k, o7 F$ o

5 R$ r8 }! S, }" ~- a+ z2 i: y% }这是我所做的:
5 H8 z* D# d) I0 n0 N
# f5 v' t% w; z4 B- e' g1 n" T导入的 web3 库和所有其他必需的模块; h0 a7 h  |2 ~* D  b. ~
通过指向 Ropsten Infura 节点启动 web3 提供程序
$ B& V) Y# K8 |  P# a添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。- M2 t/ q! ?) C3 B9 a1 r/ q# s
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例* ?% V9 F6 [9 n7 ^9 z
添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。
5 q/ J. Y( j# O3 E使用我们的私钥签署交易并在网络上广播。
  r5 w( w% P; \9 }, ]$ r  K在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。* u2 r& h9 g, j$ i2 ^6 _2 w
2. 向部署的合约发送交易
# L" Z: a% q* T3 A6 }1 S2 H6 b% y2 h* q
在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。
0 d( O* {7 s4 X
  1. import json3 G9 V2 Y& F7 O
  2. from web3 importWeb3, HTTPProvider
    4 V" I: Q+ m" a) M4 v
  3. from web3.contract importConciseContract
    ( x2 V! ], S( Q/ Q  U
  4. # compile your smart contract with truffle first' `5 d. O) E4 K! h/ X
  5. truffleFile = json.load(open('./build/contracts/greeter.json')): N" J3 d- i( a: Q( ^1 i; C' U
  6. abi = truffleFile['abi']
    ' r5 \+ }- ^( O
  7. bytecode = truffleFile['bytecode']6 t; k6 C# p. b, t! N
  8. # web3.py instance
    6 Z- @( e! |5 G; v/ H- n
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify
    4 u4 z. ~% Z+ {5 n
  10. print(w3.isConnected())2 o; B7 g% H4 N5 ^3 u0 K
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify
    4 |( w; z( z* S! q4 b; `
  12. key="<Private key with 0x prefix here>"#modify  T% B, @$ q( e. c/ n" |
  13. acct = w3.eth.account.privateKeyToAccount(key)
    . e: B. T) d# |7 s3 y& @* X
  14. account_address= acct.address
    + _; @; q! K, l$ {- U+ ~) F% a
  15. # Instantiate and deploy contract
      d* k. H3 g0 M) W
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    2 }$ U5 x' n# ^& P! f
  17. # Contract instance+ j5 h$ L& K3 f! A6 @9 R
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    - X/ J: r7 T" m+ U4 n- g
  19. # Contract instance in concise mode: Z! u2 r' a3 }  }3 \5 }
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    4 O; ~' u3 q8 m2 W; x. q; E
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})2 F" T! D: R9 C2 R& T0 X) Y
  22. #Get tx receipt to get contract address$ Y3 L1 w7 s( Z& y4 s
  23. signed_tx = w3.eth.account.signTransaction(tx, key)' R; X$ U, Q# m! u1 K/ C& E
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
    7 x9 R" y1 S. Y% R) V' q2 J
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)
    / H1 S9 y7 i  [  a5 S; R
  26. print(hash.hex())
复制代码

: O" j! t3 a! U" x: h7 _: J
- s* Q$ T2 M% T# ^( C! m( }1 z5 T) A! `" l9 l$ [! O$ k
这是我所做的:
! F( c4 t/ e) s- R: ?# _( n7 Q1 Q6 r0 W6 ]; B/ c
导入的 web3 库和所有其他必需的模块
  u, y3 M  L0 i+ E0 z  K+ R$ ^: W: u通过指向 Ropsten Infura 节点启动 web3 提供程序1 X/ S6 D& [+ ]
添加了用于签署交易的帐户地址和私钥/ o4 L7 o9 s8 `% [: s8 Q
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
. ]. U" B. q- s6 r# r. R创建 tx 对象以添加问候语“hello all my goody people”并建立交易8 |9 i* b* ^' V1 T( C. ^! s2 a0 F
使用我们的私钥签署交易并在网络上广播。
+ r! S- v# D# d3 r' z; i% t0 c在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。
. o2 v( p0 {& P( _$ A5 t% W; _. q6 B$ Y3. 从部署的智能合约中读取数据3 X7 m7 m5 o  x/ W- @0 u
5 ~+ T& z( R  G# P6 M
在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。
/ K3 i7 D+ L4 A- ^7 i
  1. ; m# B& j( s% y5 n! {, {1 @
  2. import json; a* Y+ j+ D% J6 J" C7 r
  3. from web3 importWeb3, HTTPProvider7 C5 A: \2 }" P) q1 a
  4. from web3.contract importConciseContract
    + p2 x* ~% w  A3 y& W
  5. # compile your smart contract with truffle first
    - g1 U4 J* c. S- W% J, d
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))
    ! O" g, ]" O$ A: a2 U( ?
  7. abi = truffleFile['abi']
    6 D8 ]7 U$ j+ U& G! x6 F, V
  8. bytecode = truffleFile['bytecode']
    6 _% \0 [. C# D
  9. # web3.py instance9 I/ U0 a" s9 Q8 h! Y* V
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))
    0 e; s+ f$ X9 y1 U% ^" @5 s
  11. print(w3.isConnected())
      T- w" I6 ]2 R" R
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")
    # d& m' {" p, h& f
  13. # Instantiate and deploy contract' M( U3 c) D- r; E, m( F
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    % ~" @% C: h- p
  15. # Contract instance
    - s- t  e1 }1 i5 D" S
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)$ }6 o5 h' W; v* v( u/ t
  17. # Contract instance in concise mode
    2 Q: k0 ]: Q8 R) H/ S$ K
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    % E: M$ `# D6 B/ x) d* `4 H* f
  19. # Getters + Setters for web3.eth.contract object ConciseContract
    ) G; t. Z  E; ?; q
  20. #print(format(contract_instance.getGreeting()))
    7 r, ?6 A; }4 M0 m$ R5 v# Z
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码

; F) I9 u! t" y! }4 a/ K" E- V) m' a' Q. L" D5 O
* V  F/ x% L# Y( O( t5 z  E
这是我所做的:
  S9 O# u" n1 }% [. s: }
4 Z& q, Z; J5 l/ k  I! O3 {导入的 web3 库和所有其他必需的模块
, |5 `7 x+ P) M1 `% Z/ ?/ z通过指向 Ropsten Infura 节点启动 web3 提供程序
$ q: z7 z8 ]4 j, j& b) E0 I通过指向 abi 和 contract_Address 创建合约实例(来自上一步)3 M5 E3 J3 G% y! a- d
调用 getGreeting() 方法并在控制台打印结果
1 J, R' m" b2 \0 Z2 c结论
, `' k7 p+ A: r
  r) D: I6 b$ y* g) D5 x# Z( ^% {您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。5 r0 b5 v" h; I2 f. C  C

' I, Q7 r' b8 G5 Y8 R% n: h" X1 j  J. [% k4 f% W2 @+ W3 @* e7 x' |
参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程
) C9 ~& s% P* J+ \& i/ @
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13