Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
3706 1 0
什么是 DApp
6 N' @$ x/ q  n
! E) @3 w/ d7 D5 o“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 库与区块链进行交互。
3 o( G% u0 h: n3 _. Q
8 U4 ?  W3 I$ u- FDapps 开发包括三个简单的步骤:+ ~' [% ?" a7 _
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约, \; S! G" S* e. B. ^, O
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。7 }" t" T7 U. X' J

4 U, X( j3 T0 O安装0 b9 O  F7 |: \- D
  t. D% ?4 m' U5 I
Python 2.7 +$ x+ _% f/ w6 C$ v: \" l
Node.js1 U2 [) a/ ~7 c* [- w* c6 y
Truffle4 q# [, j; e5 j& @

3 \; I+ M. t3 B+ i1 _$ h7 L$ K, q3 R. Q' f: m
npm install -g truffle
6 C( u7 d& H4 |2 W6 qPip
9 ]7 P: n: j" X9 K* ~+ Anpm i pip
: L  p6 f- o7 z6 w: D$ T% Vweb3.py
9 _! B" Y2 G2 X$ T) n( p4 U) ^pip install web3
$ s) ~4 ?8 ?$ Q- b) Q9 p2 r! |; R6 c: x! t: g

, h% K$ r9 `% K# E! [Infura 项目 API
9 ^0 a  N0 s( a0 t1 {前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。
$ {! v2 N. P8 C3 x+ P7 g$ S9 `" s% z, O$ g9 e
智能合约0 j6 e3 `% A% G5 M" k
+ h$ g# u4 O5 X! D( w9 F
每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。! }1 z( z/ c+ v4 ]. i6 C$ ~

1 w+ f% n5 N; ]8 j
  1. pragma solidity ^0.5.7;
    1 y/ U8 C$ F, C6 @, C* v
  2. contract greeter{
      \* T' R' T, S6 J) {5 ]
  3.     string greeting;
    5 v3 a9 R1 G6 d. ?. x; r  h) V- s* E
  4.     function greet(string memory _greeting)public{2 S! `$ N' A4 B% }: d" {( ]
  5.         greeting=_greeting;
    3 d, ?- K8 O! E9 `8 I( H# {
  6.     }
    $ ?2 l' H! ?% C% ^# c" B! q" C
  7.     function getGreeting() public view returns(string memory) {. n$ Y7 s; g* I0 y& {+ X$ j" j5 |
  8.         return greeting;8 B/ e( x7 V9 o
  9.     }3 Z# A9 w6 X% J/ W* m0 l" {3 u. F
  10. }+ F2 C3 V3 R+ d0 v$ j, }- g
复制代码

, A; h9 ^" x4 z4 m. R* b6 s2 N$ B4 [6 Y6 f/ y4 h  T+ D
您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。2 n2 S4 r: |  j# F" P0 w# u! z1 j

$ K+ }' |( Q0 N/ S1. 在区块链网络上部署智能合约- f5 k: x1 T) p% Q: @

: n' \# S, [% }  U8 R1 fa) 创建项目:
0 ]2 `& \8 C- i, p  P) ^. D: A: d1 P
mkdir pythonDapp
- e# x+ z% Z1 F- ~+ d- k* {cd pythonDapp' n6 M) B' z. b6 i
truffle init4 D% }' Q" c. f3 f
3 S1 J2 P  M7 |+ r! s! |
6 S! K! J( i0 W- ^4 [
成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。" U' ^! v; W# f

8 n8 y5 |6 ]! Lb) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:
2 z. }) P, h3 |+ z# {# d! Q
# S' W: J  i5 e3 Q4 I/ C( z/ m* w; Y& s

