Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
3677 1 0
什么是 DApp
0 M# u, _& W# x8 L9 l& S* B" g
6 w3 p* k2 |. k# B2 g“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 库与区块链进行交互。
: y0 M6 `5 b; x2 y& R
! T5 a  l0 l) E% g( d) CDapps 开发包括三个简单的步骤:
* \! O+ [: r- E! ?+ M
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约
    0 g+ `- B# N" P# Y. d
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。( n) G& P) y8 Z0 T: x0 f

0 V9 u  D+ U; U5 p5 ?! `安装: k3 v' {! [. A! V

& A3 x$ L* w$ N( ^6 lPython 2.7 +9 ]5 h* x" L4 S2 t1 v. T
Node.js6 E% {: Z. K) d
Truffle
3 o! e1 \9 y& t+ [2 H! _1 s) k7 [
% {) w1 ?/ n# A. T$ ], V0 _
( Z8 e) I" z& m7 s0 J  ]npm install -g truffle4 |) t' H6 M: w3 B/ D: P7 n
Pip
4 L. E' N+ q7 W$ Z* B+ ^npm i pip
* M7 ]& h* S5 z& S1 wweb3.py
/ ~+ W# b4 i( Rpip install web3: ]" u4 F- S( F. |4 ^# A9 C0 ?
; V6 }: y6 W$ P5 s6 @

5 q6 X4 L3 T" J0 c; I$ ~Infura 项目 API
& X: y% [2 E) y- j; V# b前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。7 D' {( [& {8 k) x

7 ~# T4 G& d0 r4 U& Y/ {* h; e智能合约
  ^& U& B# ?. \8 l( K3 q4 T, r: r6 i9 E% O
每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。! b' F  h, p7 g- M4 {9 G( H) `" N2 S* Y
8 _9 @: ~0 I. x6 Q4 [8 a; y
  1. pragma solidity ^0.5.7;+ x! H! f% u/ d
  2. contract greeter{$ ]: b% i/ n/ Y% K/ \2 {
  3.     string greeting;5 a" [/ R! [; _, |  @9 M7 O# l' X
  4.     function greet(string memory _greeting)public{
    - v0 M0 O4 m4 R! C% G& u! E
  5.         greeting=_greeting;
    7 [0 F( h) Z# M. `# K* D
  6.     }
    ; I& [! X; h% t& ^/ r. ^# U
  7.     function getGreeting() public view returns(string memory) {9 K& ?# ~+ a4 U3 r9 j
  8.         return greeting;1 o* {: y' _1 v! p
  9.     }  V0 k2 k, t" k! F$ s
  10. }" C; l& J" m/ K6 U2 w  w$ v8 P
复制代码

; o8 e  r$ E0 T5 k& g1 U* b4 K" k: u# y: W0 o
您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。
  s* R' {- g, `- r
9 x4 W% {/ t5 ~8 G. x  n1. 在区块链网络上部署智能合约) B6 L+ B$ ]1 i; l! ^0 W
& `  b  }7 W; {4 S" Z- K
a) 创建项目:
( h1 N- s1 v! C9 P
; b) ?. E/ [& q" O* jmkdir pythonDapp  D% K& I$ w! l
cd pythonDapp; k$ t# p) i- D
truffle init4 c0 B2 _  ^' E0 ^
: i! t4 ~5 c% `4 t' g0 f6 O7 q

3 {" V# w9 e4 O/ S成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。
/ w4 Q/ R3 e- ?' g2 y
% f" o6 l4 Z+ C/ g. r4 Ib) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:
& K' Q1 _4 f( z  D: a& y% ?2 @9 k9 G8 s
4 \1 i- k5 Y6 d  v& O/ g. B
; U( D  t# l1 \, d: K6 o
truffle compile
, `4 s. f: k% D& {(or)
- D& r! ~- u2 C6 r) P. R+ x% A1 Mtruffle.cmd compile #(for windows only)
, b. ]  \8 s6 x. C- w; |, J- S* ]( K3 N, e' O  }0 F
6 l# c% c; H8 n7 q8 x4 O; u% w! d
上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。2 T( ]6 {' i! ^0 M

$ x# b) l  X2 Z- Zc) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。( Y/ [( V/ `6 l
$ u* |8 i4 @/ P
  1. import json
    & v1 A1 i& _( H/ N7 j+ j
  2. from web3 importWeb3, HTTPProvider) _! q+ u- X4 r1 q: C
  3. from web3.contract importConciseContract& a$ ^; T* t8 ]0 A2 ~: [8 ~- q
  4. # web3.py instance
    1 \" L) I( ^( D$ ~5 M
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))7 v, \" h3 q* q* c  e0 e/ ?
  6. print(w3.isConnected())
    + T& h+ v& v% q3 v$ E
  7. key="<Private Key here with 0x prefix>"
    4 d. q1 t4 j8 Y3 k/ S
  8. acct = w3.eth.account.privateKeyToAccount(key)
      f, U- K) [: k5 q
  9. # compile your smart contract with truffle first
    8 i3 ^& W7 U% l3 |: p. e
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))9 ]$ v) F7 [/ a2 E
  11. abi = truffleFile['abi']" j' J6 m$ u7 L- }8 N: [: t, r
  12. bytecode = truffleFile['bytecode']
      H; P5 x, X) Q* D' b& Z7 A
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi); s5 d# ~. u7 I2 K4 u
  14. #building transaction
    9 f. z" ^8 W9 d  N
  15. construct_txn = contract.constructor().buildTransaction({
    % C. }) R; N! T3 m* b2 ~/ S' x7 m
  16. 'from': acct.address,: z; |+ j7 d! ]# P+ `% r1 P
  17. 'nonce': w3.eth.getTransactionCount(acct.address),
    % W3 N; `: s) j: G! b
  18. 'gas': 1728712,
    ( @# \9 y0 v7 c+ M7 A7 Z
  19. 'gasPrice': w3.toWei('21', 'gwei')})
      g  L1 n/ i2 k& Y* Y+ U
  20. signed = acct.signTransaction(construct_txn)* L2 J" S% g! o
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)
    0 _) f5 q% q" y7 Y( g# ?9 }( E* r
  22. print(tx_hash.hex())
    # K* x+ O, w4 b( P6 V; ?" Z) F
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)4 N6 I. T; l( O4 X
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码
2 T, a+ j% [% O

% _( t, z, ~% r7 V" o
/ e, Q& A9 ?9 D% @; o这是我所做的:
6 i. n& P2 U4 F0 [6 _9 H5 [  U, j9 F3 N% Y! H1 a
导入的 web3 库和所有其他必需的模块) S& N& Q9 E7 `% d
通过指向 Ropsten Infura 节点启动 web3 提供程序/ C. Q) i! B$ j9 p: ^/ }3 s8 D* N% Z
添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。/ @/ C  b$ d9 l+ |# P
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
+ E) [3 |3 D( {- c" @5 i" R2 ~4 U$ u/ {添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。' m( n" B# |7 Z8 r8 c& X2 v! p
使用我们的私钥签署交易并在网络上广播。7 v. q5 o% Q% T2 u
在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。& O' `# F4 s1 V* R8 h) `  Y: D
2. 向部署的合约发送交易
( X9 X1 H9 {; O. y+ x
2 Q  Q  Q& v5 i% ^) o在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。/ p5 ^2 o6 }3 B$ j7 \
  1. import json
    3 h1 U* |; e( a, V& z
  2. from web3 importWeb3, HTTPProvider
    ! C6 `$ F( |5 u6 G
  3. from web3.contract importConciseContract
    " g0 i  j' ^3 R  q& f
  4. # compile your smart contract with truffle first
    " P+ h3 X) l: u
  5. truffleFile = json.load(open('./build/contracts/greeter.json'))
    4 m+ ]  {) n* N: w. i. h: \
  6. abi = truffleFile['abi']* H" z; f8 W9 l. Q9 ~
  7. bytecode = truffleFile['bytecode']
    ) F/ I6 P+ ^# {& I  I7 V* K" {
  8. # web3.py instance
    . B* a& W; q$ Z! Q+ g" n
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify" s/ E: q( N0 m9 A) {+ `
  10. print(w3.isConnected()): j7 H0 _0 y" ]) B* T9 i4 J7 e
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify" [) Z  J& L. h. Q* S% o# @6 f
  12. key="<Private key with 0x prefix here>"#modify
    5 y2 d* V- ~0 [
  13. acct = w3.eth.account.privateKeyToAccount(key)4 B5 k: A  [% C, t
  14. account_address= acct.address4 {; @9 o* @1 U2 L4 z3 _7 \( B
  15. # Instantiate and deploy contract
    $ Z9 f- Y5 I9 Q( G3 _5 H3 l& W4 g
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)+ u; `5 t0 e+ O1 I6 ~
  17. # Contract instance" j7 U( g/ |' h
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)' P8 I- G- J* d
  19. # Contract instance in concise mode
    # a" ]+ p# D$ U* J  X
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)' ^9 N1 c' q8 ^' m" @' W
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})8 o& \, N! {1 ~
  22. #Get tx receipt to get contract address
    , C7 Y. \: u2 S0 H+ q, `6 X5 X
  23. signed_tx = w3.eth.account.signTransaction(tx, key)
      `$ I2 Q1 V0 K
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
    3 W9 t7 A0 o) H/ Q  Q  X7 T8 v
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction); V" g; c$ H2 O! x# v' L
  26. print(hash.hex())
复制代码
" V* {# k5 V3 b) c# S9 C
1 X# B9 s+ K* Z% C# D# C" V3 k) E
  f2 @8 a* W% v3 B
这是我所做的:# I% J9 O' j2 w' G6 ?+ `  {) y
7 p4 V. Y4 @. j. {! w, H& S* z% }
导入的 web3 库和所有其他必需的模块2 L; Q3 g9 m5 a3 l5 U9 s
通过指向 Ropsten Infura 节点启动 web3 提供程序
& |; Y; B& Q- x1 M2 @. J% v2 Y添加了用于签署交易的帐户地址和私钥. s8 t& Q1 q# H; ], H
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例/ c4 d) ?$ ^1 P9 x. l, C8 b
创建 tx 对象以添加问候语“hello all my goody people”并建立交易
' E% ^6 `  _8 t. P使用我们的私钥签署交易并在网络上广播。3 e7 Z6 g3 s4 i( K
在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。
+ Q/ T6 g, A* d2 M% \6 q3. 从部署的智能合约中读取数据9 g% u% u9 B2 g/ a% f8 L" @3 q6 Q

- j* P/ ~4 P) l2 K+ F5 j在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。
! b  @$ x$ e% i6 G; e1 j

  1. . `- u7 P* u; p2 @& O* ?; N  x
  2. import json: P) `+ M7 Y% ^; F$ g% u
  3. from web3 importWeb3, HTTPProvider
    0 m% ?4 ^+ ?( o% h2 S  l
  4. from web3.contract importConciseContract
    , m4 w8 E9 {0 ?2 V# j
  5. # compile your smart contract with truffle first
    # m8 R0 S7 X7 x, D
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))( t* ]# V) O+ d8 F3 t6 y/ m
  7. abi = truffleFile['abi']4 S! \6 s$ C! C3 Z5 M2 \8 z
  8. bytecode = truffleFile['bytecode']6 c3 F& h& v+ j* i% T( K
  9. # web3.py instance
    2 W2 `( W5 F4 S1 W+ m. k% F
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))
    3 q0 _1 o8 }) t& J+ ]
  11. print(w3.isConnected())
    $ Z3 p  L% o& @: L8 A
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")
    " C1 r5 w! g/ P( K$ T( C
  13. # Instantiate and deploy contract
    $ B4 [1 _; Q9 G8 k
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    $ M" n& ]3 n* z, o8 Y/ }
  15. # Contract instance
    8 F0 g- ^. O# d. [
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    ' n2 w, O3 g0 J: q# K% @' S
  17. # Contract instance in concise mode
    : z+ r9 @  J( L& N1 P. w% _1 d
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    ; T+ {4 ^, Z/ a+ l: v% a
  19. # Getters + Setters for web3.eth.contract object ConciseContract
    ! V6 j1 S9 ?3 T! F' g! `3 Y+ S
  20. #print(format(contract_instance.getGreeting()))! ~( I+ q" c% f$ Z
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码
$ J0 h, m( N( j% g$ d2 f. Z7 f" }

( j  A3 H; s+ K$ @
/ Q  A! f4 I* p这是我所做的:( Q2 _% w% h6 b
; T* h6 D' B+ }8 J. {
导入的 web3 库和所有其他必需的模块+ M. S0 t% I& B. O* O
通过指向 Ropsten Infura 节点启动 web3 提供程序
0 ?* N- O) C# Q7 C+ u" z通过指向 abi 和 contract_Address 创建合约实例(来自上一步)
: K; h% V4 X% p3 X调用 getGreeting() 方法并在控制台打印结果) h0 l( x# q" e  Z6 }7 H
结论: l- k8 S+ ?/ B
6 ?0 p8 a% a9 J
您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。
5 q( Q0 a8 J4 o$ W$ F7 b
' C- V4 W% S4 h6 L4 O0 x! ]7 [$ ?  r3 W$ N
参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程
7 Z1 f+ ~0 ^5 P9 Z7 o7 Y' k
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13