Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
3705 1 0
什么是 DApp: E8 R+ M' G& e! B+ L

0 v# o8 [5 x' w) U0 u“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 库与区块链进行交互。
- T5 D3 b& Z" k) Y; y( f
1 ~: @) q& o6 [# w7 q' O; ^. rDapps 开发包括三个简单的步骤:
$ B4 D% l8 D) Z
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约
    3 d- Z% `* }4 G* t; p
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。/ M- M' w8 T2 _7 T5 |, |
! h$ j; i1 ?, C
安装
$ S) y# t; k* X$ E- u4 w: t' n, _) C2 k( Z+ m$ S
Python 2.7 +
) }  |, S6 q" Z+ J  bNode.js8 f' w+ g9 O8 v% i; u8 E+ f
Truffle4 a& A/ {# G! _; Q" D8 \& D

1 R" A% Z+ j  M: u2 L0 ~' t% ^+ u2 v0 c2 \( [: I; s
npm install -g truffle
8 f( W: A% Z' g; x9 V# T, L8 w/ f6 tPip
- A$ W0 Q2 H' m6 h3 {npm i pip4 C9 _: ^; J$ r5 B( E
web3.py0 l8 L- ?: }% {# V- S" s4 Y: j
pip install web3
1 q8 c" `1 t7 e% \, J" q& p* d' c6 p' q7 {2 I* g
( Q- x( _/ |/ P3 k, [0 H1 j
Infura 项目 API
# d7 {: Y& z! V7 u' w4 P前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。/ U/ i+ |% \: {; B  j

! u1 h5 H- \% X3 j$ f9 W4 D智能合约
2 a) C9 w; f5 g- C4 N1 b; J% r3 }% W1 m7 Q6 F7 k
每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。
7 h: ]& C7 u6 W0 M8 m4 g# ]7 E0 D
  1. pragma solidity ^0.5.7;
    # z* \. }  d9 H* `/ e, R1 I
  2. contract greeter{: r% h9 K2 w) b( z% @
  3.     string greeting;. x2 a5 Q% Q7 }! `- P( {
  4.     function greet(string memory _greeting)public{
    ( X6 v9 G2 _' n( p3 {+ l
  5.         greeting=_greeting;
    * V! i  g8 q% b5 s
  6.     }8 R" B6 ?/ w3 Y' u
  7.     function getGreeting() public view returns(string memory) {7 i' ?. U6 b$ C& W
  8.         return greeting;
    , Z5 u+ {8 C! I
  9.     }
      {8 L8 \" a" [3 n6 Z  R$ G. M  q
  10. }
    4 r9 {( g" W% h! m# C
复制代码

0 @9 N  w+ b' Y$ u4 `& g1 S& v) o1 J
5 [5 i: S! f( g' a6 x5 l您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。/ m7 H7 o7 R7 R- y1 r7 P3 }
. _$ M3 ]" W$ c
1. 在区块链网络上部署智能合约- Y8 P4 s2 `, r% N& v. g

5 c7 P8 L) C  O, ]a) 创建项目:5 N7 R( \: c) S  l3 q5 _

5 |* H; u9 P8 a# R4 e% |mkdir pythonDapp* R- \: b) ^; ~  n
cd pythonDapp0 T2 u* ]) ^7 p: T4 y: G
truffle init# c. T$ \$ u9 D* w+ q1 m
' `8 i7 E- C/ c; b% y
( G/ b3 ]7 O- s" g# r$ C
成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。
/ s3 X& f( Q5 A, S2 `( S8 |2 J' F( S4 R4 n( r
b) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:
- l+ s; f5 x  x% g7 G! S; G  T% F# E5 T  P. s+ m5 }9 _% W/ o
5 X& f4 J# A! m
: f/ j. Y" V. g/ L
truffle compile
; }, \- {( H; s& z, j. K* b2 v(or)
) V' g+ E7 `8 ?1 _) vtruffle.cmd compile #(for windows only)
; q, Y0 X- J  S7 ]" O4 C/ \
& \' ?# G8 t$ A: T9 I( J: Q* O8 b7 d5 J
上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。
3 N+ r+ U$ K  W# S4 ^/ d6 o; G! [2 h4 g! F" Q% V& A) F: D/ _  n# j
c) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。4 P" j' }7 \6 v- w  [9 a/ {5 u$ A
0 Z' P) y  o2 K& V
  1. import json: g8 w; n3 O) p5 _
  2. from web3 importWeb3, HTTPProvider4 g* B4 ^  o$ m' }" F; w" V
  3. from web3.contract importConciseContract
    ' w- Q* a. Z( S$ ?; {
  4. # web3.py instance
    - j  }) L7 j" r6 n" z
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))) R! H, W# c! K0 }0 t! O: w8 M: R
  6. print(w3.isConnected())  P( p/ z7 Z* d6 Y! l) \
  7. key="<Private Key here with 0x prefix>"
    ; |! z& z) ?, [; V& k% i
  8. acct = w3.eth.account.privateKeyToAccount(key)
    6 a; ]2 r* \: i" P1 J) u3 _
  9. # compile your smart contract with truffle first
    3 ?; ^' m8 e/ M& H) P6 I# W  ]
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))
    * m5 n2 Z( H( S; T# f
  11. abi = truffleFile['abi']  }) e$ s, |) i: d; {
  12. bytecode = truffleFile['bytecode']: v; |8 u: u) ]1 j
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi)# u/ w8 Z4 E" M4 A. X; R
  14. #building transaction
    ' e6 x2 G0 Q! u* y
  15. construct_txn = contract.constructor().buildTransaction({
    " m, D/ W1 v) `( q/ l' [
  16. 'from': acct.address,$ U) h, W2 Z0 S# B6 y
  17. 'nonce': w3.eth.getTransactionCount(acct.address)," T. F$ k/ V9 t0 ^# v, Y$ S" Q
  18. 'gas': 1728712,
    * w: d  G/ k8 f# }& [" Y" w5 G
  19. 'gasPrice': w3.toWei('21', 'gwei')})
    ) L/ W  i+ k/ V" |, q% @6 ]5 s
  20. signed = acct.signTransaction(construct_txn)
    4 G) p% d3 T% w9 A+ z
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction). U7 w1 w6 R9 z$ l2 y  R) Y
  22. print(tx_hash.hex())
    # P* k" L2 r4 M. d' z4 q
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
    % m5 W+ P6 M8 }9 W) k0 z" h) W
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码

