Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
2627 1 0
什么是 DApp
8 ]; B- u. b6 T; b( T5 ]" U& P1 ^$ m' i( R/ w8 H% i
“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 库与区块链进行交互。' L" e, t& `+ g1 W  e8 T, s: C/ N% S1 l

: z' i) ~4 y6 E: t) nDapps 开发包括三个简单的步骤:3 G5 W$ u5 r5 w3 Y* M* m
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约; E- g' P5 i" Y6 H% Z. t
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。3 n2 x. U7 n& B: F; L5 w+ B
) H' j( r( V8 F4 c9 G, j6 ^
安装
3 g3 V" U' I5 F4 y1 Q  F8 z
$ i0 r2 r0 k4 v1 o+ Q& @. [Python 2.7 +4 m6 r6 e7 D1 n% i
Node.js
4 L0 T; G1 _# P( r# s7 hTruffle
( V4 d  n" g. F$ X4 X4 x0 h9 T+ ~+ f: X7 [& x6 S$ z# e3 F* G3 h% t

* s' G* V% ~$ _npm install -g truffle
4 H$ M# r+ P) @# a) n3 O6 yPip
% j, P9 M+ e3 Unpm i pip" w* I: y# ^) k( _' }0 E; j
web3.py" W. v6 J( U, @- }# d
pip install web3
: C) x1 w7 y3 y' l6 I& j
+ D4 G/ q8 l  U! J. O
$ a3 T0 ^- T/ O( RInfura 项目 API9 I  r; ?1 ]: Y0 U/ h! x
前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。& c. I1 J2 {  ?3 W/ h
/ a5 R4 R# y* `( q: \
智能合约
; |/ o- J" j; D: f4 i* H
9 k  E- }4 Z0 E4 L9 d" |0 F每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。; ?( o# d$ B+ r" [: R1 @3 T- G. d( }
3 |/ Q& E) b& |# u9 f
  1. pragma solidity ^0.5.7;
    + \& N5 s  J9 j" o  x8 e' p
  2. contract greeter{
    ) M! g% A: x8 @: m8 `/ ^
  3.     string greeting;5 q% ^7 [6 u9 G: ^% g
  4.     function greet(string memory _greeting)public{
    7 I/ u: s7 t* ^. {- s" \4 ^
  5.         greeting=_greeting;/ d2 z& v' l# T: i  p$ L4 @
  6.     }8 A, ~& G9 W4 \+ \
  7.     function getGreeting() public view returns(string memory) {
    " ]8 B) K  C8 k9 k% P, P
  8.         return greeting;
    & M& D" e( @+ `  O
  9.     }
    - o7 m5 Y8 F5 ~5 e8 x
  10. }9 P- F, T9 |* J+ |; c& K" y/ @
