Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
3703 1 0
什么是 DApp
( Q7 D7 K8 f( r$ M$ D7 C0 u2 ~3 Q" d- f* s4 ?) G2 r
“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 库与区块链进行交互。! u% z+ i7 _7 j+ u# i
+ U* _9 m/ |# t7 e! M
Dapps 开发包括三个简单的步骤:% c! Z. L3 Y1 ]& s# E8 [
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约* Y* L) O2 v9 \. O, V+ _
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。
8 h5 K% d" s5 z- X% k4 e! X0 E2 o: v) p4 A! C% q
安装" v1 v- t# I, s9 T0 n: O5 g
' l3 r! {4 S8 T
Python 2.7 +% E5 I& X! x3 R6 h
Node.js; O: y6 t4 E4 [- P! T$ \
Truffle. K% \) V7 g: ~6 I- @1 K; r8 Y
0 r9 a9 h% k0 Y. V- s& J3 |

  u, n' d4 j% _5 \3 N3 N8 m: Lnpm install -g truffle6 j9 x1 D4 R2 c
Pip
: u& @- p+ K6 y8 ~7 @npm i pip
3 v1 R1 Q: D: t: Zweb3.py" c+ P4 N, e* W% C& k
pip install web3: I- [5 |8 B) }- D' }
: T* P/ M# I' e8 K! [
3 F  O: }/ Z- F
Infura 项目 API
& z2 j& j3 o# k% p; B前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。% Z' N  f  C: N
" H) g- _7 U) k. @( B. V
智能合约
" O  D" m# ]) _- U' \3 A( [0 H3 V. ]8 J* ]
每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。
$ ^/ c9 h7 j* Y* L; L4 k( c; c* W6 a9 H  d* E: v/ x7 V7 q( g
  1. pragma solidity ^0.5.7;8 N! @3 u& m: C( m$ X
  2. contract greeter{* d. m+ h& q: j* R" |
  3.     string greeting;
    ( s$ T, _  y  D' C  D
  4.     function greet(string memory _greeting)public{0 Y% z; o; y( L! u1 e- H
  5.         greeting=_greeting;
    ( K: |/ _! t2 b' ?1 d
  6.     }
    , T; Z  x7 @; l! z5 \$ \9 F
  7.     function getGreeting() public view returns(string memory) {
    1 @' \: a# M$ k$ T5 R  m
  8.         return greeting;
    : q- L7 z) ]* h6 t  C2 S2 ?  F9 G
  9.     }& I' ^; m$ I: r) v
  10. }
    $ Q5 w2 N8 @- E, g2 O
复制代码

+ o+ j/ @& x  _" j: \6 B2 C1 S6 O, s, Z, I+ k' S. }' D
您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。
* H" g; u6 S" Q7 \. }
; ?6 ~3 t# F* f1. 在区块链网络上部署智能合约
' v  r3 k, U: A* h" `2 B5 W  m6 T# s8 I" i* ~4 Y! F
a) 创建项目:
1 F& h; R0 ?3 v1 o7 |5 j
+ P- v& g3 N* H! R0 K/ X) H8 p* h/ Fmkdir pythonDapp6 {8 I1 m7 L% Y/ \4 h
cd pythonDapp
1 W) v# c" V( l. ftruffle init/ Q1 ]! h9 t, S# a
# O2 c) o& v/ ~' x2 |8 k

% E. U# J- g1 c8 L+ p- f成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。5 L) j) |7 e8 Y' j

* A4 \1 y5 A: a# w3 K7 ]6 Tb) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:. z" Q6 w  a) i8 p6 S4 `, h  O4 P# h- h
; i: q( J; M. e( Z

2 U" P, x- s* _$ K1 M' m
1 {; ~& o' \/ Ptruffle compile, M% ^. ~8 ^2 d* z  R. j# h  C
(or)6 M2 G0 x8 O) ?3 s
truffle.cmd compile #(for windows only)) w3 v* X) U0 I: t
- |* p! \' v+ ^2 z0 r$ m. i
, C2 I8 T9 K8 T/ V! _+ `
上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。
4 a+ [9 c- v! X4 o( U+ S1 d  o' g* i1 Q
c) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。
7 B+ n6 [' x# @( }% u
* |" w2 x( R; Q3 [. A) z$ j
  1. import json9 q, R4 f% Q: W; ]+ B- O
  2. from web3 importWeb3, HTTPProvider
    + T2 S9 l/ V6 y) ^
  3. from web3.contract importConciseContract- X! |' E- K; z. ^" e# V
  4. # web3.py instance- M/ N, n/ |% t# a5 i% @; r
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))
    0 g7 N, \5 Y( ?* O. A
  6. print(w3.isConnected())
    ) N( K. R/ z" a+ C: x. {
  7. key="<Private Key here with 0x prefix>"8 r, V6 W& ^+ m8 ^( a# }0 \0 S, ^4 g
  8. acct = w3.eth.account.privateKeyToAccount(key)
    " u8 q* u& j4 c8 M
  9. # compile your smart contract with truffle first) j$ ], c$ p) D
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))1 f$ u5 ?4 e' ~9 i2 l+ a' v
  11. abi = truffleFile['abi']- J, ~! v0 I$ S# _8 [8 ~; v) [. L
  12. bytecode = truffleFile['bytecode']* i" j8 H. g! W8 H9 G" f; C1 ~
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi)
    $ R$ N& @; R9 e8 J& A
  14. #building transaction# L$ ]3 J/ z9 P$ l5 x' T
  15. construct_txn = contract.constructor().buildTransaction({
    7 E' o5 ?1 M) E7 D8 V* L+ r
  16. 'from': acct.address,
    3 j4 Z2 u: F! w$ U4 N0 B. u
  17. 'nonce': w3.eth.getTransactionCount(acct.address),! d* [2 j3 a/ h( l4 S, S+ o
  18. 'gas': 1728712,. |% }8 _& _! i5 A- h: @
  19. 'gasPrice': w3.toWei('21', 'gwei')})
    + Z% M# F/ Q) _! W" K) u
  20. signed = acct.signTransaction(construct_txn)
    $ ?$ L8 H2 X6 p8 S3 u
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)
    $ H: |' J! g8 R5 ^
  22. print(tx_hash.hex())
    ( N8 R/ Z1 c/ W- i& Q
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)/ V- u5 b' o; E& Q# f# J9 o4 f% m
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码
. X9 x! W8 R: }' t

! w0 C$ s, Z6 Z1 h" j+ G9 z! j: v# ^  ]  D* L! Y
这是我所做的:
/ A# M5 |9 x1 B+ O! k. l: p7 D3 ?/ e7 l+ M* o- j' c
导入的 web3 库和所有其他必需的模块0 ~4 \$ e6 e& a; w7 j, O2 r
通过指向 Ropsten Infura 节点启动 web3 提供程序- d  Q) [8 w! r+ p) A. b% L
添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。
; ]# g) t  H' E- m  r! k& \通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例+ O& T  {. j/ A7 `) E
添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。+ p1 j- ?4 @0 A
使用我们的私钥签署交易并在网络上广播。
  h# O0 e4 y  L8 N& S# X) U在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。8 F  p: A* M, I7 Y, M
2. 向部署的合约发送交易
, Q  u6 ]. s% |" z; B' G* z) _, B
2 Y) _: u# a7 x9 H! J5 _在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。/ G3 F$ G  U7 j+ M
  1. import json
    % n$ I) y+ s% {+ j( m9 m# s
  2. from web3 importWeb3, HTTPProvider
    : P3 ?9 d5 f# r/ ?& x, j# [- \5 L9 q5 w5 x
  3. from web3.contract importConciseContract
    - n6 @, _4 `  n9 P" U
  4. # compile your smart contract with truffle first* V$ d1 ?1 w) u, k6 u5 f" n+ i) H
  5. truffleFile = json.load(open('./build/contracts/greeter.json'))
    + C2 W' @. w8 X+ `7 ]
  6. abi = truffleFile['abi']
    . v6 m; q- M/ I. r9 Y# T
  7. bytecode = truffleFile['bytecode']5 K  d( T3 p& A" d. F
  8. # web3.py instance6 E, A1 C: t' ^
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify
    ) k0 X& D$ `+ B! q
  10. print(w3.isConnected())( E. N/ Y* @. M1 i3 u. W  ?
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify
    - H) }! D- u) r6 H% x
  12. key="<Private key with 0x prefix here>"#modify$ F5 u  _4 ]# \  a  B& }* E( @
  13. acct = w3.eth.account.privateKeyToAccount(key)
    7 A( q) Q$ E. u+ w
  14. account_address= acct.address
    4 [. V& e' H' i
  15. # Instantiate and deploy contract+ M" }4 i( _" V
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)* _, k# j: R/ ~2 u
  17. # Contract instance
      R( y2 i* z" R) B
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    ' X7 I/ ~0 w3 s+ Z  B
  19. # Contract instance in concise mode$ L. {" {; c! `, @& y" N
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    1 H0 ^% z) R+ [% S0 U7 G  a
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})! o' M. f# z' s5 g+ g# z
  22. #Get tx receipt to get contract address
    3 \- r! R; ~2 s' U' ]# j7 w" g
  23. signed_tx = w3.eth.account.signTransaction(tx, key)
    , I/ Z+ {& f8 c/ b
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)" j: _; e3 V4 i% f
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)! y4 }, b7 z  ^; R0 U
  26. print(hash.hex())
