Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
3658 1 0
什么是 DApp
; s" U1 a+ i7 p$ j  `  y
/ ~0 y# _' L. _" y1 V5 ]“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 库与区块链进行交互。2 \8 p* d2 C3 e9 j# \

- m) ~0 T4 `8 ^' W6 n, @Dapps 开发包括三个简单的步骤:+ N, r& J$ P1 n+ v8 S7 G
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约
    ' v, ?9 o! J) P! e
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。
+ P2 B/ Q! n+ L+ t: p3 j% `7 r
! m( K6 J$ k8 s& Q! V, m' o6 g安装+ @# P$ t- w! j5 E$ R% O

0 [* s; S+ w; g. H8 ?! c6 XPython 2.7 +* m# Y  G* v. b0 Z: v; N4 h! Y- i% b
Node.js" R' o  B8 }; P( P$ H
Truffle) z" r" [" g% @7 J: n
0 _: f0 [9 k* H* x& g8 J

7 z0 m( W# G* M3 J8 u+ Knpm install -g truffle
/ E- c' v  M7 x0 FPip
0 X1 o' p6 u3 E3 s* ]0 `, Y: T/ znpm i pip
# D9 P' ~1 v, s6 J3 W8 Qweb3.py" @' g) j/ V, j" `- H: o: ]
pip install web3! a, N0 E& a7 Z' q6 T3 B& j7 N
! m& @5 t# i$ V; a( D) r

5 j7 M2 W) R* k! s. D' j* n8 FInfura 项目 API: l4 O3 @0 V, q4 _2 |# x. t% E; f
前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。
7 U: \2 O) y3 _8 v: Z! G+ R1 q9 ?& C) P7 t" _
智能合约; A9 q! h- ]# \5 R
7 Y0 x6 e9 u+ j/ r
每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。
  C/ d$ I3 G# D; A, I" U$ ?+ S" Z$ T, Q2 A' |
  1. pragma solidity ^0.5.7;2 ?5 P- @/ O% R; i
  2. contract greeter{" Z1 F8 w+ B; P# o3 H3 g1 Y
  3.     string greeting;
    - R: W: f% _8 K
  4.     function greet(string memory _greeting)public{& k# X) y7 P' T! y3 G' `8 ^! d
  5.         greeting=_greeting;( X1 j! ^2 K) h$ P7 n) d: X7 [3 g
  6.     }
    2 j/ D- x- m- X5 U# s9 G! V# @
  7.     function getGreeting() public view returns(string memory) {6 x$ ^9 u3 {" W! n' ]3 p5 r2 J
  8.         return greeting;
    * o. P/ D' a& ?4 U  u
  9.     }& g3 T3 @% O7 G, H, R
  10. }! a* `$ i5 M1 e4 q3 C
复制代码
/ y6 a( [. ^* g2 a* q* Q6 n
4 a+ {. r; |& C" B* \5 u
您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。
8 K- U( |# A" C1 K
: N' Y% ]8 ?; H2 z' k7 S: j1. 在区块链网络上部署智能合约
  u# B1 g. ?- u6 z' [3 t- n
8 {/ x; @# D3 j. H' i  ]( Q7 aa) 创建项目:* l) V* }" {; Z3 t8 [

  d& g2 U' t5 H/ w/ n6 G% C3 ?6 dmkdir pythonDapp9 P! z; [3 u; G* T  R" q$ z& ^
cd pythonDapp( D( ]* @& c+ W7 ^& {; l/ X6 ?
truffle init
8 m% z: |( J6 v9 d5 {3 P4 N3 x
8 `# ~8 x2 [  G% q# I$ u# R0 E+ Z9 H2 u  g
成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。0 I2 C) b0 v: u
, Y/ c+ C) a) Y* l2 ]8 n9 z
b) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:( s; @# X7 q: v$ J$ Z
4 ]& ^9 U. `; {
: A; s2 ^  I9 r* ?/ ?3 |
$ ^5 C' \8 t$ \) }
truffle compile
" r, ~, r# s! X% o' e  o1 r(or), \( \) Z* }! {- E2 d
truffle.cmd compile #(for windows only)9 H3 K2 U* Y! D  E% z8 q$ m

/ @" x" x" ~: ^% c# K6 a7 J% Y5 j- V$ u* l2 L
上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。( t* R- f$ a( |9 K# z9 V
* N6 I- }9 Z" a% _" T( W5 l
c) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。/ c# `0 ]3 I# H* P4 z( r6 U