复制代码
2 }$ d0 X4 e. X8 P, u- k. {) n
4 N* P, Z+ `4 v. w, P% a! ]
您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。
$ |5 @: w1 X2 I7 u" c
3 }0 x1 C1 t, g; i8 p. t. C/ d! S$ W1. 在区块链网络上部署智能合约  m* P) \; ~3 @" f( @

9 j: Q' Y0 b( f2 u  ^  Va) 创建项目:. U. M1 j6 d3 h( T/ \, K

/ E6 f+ V3 [) J: P% ?. z" ]( `mkdir pythonDapp1 B$ N6 c% [6 g
cd pythonDapp: n" Q, Z4 l3 W1 L+ B. Q
truffle init
; h4 `! o" Y6 }- Y0 O9 |" x
) c; [8 S3 `9 ?& H* G. G2 r: d
( b) P/ F1 j* z+ \/ P" B成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。
9 k; t& ~4 ^4 p. y6 w! X" G( e+ w3 x- W" G1 g* Q0 s
b) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:
, A; r% @/ [( q
% u5 F& g/ T' k/ [
8 ]# t( m. a% j6 T0 F/ c* m" m3 T9 {1 `- ~5 W+ G. k
truffle compile
+ N' q( T7 n! V- t5 f8 O(or)
( w/ H9 H! j$ x  J0 J; v3 Struffle.cmd compile #(for windows only)/ y& x) |! {; O! Z* v
9 N& |6 Z; O( @! \
3 {5 z3 w, K1 I
上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。/ f2 }; f* {6 A6 X! e; G

1 I4 ^9 C$ |" K* M! qc) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。
0 g. z1 u3 Q+ ~& R* w0 l/ w& h7 R2 @' x( x; k
  1. import json
    # m! ~- g: X' @4 L8 q
  2. from web3 importWeb3, HTTPProvider: S- H# b  [+ s: I2 |4 B0 |
  3. from web3.contract importConciseContract1 L$ v$ \9 I6 ?; u( b
  4. # web3.py instance. l3 m0 `8 _; P( t& Q
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))8 s/ z) i! q, M' Z4 v4 }
  6. print(w3.isConnected())
    5 M6 L  Z+ S9 w6 L. u( w
  7. key="<Private Key here with 0x prefix>"
    6 _" N2 U; |. C; v/ `4 l
  8. acct = w3.eth.account.privateKeyToAccount(key)" i! i8 ^6 x. ~& ?' ^2 z3 e6 y
  9. # compile your smart contract with truffle first& N3 r. g0 {5 R
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))
    # g( S8 @6 B' ^- ?6 X: Q; x
  11. abi = truffleFile['abi']3 L* V8 n5 d/ N" R. {
  12. bytecode = truffleFile['bytecode']
    : S+ c: g4 m0 K4 K; a! Y
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi)
    4 Y' W- R- d/ u) ~. ~
  14. #building transaction  T: [" M6 Y0 J' V0 F
  15. construct_txn = contract.constructor().buildTransaction({% ]4 }& L' ?) i8 j2 h
  16. 'from': acct.address,
    , g" {: T1 g( m; A9 c' ^* }
  17. 'nonce': w3.eth.getTransactionCount(acct.address),
    0 Q2 v! [( T' c0 D6 q5 N6 V
  18. 'gas': 1728712,% l+ c$ [1 R% @. r" P" s0 T1 Y
  19. 'gasPrice': w3.toWei('21', 'gwei')})1 V4 m  b: `/ t9 A  N0 l! Q
  20. signed = acct.signTransaction(construct_txn)
    1 f3 ?; P6 V8 A$ Z
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)5 L# T% y. H1 C1 n! @
  22. print(tx_hash.hex())
    $ B3 r3 o6 u& O, |  X5 O3 `
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)" A( y0 p* r* p* n. b7 X
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码

' D, v  x! n! k4 H$ ^, f: _  D
) R( F- Z" d2 I
1 e6 S3 Y/ l, n) O0 o( }6 ?: O! I这是我所做的:
) j0 Y: G  t! [  Q5 X! _" r$ X% H! k6 [/ f/ Z4 U* \
导入的 web3 库和所有其他必需的模块, A. _; s( C0 R% g$ Q
通过指向 Ropsten Infura 节点启动 web3 提供程序0 |" s0 K0 C7 R. l* i2 C
添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。
$ I' H0 p# _; K, g通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
, ^: x/ H$ X" @9 A添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。
  p( }, Z; \# p使用我们的私钥签署交易并在网络上广播。
$ G3 P; ?+ ^/ \) }在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。
6 o9 y) `5 b9 I2 `5 _2. 向部署的合约发送交易, ~. Y$ B# a" l! h