: g3 G" J( p8 M
3 _4 b% Z2 Y& r0 F" K3 s- y7 Q8 y. @5 H4 u/ J
这是我所做的:
& G$ M+ a8 f9 t* M& n4 }8 a/ B  u
导入的 web3 库和所有其他必需的模块
0 k* |: @! ^% f  x  z9 @6 ]通过指向 Ropsten Infura 节点启动 web3 提供程序
1 ?( f: S! T5 ]# K  e$ `添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。! J4 v9 ~( w2 |/ p( F5 [) ]3 q
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
. Y- p# u0 [! B9 t添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。
6 i1 d0 c/ r; F+ J' F8 L使用我们的私钥签署交易并在网络上广播。8 e2 N" L& ]* J& j% S
在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。
2 N3 U; V# _; H2 G! h2. 向部署的合约发送交易7 m/ n6 V5 V  t, V" \

+ E- l' q/ o) Y5 s% d$ N/ ?  G在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。
/ q# R% ^, S& Q( v! d/ q) v8 _
  1. import json
      Z0 I  J3 D$ U* [6 u2 [
  2. from web3 importWeb3, HTTPProvider; @5 v5 Q5 W7 u1 N  p
  3. from web3.contract importConciseContract
    : ^5 g7 K* j3 `$ I  B7 ]
  4. # compile your smart contract with truffle first5 ^3 O( j  H' q
  5. truffleFile = json.load(open('./build/contracts/greeter.json'))' L+ W0 k; i  `9 w+ _3 p  t
  6. abi = truffleFile['abi']# _7 |, [, t1 ^4 }: H5 ~
  7. bytecode = truffleFile['bytecode']# i. W3 _" l; n" @6 l& S: [; H
  8. # web3.py instance) U- s" W+ P3 y+ p1 n' F
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify1 u0 \% P- G, h, I3 e* @
  10. print(w3.isConnected())+ P  k* W* S! K1 x3 E0 G
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify
    7 `4 @6 U% q# {+ ~$ N* P* ~) S
  12. key="<Private key with 0x prefix here>"#modify8 m2 r  j0 j! S& w/ s2 `/ r% [
  13. acct = w3.eth.account.privateKeyToAccount(key)$ w9 c/ g# Q5 u2 }% I6 w" z
  14. account_address= acct.address8 {& \1 r! g* o( i
  15. # Instantiate and deploy contract) y7 W% ~5 P/ m+ a9 _/ `, D# F- V4 }9 J* r
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    / `8 \' ^3 l) @$ m8 |; o; K
  17. # Contract instance
    - H" @$ Q' h1 T' J
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)0 x% b% V! S# l
  19. # Contract instance in concise mode
    * P4 K" u+ z' a  w" i5 I
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    5 V% X( p" M% i! ~: K
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})
    ; k) {6 Q  u+ }/ u4 i# F& f* E: t
  22. #Get tx receipt to get contract address
    " `9 F) I5 y7 D$ x
  23. signed_tx = w3.eth.account.signTransaction(tx, key)1 C1 H/ i1 @  {1 J; z% B8 Y3 e
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)9 g* I6 e/ o( t3 }9 H3 C2 u; X
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)5 y, I0 |* \! O. ], J, T2 }
  26. print(hash.hex())
复制代码

) t/ h1 ^  H; Y1 E5 u1 O; q* F/ @6 G
! S/ C9 v  A1 x  E
这是我所做的:4 s9 I" T# }7 T7 d
9 H! U# I0 j) G* V8 `
导入的 web3 库和所有其他必需的模块
( J8 B: z& B& Z% f: F通过指向 Ropsten Infura 节点启动 web3 提供程序  P" |3 I& f. M' f$ e1 S
添加了用于签署交易的帐户地址和私钥
$ }* E' w; }4 W' \0 S4 w1 R# q+ f: X通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例) X# k% s4 I$ r* d- S' {$ W, d- F
创建 tx 对象以添加问候语“hello all my goody people”并建立交易5 S; J# O* _: m8 w" _
使用我们的私钥签署交易并在网络上广播。( I% M* x% x7 l
在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。
7 J; D0 }+ U! G$ x3. 从部署的智能合约中读取数据! ?: h- Z) E4 d, w' ~, v