: ], N1 g3 L7 L" Y- ?7 i4 H, etruffle compile
" `! Q% M2 F: s8 }" P(or)' [+ c7 u, g# V& Y6 L  @& [
truffle.cmd compile #(for windows only)
! E; W; X2 \! u* h- T( A( H
( \" M7 j& J5 s( \$ R% V* U) F* s; ?/ ~
上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。+ t) K" O* ?0 [9 b
3 s! f) k) u7 B# \  y& q
c) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。( B( n# P; c& w! _! ~, a

  |, N) B8 O( m
  1. import json
    7 G4 M' e) B- g5 t$ y
  2. from web3 importWeb3, HTTPProvider
    7 ?6 D' C& T  I! b* C9 r( \
  3. from web3.contract importConciseContract
    ) ^* f# }8 H  e' v
  4. # web3.py instance
      ]- T; d: f6 c4 t4 e( N
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))0 B; Y& J/ v: C' l2 v
  6. print(w3.isConnected())
    . w" z" O( @" M8 Q" w( I; }0 Q
  7. key="<Private Key here with 0x prefix>"
    3 y! I' t/ Q# ]  s4 }' m
  8. acct = w3.eth.account.privateKeyToAccount(key)3 W1 `, Z! x9 p$ O
  9. # compile your smart contract with truffle first& c  o6 T3 {0 S, H8 e! d* I
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))6 a* f1 \3 _' [' F# ?! n( d
  11. abi = truffleFile['abi']
    ! `3 ?8 @/ e5 S1 L
  12. bytecode = truffleFile['bytecode']
    $ d! s9 [/ x' u7 G
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi): n1 O, H& o* E: M$ l5 N. {" }& q
  14. #building transaction
    6 F3 D8 r# E- _5 X2 Y# w4 ^( S
  15. construct_txn = contract.constructor().buildTransaction({
    5 A) N7 c( F- o. S
  16. 'from': acct.address,9 y4 U- C+ K- z3 p/ c& W/ w
  17. 'nonce': w3.eth.getTransactionCount(acct.address),6 X" g! r( O! X2 O3 \
  18. 'gas': 1728712,
    ' @8 p8 m, R; i# V: E3 F8 j7 R( q- `
  19. 'gasPrice': w3.toWei('21', 'gwei')})
    ' L# W/ i) W9 I- [( w! I. U3 ^
  20. signed = acct.signTransaction(construct_txn)% t5 A, x! k. |" l: j
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)
    ; t4 @3 g, N7 X5 u/ D
  22. print(tx_hash.hex())
    9 }, b4 X, x2 |3 L/ |+ E
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
    6 I9 o& Z' P  ^, S  `5 u
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码
4 A( j4 W) k4 v
" j$ h8 ?/ j8 ?

9 _9 D) P& h2 i3 Y2 v这是我所做的:
0 y' T. F+ G, i$ d* y7 q+ A) s2 ?; ]6 ~! j. F- L
导入的 web3 库和所有其他必需的模块
! X  ]( E$ C6 a! Q通过指向 Ropsten Infura 节点启动 web3 提供程序
- M4 x- o8 B0 T8 R添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。
5 Q- X: m+ @) P& @) F' ?& l通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
( c' X9 Z3 g$ B% ~8 e2 @1 e4 J5 l添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。( l5 x6 d' \5 k. B9 t* }) V
使用我们的私钥签署交易并在网络上广播。3 c! a) e7 H6 W5 m# q9 ~
在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。
  Z* O3 M5 S+ s, p# b9 j2. 向部署的合约发送交易
