Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
3680 1 0
什么是 DApp3 z: o# I& ~3 N" B# s! ~, Z& U% o

8 y1 r* b  m7 Y“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 t, |% z( L- S; R" r) P% G
+ i) Q; O4 ]4 L. A% S& _! e* IDapps 开发包括三个简单的步骤:7 U+ r1 J! p$ B, S1 W/ z( ~
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约
    / l9 t. m1 G. e6 Q) m
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。
- _* j. Q2 [8 W3 p  b1 @2 h. v8 X! h0 T8 f" F$ j& n7 v9 ]/ `
安装& a4 n4 z. r1 I7 {9 Y

3 y- P/ g' D1 I& l- S9 SPython 2.7 +
$ S& N& V1 ?# _7 L! aNode.js$ R9 o/ n/ a8 u) h! r# Y9 q' K  Z$ }
Truffle
* e4 o/ K# u: {: O. m0 r0 R8 n

1 }6 e5 J. O4 k2 x2 G6 Enpm install -g truffle
" h, z8 w0 X! ^$ \' }. UPip
- z( R6 d; }1 n  y) @- bnpm i pip
) ?0 U  D% q' u' c9 q8 X7 G5 Iweb3.py
6 d1 m+ }8 O" c7 b5 Tpip install web33 Y! p+ Z7 J. a" G* h9 K0 v
; U9 ?" Y8 G9 g( z7 m- o

. [# B5 V* T# Q% L. T  p9 jInfura 项目 API7 L/ D- U, J0 |  N
前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。
8 i& g) N$ ]  [0 R
% I8 C/ W9 T* C" q4 u智能合约( b2 D* i9 p6 M; M+ @( ?0 g1 w
$ y, t7 S8 v. I( ?/ Z, y: _
每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。
; O+ L8 r( e3 [& ?- h7 a8 f* k; M$ ~" b; Y6 |& z8 J% d
  1. pragma solidity ^0.5.7;, f, z4 k  \4 s$ T) Y
  2. contract greeter{
      M" d, C5 a  ^; w
  3.     string greeting;8 I0 [! G; t& A7 q" O+ J/ s
  4.     function greet(string memory _greeting)public{( E7 ~7 t) _% C6 O% z# w! v
  5.         greeting=_greeting;; M% E2 c  q5 O6 Q# V5 y
  6.     }8 C: i. o& A/ H- F2 H
  7.     function getGreeting() public view returns(string memory) {2 N4 Z+ |' @- M: V; f, Q# H- r4 K- p
  8.         return greeting;  l, R- |% t9 a5 |5 y4 y
  9.     }5 ~: M$ h0 `# d6 q# k$ a( ^  H
  10. }
    : ~. |/ m8 O1 x: q; i
复制代码
* U. Q% f$ c7 A5 S% y

# u$ Y# p5 n$ t您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。
1 K3 }% o: v. a* {, Q( S# R$ t3 [5 M2 W; ~4 i$ y
1. 在区块链网络上部署智能合约
  }2 e. r8 g9 b' v7 G2 X2 Q
5 f* w, `  `( t+ n5 R- Y7 za) 创建项目:# H% W5 ]" S/ R' @4 d- l3 r+ h
6 Y8 H- |; A3 ]" R  Z
mkdir pythonDapp
. c8 k7 U2 N/ Qcd pythonDapp, q9 Z5 J" b6 t2 \
truffle init
8 f$ {# o8 k2 T4 b5 z7 m1 m( e" D# E  d: d/ x
- _+ ~% Z, Q7 S
成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。
) j. x/ z5 D& p  V2 I$ P+ Q2 d9 U
7 W' P* G. K: m6 \b) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:
2 d# O5 T9 `- C) n: Y  n& u" i$ o/ f4 A; z
) ]! S; j$ U% }9 m2 I
; S* @) c0 h8 M- o
truffle compile
  P' [; {* q$ z# j(or)