$ C: k7 S. s5 ^- N) H在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。" H' Q' @$ Y) u+ z7 m$ Q

  1. * f" D5 H. d* o: _- Y+ S. n/ g/ x
  2. import json* N4 `9 e: l. c# z' m: _5 s
  3. from web3 importWeb3, HTTPProvider$ ]4 B" j2 ~+ a8 [: A! k2 a7 f
  4. from web3.contract importConciseContract0 G* \7 {0 n$ u
  5. # compile your smart contract with truffle first
    3 z* n1 F( c' Z, L% o+ F
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))7 M$ o3 k; C4 w, r. V3 b
  7. abi = truffleFile['abi']9 }0 @7 e0 C: F* P2 g
  8. bytecode = truffleFile['bytecode']2 E$ {0 k( y5 ~/ A* B
  9. # web3.py instance' X' J  A+ M! d7 ?$ x4 `
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))" Z- J  F5 G$ Q3 k: C2 i% i
  11. print(w3.isConnected())
    ( }% O0 Y" B! ~: u6 O, H1 G
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>"): G9 J" o; U2 ~
  13. # Instantiate and deploy contract% D2 b. u! g( [' M1 w/ o
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
      s- M6 m; v6 M4 v  i' ]
  15. # Contract instance
    * c' W! t  N& ?9 e
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    4 O+ v  w: f7 z6 j; ^' ?$ M6 Z+ a
  17. # Contract instance in concise mode/ Z( R$ t4 y& d, o/ v7 X
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)* l" h! i& A1 P, O3 g# p9 X$ l
  19. # Getters + Setters for web3.eth.contract object ConciseContract
    " {9 t, [: P& J' |7 U- w
  20. #print(format(contract_instance.getGreeting()))! ~, o6 R1 [" q! {, e! b0 I1 ?  Z; _
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码
& j3 J( @, X1 C# T

; Z- a  {; ^7 h) _" y8 R
/ Z( X- D( F# m2 ?" i  @' P这是我所做的:
/ J* X. _: v& ~8 e5 R. {( v' G
导入的 web3 库和所有其他必需的模块
, J7 I9 c5 W  \3 a& r8 [: E通过指向 Ropsten Infura 节点启动 web3 提供程序+ Q" Y' Z. n7 a3 g$ K: l
通过指向 abi 和 contract_Address 创建合约实例(来自上一步)0 r) T& {0 H" Y# o! L
调用 getGreeting() 方法并在控制台打印结果
8 Q$ O$ A" d: x! d结论
" e; Q2 b: Z' S  _2 y$ ^/ k, y7 A5 u, n. ?2 _0 j6 X4 y
您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。
4 r6 L4 A( `0 p/ w. P1 F% e+ o' i$ t- t" G$ F

5 M8 e0 C7 u0 h1 \参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程! J8 o7 @# V' [8 X1 i
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13