9 Q( {5 Q/ P) ^% t7 b/ [8 y' T9 [. b8 m6 v$ @; Q) [
在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。
* @4 t; m+ `! l  ?4 f( Y' D
  1. import json7 M, k, {! G- J; L) Q
  2. from web3 importWeb3, HTTPProvider
    ; M6 {5 a1 k' l: B( @# }
  3. from web3.contract importConciseContract
    / Z4 v* k" K' a' H$ X1 e
  4. # compile your smart contract with truffle first2 \& F! u1 I  V2 T3 ]7 G; I# H
  5. truffleFile = json.load(open('./build/contracts/greeter.json'))
    % Q  Z; v; e- R( U! E5 k; S
  6. abi = truffleFile['abi']
    5 P3 W# e' q$ S3 W! m) l, ?
  7. bytecode = truffleFile['bytecode']
    8 s3 [  S* @0 n( E% L3 N
  8. # web3.py instance" V+ @" E  g* f9 F
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify
    % y1 a3 Y. b' D: o* R
  10. print(w3.isConnected())2 W: M5 o. E1 {0 t; }, V$ @2 T
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify# e8 _$ h8 j6 @/ e, i
  12. key="<Private key with 0x prefix here>"#modify+ Y- P: a( y9 u4 u- J
  13. acct = w3.eth.account.privateKeyToAccount(key)
    ( D6 f, S5 f& s0 H
  14. account_address= acct.address2 G8 l* u/ p( b
  15. # Instantiate and deploy contract
    : k  x# ~, H- D, P
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)( A! {& h" |0 i* P
  17. # Contract instance$ l( ^2 j' i7 K- \, M  P: d
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)- n! m" R+ B9 d( ^, C+ f
  19. # Contract instance in concise mode4 v! c0 }+ x: N9 d. v
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)  t( q! J7 u! c/ v% O' U
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})  ~5 |9 w( _  P. y* `8 Y! D
  22. #Get tx receipt to get contract address$ a6 X" j2 h& O5 H! s1 l3 ?6 J
  23. signed_tx = w3.eth.account.signTransaction(tx, key)* A0 {+ Y; Y' r5 k8 Z; L0 s/ n
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)( c8 o! M. A0 V7 N9 e/ s. l2 u
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)
    . k( G" V$ [7 d- _- p+ @
  26. print(hash.hex())
复制代码

8 p- o) B8 R, c8 y& t* T9 N; N, u1 S; S

" p% r+ R! u0 t+ m2 T: K2 m这是我所做的:
3 J1 j  m& j4 n$ g- `1 V  G/ p' i! @  O- D  J6 B' b
导入的 web3 库和所有其他必需的模块$ k# r0 \. Q! s. W, Q; f, M
通过指向 Ropsten Infura 节点启动 web3 提供程序- H. k4 S4 Z2 e3 R9 u( U, ]
添加了用于签署交易的帐户地址和私钥
- c# |8 o' V" u- @6 W通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
/ j7 q5 y4 j# t  f创建 tx 对象以添加问候语“hello all my goody people”并建立交易7 u$ m+ V$ x7 c
使用我们的私钥签署交易并在网络上广播。
( {& s. Z) C5 B+ L# d! \+ v/ W在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。
! i8 N6 q; l: U' i# a3. 从部署的智能合约中读取数据( E  w( f  m- D' r
! l7 I) L0 Z# x! |' X
在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。, U& y, r1 v$ S& y( h' i  k, M
  1. 9 p' j+ H% V4 c& }% n% \+ j# P
  2. import json. W; @" N( K2 q1 Y% r2 _: q8 R5 X: N
  3. from web3 importWeb3, HTTPProvider$ l* R7 k) F+ T, g
  4. from web3.contract importConciseContract
    9 s  I. m- i2 p. H# Q; D
  5. # compile your smart contract with truffle first; H3 X1 ~- H: j  N% H9 E- p
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))4 s# Y& d- G! H' f5 k' @& ]
  7. abi = truffleFile['abi']
    4 d9 w8 a+ m/ A  f6 K& [; Z
  8. bytecode = truffleFile['bytecode']8 v0 H6 ~: `; _( j* T
  9. # web3.py instance6 t' w5 n8 g! U& u- e3 J# c- w
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))5 j9 Q/ X  ~+ R% P4 l1 X2 L( d& W8 n
  11. print(w3.isConnected())# O2 Y7 e) C' J! y6 m* j
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")6 N, b3 ^" Q- [
  13. # Instantiate and deploy contract: m6 n9 b$ f. ]" }0 x& K* x  i
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    ( G; Y" w% @; H8 s9 b0 T2 _
  15. # Contract instance, R7 |" R/ \+ _. B# b9 v1 G
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)6 Q" Z! Z. h' q
  17. # Contract instance in concise mode
    $ Y$ ^$ W1 H/ I/ N/ Q
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)+ b/ G( Z( @1 s) w* x5 P+ W5 l; O
  19. # Getters + Setters for web3.eth.contract object ConciseContract/ h- t1 f* r( k4 C
  20. #print(format(contract_instance.getGreeting())), J7 v( W! j" v4 v/ C8 D# V
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码

4 ^( j9 J; P" p! D. y$ l: \; x* r+ o0 ^: }. V
4 l3 R# |2 j1 F
这是我所做的:
7 a7 H! D6 O. w* w$ @8 N
; t3 [9 H1 D7 W7 u& H导入的 web3 库和所有其他必需的模块5 [* T; o& q0 g- K
通过指向 Ropsten Infura 节点启动 web3 提供程序; m+ j+ B( K, Y8 W( d
通过指向 abi 和 contract_Address 创建合约实例(来自上一步)
* E' ^$ t- \" Y* j% v调用 getGreeting() 方法并在控制台打印结果: K1 B7 C3 H4 V$ C
结论
1 A+ i! K; R7 \; d$ }" W. b' d
  n/ \% ?. R6 ~2 E您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。
( Q8 `  `) T- b! G8 u/ W* y* y; {" a, }$ a! |6 t
8 W2 G8 A, S- r
参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程# S! N8 ?3 j" R
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13