4 y- @. I  j, {+ _+ V6 |& d0 R' C在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。
, q% M/ v( e& P7 c
  1. import json
    " o- L# p. G5 T6 P
  2. from web3 importWeb3, HTTPProvider  i# i2 E: ^/ G
  3. from web3.contract importConciseContract
    & n0 I) n  d. Y  e/ b. f
  4. # compile your smart contract with truffle first: a% ]* M, B! u3 O" V( K5 C& b9 Y
  5. truffleFile = json.load(open('./build/contracts/greeter.json'))( b4 J) ]( \4 o3 u" ?4 ]2 Q6 m
  6. abi = truffleFile['abi']) y0 b9 y, D) R3 b  P1 p
  7. bytecode = truffleFile['bytecode']
    ! ~7 J8 w7 U( F$ T
  8. # web3.py instance
    6 z- I( T, {8 R% a% w9 M+ M, S( ^1 Z4 m
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify* |2 W7 B; z" t# h1 Y% t; h, K0 z
  10. print(w3.isConnected())
    0 y$ X6 F' W6 I; i* @
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify- c2 v" T5 k" V) `" _) d0 `5 f
  12. key="<Private key with 0x prefix here>"#modify/ B1 ^" |; F9 I: L6 h( W
  13. acct = w3.eth.account.privateKeyToAccount(key)7 h/ ]2 J* J8 T
  14. account_address= acct.address
    - l: U5 K5 x. d2 y, W* _* }/ K3 Z
  15. # Instantiate and deploy contract$ O% e' l9 A7 x0 N3 G, o  s+ c
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)9 l0 K+ Q3 k% A* j4 Q# U5 W
  17. # Contract instance
    5 J1 N: _7 U  s
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    + l, D( o; L7 [8 ]( i. o1 e
  19. # Contract instance in concise mode
    8 [/ M: f. k, D6 k" G: t% R: R
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    ! K$ `  w4 u3 {! o; L& Y% g
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})) t1 N, @* {, V0 E. c9 ^) Q
  22. #Get tx receipt to get contract address; y4 v% w$ D- _3 p( k2 e, @& j8 V( f
  23. signed_tx = w3.eth.account.signTransaction(tx, key)7 g: O; e% y, @1 g2 u( R& \8 ~  o! a
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
    1 A/ Y% z9 E6 G" n% [
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction), \" H3 W$ k$ z( c# Q9 n0 B
  26. print(hash.hex())
复制代码
' |  E, p2 h* Y+ A# O% D* `
: i$ V* l" U3 H% z- ^
# v0 R/ c7 f( e' v! W! v  Q
这是我所做的:
  O% G3 y+ ~' W5 u+ S6 q/ T
: @% k' G; P0 g, e导入的 web3 库和所有其他必需的模块
" }' m: M/ u+ {: E- F通过指向 Ropsten Infura 节点启动 web3 提供程序( b6 C6 A9 B8 B- u
添加了用于签署交易的帐户地址和私钥
" _4 I2 h+ v3 {+ |. q1 |" `通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
5 ~% l# S8 A4 |/ Y; o创建 tx 对象以添加问候语“hello all my goody people”并建立交易
3 n9 U& `* ^# g* j2 i1 @使用我们的私钥签署交易并在网络上广播。3 ~5 f  x( o( {' `$ M& k
在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。
* ~+ ~% b9 ~& E  Z7 D) `3. 从部署的智能合约中读取数据" p2 S0 ^. X6 Q9 l

: V6 @( H, l4 C$ ?+ l8 H7 h在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。, M2 q, B; Y; t) h4 A

  1. 9 d7 ?$ S: D! F8 l! g. s
  2. import json9 p- k/ E$ C/ X% U3 `: R
  3. from web3 importWeb3, HTTPProvider4 E+ t& G0 h/ F4 M# [9 c. H1 ?0 n
  4. from web3.contract importConciseContract
    6 R% z. W: z: \) w* K6 e4 F
  5. # compile your smart contract with truffle first  S+ {, @1 l; f# e5 S3 S; O, U
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))- ^- U* c  Z3 `  R. F! G
  7. abi = truffleFile['abi']# k! u! q1 M$ X/ u& b
  8. bytecode = truffleFile['bytecode']0 q  V# z* p! R
  9. # web3.py instance
    0 C7 d5 i- c& z
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))5 I' p( ?/ ~' e
  11. print(w3.isConnected())( I3 F7 V6 r' v1 R
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")3 j. C4 K# }) r: |1 r9 j7 s
  13. # Instantiate and deploy contract
    , i. M: L2 [6 z
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    # }7 O. a9 ~: ~# N9 h/ U
  15. # Contract instance# \) x4 X% w- W
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    ; {  a3 w# `" F
  17. # Contract instance in concise mode) u% V1 p4 B9 n! V' P% P% H2 t
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    ; @! R  b3 h! ]! e
  19. # Getters + Setters for web3.eth.contract object ConciseContract! x8 Z% t. K% p, G" g  L
  20. #print(format(contract_instance.getGreeting()))
    & \" C8 B$ \0 |/ K' r
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码
2 Z9 a" E7 |3 i1 ]' o8 ?

' x2 |: A+ {3 h' i  |- Q
, x% Q* F' k; _5 f" j这是我所做的:
: G; @! U2 Y- x5 |
, Y6 p0 B( a% O0 k导入的 web3 库和所有其他必需的模块
( C( a$ T) x) j0 d0 O通过指向 Ropsten Infura 节点启动 web3 提供程序# H5 R( ]! c- T1 ^' O. o8 Y8 w$ l
通过指向 abi 和 contract_Address 创建合约实例(来自上一步)
; a9 w# f0 d& q9 ?; u6 \调用 getGreeting() 方法并在控制台打印结果$ U  ]+ w! m; l4 K+ G& ?
结论" x% |0 a" A7 w% [, q
7 U# u% [( c$ F# y9 y6 W- ]
您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。
: B/ W9 Z! ?+ t, n0 j6 Y" c6 \( j( P( Q& h

1 ^: r! b  a7 Y; }参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程
! U- @- D- Z3 {& A
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13