复制代码
5 G1 W% d9 r) X1 N
6 M5 x  T7 |2 C& Q- d; Z4 N: R0 r

" W  L4 }( n4 q) K3 Q3 @9 j' C这是我所做的:
0 f6 A/ v4 K. N
2 ], Z% I+ G: d/ O4 c* O导入的 web3 库和所有其他必需的模块; U. I( q* ]% M* u0 d9 S6 [/ Z
通过指向 Ropsten Infura 节点启动 web3 提供程序
2 \) L' y# Z$ I添加了用于签署交易的帐户地址和私钥
* M2 H& {: L7 g+ L8 y5 k2 Z, u, v( f通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例5 _2 R, o) Q0 f/ a: Z- X
创建 tx 对象以添加问候语“hello all my goody people”并建立交易
# k6 ?2 b3 q* L, g# f) T, w# m, ?: R使用我们的私钥签署交易并在网络上广播。0 @. t6 L4 X' q
在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。- n4 Z) w$ |; y6 [3 Y: I
3. 从部署的智能合约中读取数据- [6 n, D9 o8 S( X8 M

; N9 h0 E5 [- Y# t4 F% M2 O在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。
7 k0 L: V% K- b! `6 i
  1. * Z, f7 k; }1 I8 F9 e3 x
  2. import json
    0 f0 G: [9 R- t5 k8 d% d
  3. from web3 importWeb3, HTTPProvider
    4 a, f$ Q$ U* T( J+ ]2 D% u: T+ k' w
  4. from web3.contract importConciseContract) l, D: I8 m* ]- H7 z( v. u6 g
  5. # compile your smart contract with truffle first
    " \' d7 C! l% `
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))6 I4 ?9 Z. Y$ a
  7. abi = truffleFile['abi']5 J  Y7 C6 w) J
  8. bytecode = truffleFile['bytecode']2 I! z( l  g: G& X
  9. # web3.py instance+ o0 Z% I) _# F, c+ \% S
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))
    # ^' P& H! J. _1 `0 i
  11. print(w3.isConnected())
    $ g$ L0 }2 g8 G$ }
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")
    $ a3 G, \; {8 M
  13. # Instantiate and deploy contract  a/ n  [; d7 C5 E5 n# t
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    1 C- T1 U' `* K$ Z- I$ H0 C
  15. # Contract instance- D! p! D" V, X# W' G. b/ D0 l
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    - Z9 T; c6 c: o' \; `3 \' C
  17. # Contract instance in concise mode
    , c1 U6 C7 O+ v
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)# ^5 K7 S, ~% |) ^- l. j
  19. # Getters + Setters for web3.eth.contract object ConciseContract
    % o5 J9 S7 D% E; F4 E- z, U
  20. #print(format(contract_instance.getGreeting()))1 j" |" G; y/ i2 D( q4 t
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码
) D3 V4 m; T6 `7 _" s

0 Y. ^8 `! k( J. S2 h3 K! o4 E/ I. q0 L/ A0 d/ o  c
这是我所做的:! c& e- h. ?+ E7 }
0 |4 p2 C) V; s
导入的 web3 库和所有其他必需的模块( M; j( P; k8 g
通过指向 Ropsten Infura 节点启动 web3 提供程序0 V7 a4 S6 @$ B' a9 t- t
通过指向 abi 和 contract_Address 创建合约实例(来自上一步)+ k5 h- G) y, X( o; s1 O3 B
调用 getGreeting() 方法并在控制台打印结果6 n8 u9 b6 x, C. n! y% T# n
结论5 \, x& E% y" l/ r: W9 R" H# y
7 c$ e. S; Z' I$ x* l
您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。8 x3 T- P! a. Z5 P: {. m
# Q  v7 W- E5 x) V3 r2 {
3 [! d/ o; G0 w* Q
参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程
# \( v* \2 M7 b# Y6 Y5 N
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13