+ _0 X6 C6 w( v' qtruffle.cmd compile #(for windows only)
  Y  P; Q/ V2 T2 ^! \# y! X! h) ^. l' V6 T% l; ^
. R, O3 J1 M( W  a* I: E% h" E
上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。
3 Z+ d" z& B6 t) L9 e
. O1 U9 V2 n7 z  t" ~- Cc) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。1 y; x: J  h$ L8 ?7 E7 z

- ^+ \* X3 F8 k
  1. import json
    ) T& @8 x# f6 T& h( K' n) E6 X9 b& \
  2. from web3 importWeb3, HTTPProvider
    * Q) j$ Z8 y+ k) f
  3. from web3.contract importConciseContract5 [0 j  b8 o6 S$ f( N$ g
  4. # web3.py instance1 x6 W0 ^# q: ~, \8 g- U& c
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))2 Q- m$ P: C; o; N( i+ S8 X* m
  6. print(w3.isConnected())
    8 T, _' r: k/ O
  7. key="<Private Key here with 0x prefix>"2 i7 [; D  x! Z; P' T: q
  8. acct = w3.eth.account.privateKeyToAccount(key)0 h! _9 u% U# `  }
  9. # compile your smart contract with truffle first
    ) i, p2 G; G5 J/ }+ K3 o
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))5 `0 P, h# l1 G7 W$ y
  11. abi = truffleFile['abi']  M4 S, O3 ^$ u. W
  12. bytecode = truffleFile['bytecode']
    ) P+ c+ N" B( `
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi)& ?/ ^$ b1 D7 \: m1 T# f) J
  14. #building transaction
    1 I1 O+ U. ], m
  15. construct_txn = contract.constructor().buildTransaction({7 u9 ~1 x( d: W" D- D6 a$ Y0 h- b
  16. 'from': acct.address,) j# Q% P; Y  k" G# a! v$ g& L5 p
  17. 'nonce': w3.eth.getTransactionCount(acct.address),
    6 K2 u0 m7 P6 p) n) ~1 {0 a
  18. 'gas': 1728712,
    8 H% z5 e1 I$ K" E+ q
  19. 'gasPrice': w3.toWei('21', 'gwei')})" Z$ r9 F, M  K& a, i; |, v$ T0 K
  20. signed = acct.signTransaction(construct_txn)
    . [; T8 `; D( f1 L7 \9 ]! k! Y, }
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)
    - f* y% A' U( R# q
  22. print(tx_hash.hex())) G4 K$ @. c% e* `! L2 ]
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)& j! ~$ a  g7 q8 I
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码