9 g, Y" T& E# d6 x+ _
  1. import json
    , x! v/ ]- E& U. @
  2. from web3 importWeb3, HTTPProvider
    " m1 V4 o) p, H2 k# [$ @* k0 @# @
  3. from web3.contract importConciseContract
    3 _3 o: J+ t- e
  4. # web3.py instance
    $ l% _* I" G4 i
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))
    9 O9 B" `0 `+ _; L
  6. print(w3.isConnected())" S, }; z& m% o, k
  7. key="<Private Key here with 0x prefix>"
    ' o! M3 Q9 G1 k% z* @
  8. acct = w3.eth.account.privateKeyToAccount(key)
    $ ?* X% X7 {( Q8 K" [" ~) ~
  9. # compile your smart contract with truffle first* U9 X$ ^# e" ^; J+ o% f# P. {* ?& }
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))
    3 N" B# Y+ C) U3 V0 N* C
  11. abi = truffleFile['abi']2 Q9 K; L+ \3 h5 A% U! ?
  12. bytecode = truffleFile['bytecode']- R1 {2 i6 n" L$ K3 e
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi)
    8 p3 }+ E: m' o& l1 c, ~
  14. #building transaction
    9 h/ B# C+ O/ Z  v0 F% f) ^
  15. construct_txn = contract.constructor().buildTransaction({
    $ Y* s: _9 G1 f, j7 p( o
  16. 'from': acct.address," h- j# ~' c' `1 w" O+ e7 o
  17. 'nonce': w3.eth.getTransactionCount(acct.address),
    ' L* ^/ {0 D9 l3 ~
  18. 'gas': 1728712,  i0 I' z2 O& P$ i" y
  19. 'gasPrice': w3.toWei('21', 'gwei')})
    ' O3 z9 z  K. }6 z5 P/ w: w
  20. signed = acct.signTransaction(construct_txn)
    4 v$ o$ M4 Y1 }  Z/ j
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)
    6 Y4 d$ u! S5 |, G6 Y/ J
  22. print(tx_hash.hex())# |  m$ S# U5 S3 j# k2 l
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)2 J. O3 y/ I1 {2 P
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码

# t+ C/ N1 e( t0 r; C5 r, k+ ]& J7 D6 j& T

1 Z6 S9 R9 h! b! B5 f! D7 _这是我所做的:
  v) ?6 m' H' u+ C
, A4 \; V+ L% l& r导入的 web3 库和所有其他必需的模块
1 g1 X6 s0 S, S# W) J8 O% l+ h" X通过指向 Ropsten Infura 节点启动 web3 提供程序
$ Q7 _% H7 U1 J% r添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。
6 P  O7 @- F" O9 I7 ~5 ~通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
; {9 o8 H7 c) d4 `. m  J/ S添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。8 d8 s8 K' j5 \+ W1 K
使用我们的私钥签署交易并在网络上广播。
* E& Z& q# W5 N1 M3 _0 Q在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。
* A! e- j0 x7 C/ ]' A2. 向部署的合约发送交易
7 l  f% V  Z0 U- F! S6 _' L% _0 \' y5 ^6 U1 i' o: s" D
在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。
( e$ e8 ~# |4 z  Z
  1. import json5 M1 @( x" i3 [$ Y" D. b* ?
  2. from web3 importWeb3, HTTPProvider! D$ F, J8 R* N; }9 }; T2 Q! Z
  3. from web3.contract importConciseContract+ d% v5 {% h2 S
  4. # compile your smart contract with truffle first
    ( R  z! x5 ^( ^5 {/ L
  5. truffleFile = json.load(open('./build/contracts/greeter.json'))3 U* u. _* a9 o& d1 C
  6. abi = truffleFile['abi']
    ) n( s! m  X* @; u+ [) ~; d% g
  7. bytecode = truffleFile['bytecode']% S% e8 v; c! Q
  8. # web3.py instance
    & ]9 v; `, b4 z" d( D6 g& N
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify
    $ ]& w8 ]7 C2 X
  10. print(w3.isConnected())% e# B% G1 X- P! M4 H+ S9 W2 u$ z
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify
    / \1 L. M+ l4 i3 }# ?7 J3 W1 C
  12. key="<Private key with 0x prefix here>"#modify9 j7 g5 O2 \4 K' P0 u: j: I
  13. acct = w3.eth.account.privateKeyToAccount(key)
    9 D8 L/ R- B- \2 Z$ ~2 z
  14. account_address= acct.address; Y, R6 l6 F; }
  15. # Instantiate and deploy contract
      W* a9 X4 L% k* n$ b4 t. l
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)# c: V6 t% Y" z; W! ]# [+ g) |
  17. # Contract instance
    ; H; T7 [/ s7 }! W+ X
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    " Z. z, p5 [5 d( H  P" Z# a
  19. # Contract instance in concise mode% x6 M# c0 Z3 I  [* u
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)/ J5 p& h" B7 G+ o& B7 F. n2 P
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})8 I$ A8 i: D. D% m* M  `4 M
  22. #Get tx receipt to get contract address/ v$ E1 {) b) Q/ N; B' _& L3 n
  23. signed_tx = w3.eth.account.signTransaction(tx, key)
    3 \4 w5 S0 N  h
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)" y6 ?, p4 ?+ h7 w' e* Z2 q$ I; ^
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)
    % Q, |) u0 J* _* O
  26. print(hash.hex())
复制代码

7 J3 Y  ^& s  W- M; w4 d
5 M+ f3 s2 j$ T+ {$ m+ K# G1 V' a. c, X5 n% o$ {4 ^
这是我所做的:6 C% U8 v% O) L2 d0 c

4 t" P! K4 Q$ B0 @$ l1 s; V3 @/ Y! O' k导入的 web3 库和所有其他必需的模块% {; f4 i) q/ E3 K0 ^
通过指向 Ropsten Infura 节点启动 web3 提供程序
% \( N/ ^) a4 u) }/ \  e4 \) I+ E添加了用于签署交易的帐户地址和私钥, q4 }+ f+ _9 C1 V5 [+ y# B
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
4 K% r$ V5 l; _创建 tx 对象以添加问候语“hello all my goody people”并建立交易
  g, k6 r* c, R( _7 S- y, T$ z: J使用我们的私钥签署交易并在网络上广播。2 ^+ g7 x! N5 V$ W0 w1 r* I
在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。1 ]2 a5 ~  i6 Y. Z# U  f
3. 从部署的智能合约中读取数据9 [) ~2 x: b- j% v4 N1 f3 S- }
! ?& }# @. P( K+ _/ D0 D# {
在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。
) {# C& h1 E) y3 f# x
  1. % n- q# _2 c7 j8 d! Z; i4 g% c
  2. import json
    - D) Z9 P+ b* t( R% K; q
  3. from web3 importWeb3, HTTPProvider
    8 v9 S' i- ~# F$ U6 k$ A
  4. from web3.contract importConciseContract4 ^! D3 z* a- D
  5. # compile your smart contract with truffle first) N9 G; i1 l1 ~1 ^+ k6 B, z
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))8 k# X3 [" C" F
  7. abi = truffleFile['abi']9 p1 E# N- c( @( M4 f
  8. bytecode = truffleFile['bytecode']
    ; R' y! Y7 `4 ~! q
  9. # web3.py instance+ s6 p' ?2 L% {9 x/ @8 B9 ^/ n
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))
    ( L) @) t5 P* a$ `
  11. print(w3.isConnected()). H, e* j4 Z; ~$ u8 G7 l
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")
    : V" V; n) |* z; a- w% A
  13. # Instantiate and deploy contract
    ( Y+ i# E8 x! h0 b% I1 z7 Y/ f
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    " y- \0 h2 i; e7 E* C
  15. # Contract instance
    0 k) R5 q6 V% y" r: p
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    7 j1 i' O) H' g5 W! H% `4 n' e1 |
  17. # Contract instance in concise mode
    5 E8 v1 N0 q, `0 j
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    " w7 V# i% A% U/ X. o
  19. # Getters + Setters for web3.eth.contract object ConciseContract
    4 B3 S/ A; X* S! i
  20. #print(format(contract_instance.getGreeting()))
    ) H% e! B, t$ m
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码
0 a+ ?! J9 K9 {* m; @6 [

+ w8 X. q, i0 e4 {! v, e
& n5 h+ X2 A0 l3 t$ W, y这是我所做的:
) k  A+ X% b% |7 i+ h2 t+ O4 \" a! o6 t# t1 M2 u3 H0 F
导入的 web3 库和所有其他必需的模块- d! P0 i+ s5 Z' f1 P: o1 `3 b  ~$ Y
通过指向 Ropsten Infura 节点启动 web3 提供程序3 w4 n5 t8 y5 j8 W1 q  n) C
通过指向 abi 和 contract_Address 创建合约实例(来自上一步)
, j' b: \4 ]- o" `" k" d调用 getGreeting() 方法并在控制台打印结果' E$ |& I' y# [7 l& n
结论
1 C3 r! J! h2 i" c9 c9 |1 }" w" p
9 r6 R* i4 K4 e9 `您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。) ^' p! K$ B7 a4 {! k

# J8 V/ U" H1 H" F, ]# l8 _6 C; I0 z6 G
参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程$ p& s4 g$ W* O( ^
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13