5 D8 v/ Q0 P. w# F& s
" R8 z6 D& u2 \- d2 L% g( \- ]. I4 c
这是我所做的:
! k9 R& [1 d0 y, k$ s+ a: c+ y
% k" R. R( m* V/ O3 m: u* G6 y导入的 web3 库和所有其他必需的模块
7 R7 }* [1 K+ v: W- P通过指向 Ropsten Infura 节点启动 web3 提供程序1 G2 q" m2 Z/ x+ {! D! g8 i
添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。+ Y+ V$ B' I) P# l6 ?4 X
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例5 ?8 e, v4 U9 d! O7 h& G, E
添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。
5 m' [, L( h0 q8 Q! k使用我们的私钥签署交易并在网络上广播。
0 Y8 F" ^" v+ ]: ?- c" M. b/ Z在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。
% g7 }* d) U# o2 J6 m' ]$ b2. 向部署的合约发送交易
0 p2 K, N: ]0 u& S% R# {; Y3 Z7 n6 x% S: O
在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。
& b& x  i* a4 ~6 M$ a
  1. import json. d0 i% l9 T8 Y4 d3 }$ B/ b$ W
  2. from web3 importWeb3, HTTPProvider* s, @  r" J3 q0 y1 X4 l! `$ f
  3. from web3.contract importConciseContract
    / `- m  o' T9 P8 J8 P. G
  4. # compile your smart contract with truffle first) |" h  e9 i0 C
  5. truffleFile = json.load(open('./build/contracts/greeter.json'))7 D' M6 G+ Y& T$ a4 d
  6. abi = truffleFile['abi']6 f% N* J* ~! W4 ^. f& F& X
  7. bytecode = truffleFile['bytecode']
      d6 o, `, M$ X/ V. \+ m; u
  8. # web3.py instance
    ) W' F5 p) [3 l  B
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify
    : f" R! k1 B; G+ B- b$ n% S" e
  10. print(w3.isConnected())
    7 X' G3 L* \+ n
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify/ D5 _; P3 I  _, v9 m; L% a9 q, p+ s
  12. key="<Private key with 0x prefix here>"#modify
    # `+ P1 ^/ H" @) }( y/ J
  13. acct = w3.eth.account.privateKeyToAccount(key)0 H4 r( {6 {; c! C" a! q: D
  14. account_address= acct.address
    3 u7 M& e5 l" I' N/ b
  15. # Instantiate and deploy contract) E$ w! e- d- {7 }+ n% Y
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)" {+ f4 W& P: y- F  n1 |% n
  17. # Contract instance1 K" _% `, l- ]- e# E* L+ N
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    ! H8 F0 {) O7 k, Y" G3 H1 M6 }
  19. # Contract instance in concise mode
    % A/ H$ r- k$ d4 X  p, l" R& q
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)6 Z; O; y0 h7 }& J6 c
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})
    ( d4 R1 c/ |' _5 b3 H, A
  22. #Get tx receipt to get contract address
    3 h: L9 L! `% V6 @  \$ n$ a/ D
  23. signed_tx = w3.eth.account.signTransaction(tx, key)
    % L( ^2 ~% Y' }) m1 u& ?% _1 Q
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
    6 B* H6 S2 E2 h) k: r6 }1 i
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)
    4 t, ], z; ]' G* z/ h& p' k9 @
  26. print(hash.hex())
复制代码

; f. M0 T3 p% F
. `) m4 D) {5 b/ A: u3 f9 f. Y2 e3 c- v7 {2 {8 `3 q0 Q, C6 e% K
这是我所做的:0 R6 r- n( q7 {0 H' Q2 B3 n! N

3 r5 E* L# ^: D+ Z* ?" x# V9 C  `# m导入的 web3 库和所有其他必需的模块
6 y0 x' X3 C, J0 Y: z通过指向 Ropsten Infura 节点启动 web3 提供程序% Y: R; r: I6 v! ^
添加了用于签署交易的帐户地址和私钥
! \* ?$ {4 X7 ?# O通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
' ]* D5 L8 N% J: S创建 tx 对象以添加问候语“hello all my goody people”并建立交易
: |" o8 G. A# y# W% W0 w. g使用我们的私钥签署交易并在网络上广播。1 y( z) P; T5 m7 C6 I
在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。# Y4 h* m9 z4 j8 y) _/ O
3. 从部署的智能合约中读取数据
0 V; t, h- R5 J! r! \) l# y! s6 M/ d- m
在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。
# }% y# n2 ?. ]+ |+ I& R$ Z& t

  1. 8 t2 Z% A1 q  @  X5 g8 N1 P
  2. import json- H1 |. N' L7 e% i, I0 J& T
  3. from web3 importWeb3, HTTPProvider3 d! s9 W: {7 `
  4. from web3.contract importConciseContract- L# v4 V* z6 n% L% T& I
  5. # compile your smart contract with truffle first
    3 D4 z' X+ c$ y# K
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))
    8 V5 j) l1 M% \. ]( p, X1 E% w
  7. abi = truffleFile['abi']
    ( e* y% `  O; F1 M6 F" f
  8. bytecode = truffleFile['bytecode']
    ; O. [+ ]& D1 d8 X% p# y8 z
  9. # web3.py instance
    1 f0 w; X9 y: F; q
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))% n. e: v$ t0 i3 W8 i; l- y
  11. print(w3.isConnected())6 v/ B) P0 Q# D6 t
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")# V1 G1 E' U7 }% [
  13. # Instantiate and deploy contract' [# ?" q6 J5 P2 \
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    7 B9 V, H& b$ {# o
  15. # Contract instance
    . n  C) M1 P3 K' a
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    / y5 g. ?9 I2 Q0 Z; m- r
  17. # Contract instance in concise mode9 r" ~' ^  j, e! @# K& Q
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)- r2 x' ?$ l% t
  19. # Getters + Setters for web3.eth.contract object ConciseContract, x# J( q; d; O  s
  20. #print(format(contract_instance.getGreeting()))
    % T7 I5 ?; C& `! ~, L& ?9 B
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码

* Z3 o1 \. b; `: ?' r* ]4 s* n2 q/ W# ~, P1 z8 t9 X  @
! {# V* E. R( l7 z
这是我所做的:
. j$ ?, `4 k6 }0 y$ @3 Z
- j! Z" J- G) J" W- W0 `" b$ b导入的 web3 库和所有其他必需的模块2 _0 U; a0 G! p" x/ q4 W8 \- b
通过指向 Ropsten Infura 节点启动 web3 提供程序$ E- e9 L# N; d- j
通过指向 abi 和 contract_Address 创建合约实例(来自上一步)- B% f- d* X+ `$ z- i  i5 g& C- P* J
调用 getGreeting() 方法并在控制台打印结果9 R/ f# S; p; p
结论
* f3 b" L. J. o, J  H2 M
2 K. f  m; f6 L您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。+ R+ G/ n& c% a' @! Q) E

: t. k- e! j* L5 N
4 t0 j$ V5 q7 G9 I; w! j参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程
) d  z, j5 p4 f5 D7 C' O+ E3 K- T
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13