Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
3681 1 0
什么是 DApp7 v/ B  e5 w' w9 d4 W1 k
- l: N5 W9 p7 B+ C
“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 库与区块链进行交互。
! s1 q4 C% W$ n$ ~3 T. Q3 t
+ K! e' Y  V6 c0 e8 r  ^Dapps 开发包括三个简单的步骤:, I; Q! q% p! ~5 Y" u
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约
    * v) G+ |' h3 s$ T( v
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。6 e/ o# a( l/ I7 e9 c4 C- v

+ d7 t0 v6 b, B1 j" L( `! o安装8 p( q$ y0 z0 l

* g% q) n* q4 x7 D+ ?Python 2.7 +
) S! e: H+ [8 n# y% |; NNode.js3 @2 j: R# ~0 l+ F, f* y$ h
Truffle
3 e! F+ n6 v. |/ J6 Y, T
3 }0 h0 m2 S: b2 l2 J. H: T2 j) H' _8 S
npm install -g truffle
+ z0 X7 N% t' U% |Pip
' e+ Q% J( g+ Q3 Pnpm i pip
( ]2 x1 D! w; `' q0 Y$ Q3 `3 A) J' oweb3.py
+ }+ t' ~5 A# z6 z6 c! Xpip install web3
4 K' u- {* b$ m, I- @! k2 w! w1 \' a* h7 v1 w( z6 q& @, ?

7 w6 V: Q4 m. ]5 o0 |Infura 项目 API
2 t* B: ]& Q6 j6 P前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。5 u, A5 r# u# h/ V! |

/ q. Q) O% z% j3 ~' t! s  P! y智能合约
, [* _3 `* c4 g" Y! v
9 G* Y, }8 }" Z$ a# o每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。
- _& v2 |* h# d" u8 L: b. O- }$ x7 A) K7 b$ t
  1. pragma solidity ^0.5.7;; O9 i% t- ]: C8 @
  2. contract greeter{
    8 X  e; w. f% V
  3.     string greeting;
    3 d& w. t9 F7 u! C/ j
  4.     function greet(string memory _greeting)public{6 w7 {, v7 H1 v3 a
  5.         greeting=_greeting;5 X2 g% E, C+ |* M6 @
  6.     }5 v# z8 S8 u  b! L; i
  7.     function getGreeting() public view returns(string memory) {* W& M2 W8 V  m$ z$ E; j
  8.         return greeting;9 ]" ^* @& o3 a" ~
  9.     }+ T; J8 D' B$ I* ^
  10. }2 k: i, O9 g. A( J/ u$ _+ W
复制代码
5 B8 _3 |: v6 N* p

- G  E3 i% {) m您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。
" k# X( K/ Y3 L1 i3 {5 a
. e9 U: R& L9 Z1. 在区块链网络上部署智能合约: B5 d& D1 X# J; i$ J- }
% H* u4 g4 ]3 K% j: a
a) 创建项目:
, N- p5 O. |; {$ u* `0 w8 n; B1 C/ o% `7 U
mkdir pythonDapp
" l% y3 L& ]- c& w, Q) fcd pythonDapp
- M5 y0 z' f6 ctruffle init  h: Q# T. O# ?( A/ R
8 w" L; I; ^  c

2 E. L$ _8 a/ Y/ x' x$ l; E成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。
* f7 z( p6 R# z! P3 n2 c+ m. q% N& F2 u6 ^* a9 g
b) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:0 H1 K( L& E* p8 Y
; Q' E2 E3 T' P# l+ f0 h
1 i8 y% O- k( @# a. A; G

- r( z; B4 {5 ?5 n  {truffle compile& B7 S9 t  }9 a
(or)& b" K) H) ?$ G$ P6 X) _1 q
truffle.cmd compile #(for windows only)
# q$ S9 k7 Z' W" }% @; W  a1 G& W  F' a# G/ s

5 ^9 @$ y1 P" u2 c( J: T上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。* ~# l" O. h- b2 v, Z, {
0 n4 [" g$ e" K# I' M0 }
c) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。% w$ G/ `" m' {/ R( N4 V: z: L
3 i( R5 ~! V* I2 g6 S* s+ I( J% i
  1. import json
    ' r# ]/ m. `8 r$ i2 j
  2. from web3 importWeb3, HTTPProvider
    $ d( ~# Q) f8 h; v3 _* L8 P7 m2 d
  3. from web3.contract importConciseContract
    % W0 @; C& W. S+ q1 A
  4. # web3.py instance5 J( d% ?& Z1 I6 @, T
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))! O8 ^: X) P# e
  6. print(w3.isConnected())8 m( n, V+ M0 e
  7. key="<Private Key here with 0x prefix>"
    # C: e8 _- O' [' Z7 y: z: b. w
  8. acct = w3.eth.account.privateKeyToAccount(key)
    ! I# E3 |! f8 }; E! }$ K
  9. # compile your smart contract with truffle first
    * `, o# G- E. W6 W  N+ D2 V/ t
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))
    / }/ M  H. r% i4 }2 q9 M- H( w1 U
  11. abi = truffleFile['abi']' W" ~+ x9 |, s9 }% [
  12. bytecode = truffleFile['bytecode']
    # Z/ e* q5 m% O" d- W. c* m
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi)8 F" M" t6 T; F
  14. #building transaction
    4 p5 }# Y4 G! X; @& h
  15. construct_txn = contract.constructor().buildTransaction({, W, k9 R- f( I, Q7 }. _
  16. 'from': acct.address,
    : C* O# f9 i, W* \: r9 X' K& V. p
  17. 'nonce': w3.eth.getTransactionCount(acct.address),, {  ^1 A2 J" e7 t% m
  18. 'gas': 1728712,2 O) \* s. I! K
  19. 'gasPrice': w3.toWei('21', 'gwei')})! W; b+ l8 o0 F+ ^6 n
  20. signed = acct.signTransaction(construct_txn)4 S7 p3 k( F/ _0 q& \$ @; x
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction): Q1 k) `9 c: b% L* i
  22. print(tx_hash.hex())" u+ J* w1 i) a8 p) T; b, `
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
    , {4 X" i% \8 C' R$ R. T1 v
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码
5 ~0 h, e( x  K3 }6 f0 ~: H" z
8 {1 {+ l1 D  X- }2 X  d. s
/ a) V7 E1 \" J, p& i/ W7 O" g
这是我所做的:4 D3 @7 ~5 j! r. j
- }& U1 a& \2 g7 n: D8 Z
导入的 web3 库和所有其他必需的模块! D0 }2 {; U2 y0 O0 l  b( ?1 l0 V+ T
通过指向 Ropsten Infura 节点启动 web3 提供程序/ S; L( V* \4 e: B0 _, t3 u
添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。8 T- C7 v/ F, ^3 D; b
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
! R3 ^/ }3 a& i, A) d6 I3 W% G添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。
5 K3 q9 k2 y4 O- A# ?2 i6 x3 z6 N使用我们的私钥签署交易并在网络上广播。
* J! g7 P8 h# P6 {在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。
" E% T4 l& i+ C  C8 E; m2. 向部署的合约发送交易9 A( v  C( i0 V3 h

; D0 e3 |& ^" y0 U3 d在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。
5 _! H8 g3 u% ~
  1. import json
    6 S: w! C# `: C7 ^3 ?
  2. from web3 importWeb3, HTTPProvider
    & ?: x: p  G7 g: o7 T' W- n
  3. from web3.contract importConciseContract8 J) A# u. U3 H
  4. # compile your smart contract with truffle first, {4 e- {- s: ^! n' i& K% q
  5. truffleFile = json.load(open('./build/contracts/greeter.json')), N) W7 u% l; n3 z
  6. abi = truffleFile['abi']% Q4 V2 g3 ]8 l- q
  7. bytecode = truffleFile['bytecode']: H) i& J4 {, Y) l
  8. # web3.py instance
    , l5 q$ u" j* E/ H# S
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify
    " E  K' s2 n' A% G/ ]
  10. print(w3.isConnected())
    8 }! Y4 V6 l+ W; f. v2 {, S
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify' g* t+ d7 E) M2 w
  12. key="<Private key with 0x prefix here>"#modify& |2 Q& X6 Y! o1 R; H3 ]
  13. acct = w3.eth.account.privateKeyToAccount(key)
    * \0 m: G4 C$ j/ f$ |, z
  14. account_address= acct.address
    4 k( h' t. I" Z) h' n* ~6 T
  15. # Instantiate and deploy contract
    0 T6 y0 z9 ^) D% t+ E
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)5 p5 x0 r1 w) K, t
  17. # Contract instance8 D" ]; L2 P3 N) V/ j2 B* a
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)) v  x' P) y& f7 G* h; U0 K% E4 M
  19. # Contract instance in concise mode% n6 L5 R8 x0 q9 f" K2 t7 T6 I
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)5 {, l3 L7 Y8 x) G7 E. g# n5 {
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})
    7 ]8 X* X$ H% M9 U
  22. #Get tx receipt to get contract address" H' e# C$ [  q- k2 r
  23. signed_tx = w3.eth.account.signTransaction(tx, key)
    , C; ~. s1 ~  f  b
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
    $ k- o! ~0 ~( Q- |2 C/ U$ i
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)
    5 o7 p7 B2 y7 E0 y
  26. print(hash.hex())
复制代码
5 K  ~  w) H- f% R

1 I# B- b: t2 d) b  }- Z# j# p& z+ W; `: k. D  B5 F/ f4 }- Y
这是我所做的:
) k3 u. {2 j7 k! H2 X$ n9 I# F- A0 T. X6 O
导入的 web3 库和所有其他必需的模块! o6 T! s7 u1 z* o
通过指向 Ropsten Infura 节点启动 web3 提供程序3 s1 @9 z# F6 I. \" I+ P! P
添加了用于签署交易的帐户地址和私钥6 k, h, q; c1 w1 l
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
. Q8 m5 q2 H/ w- K' D创建 tx 对象以添加问候语“hello all my goody people”并建立交易6 I% a2 N' S7 h+ v) Z" }
使用我们的私钥签署交易并在网络上广播。
  u; x* i# E" k/ Q在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。
3 T" f5 \; A- w: p) x: l+ h7 m/ Z3. 从部署的智能合约中读取数据
/ d& z: J6 S9 z+ ?; E5 \- n9 ^& c2 j, D8 W# ~+ z' [' ^
在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。
! n6 m/ t+ {3 B  V
  1. & j: e9 r& c6 @
  2. import json
    ' _, q' o# h% `% q/ B# |9 v: J
  3. from web3 importWeb3, HTTPProvider2 d" y' A  S5 i
  4. from web3.contract importConciseContract
    ; v0 x0 Z* o6 {4 G( @( n# Q# L
  5. # compile your smart contract with truffle first" q/ _0 _$ b5 W" o( N* n
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))
    $ F) O2 i9 ?7 J! B- g7 g7 {! i
  7. abi = truffleFile['abi']
    ( \( J* b7 x9 S8 \; E5 f" E
  8. bytecode = truffleFile['bytecode']( d+ c9 ~" [9 l
  9. # web3.py instance
    ' k9 |, f: r2 ?
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>")): ~* s/ ?7 J; E! ~' D$ `
  11. print(w3.isConnected()): V8 x* P/ _  x3 C1 j" f0 K
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")
    : I, I/ J) O3 K# B1 S8 w
  13. # Instantiate and deploy contract
    : j0 T9 {4 @/ d' A! E
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    ! d% d+ G9 D7 h8 @, c. Z
  15. # Contract instance( K& ?2 T: G1 Y# n* d- m
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    / B& Z) g4 g/ U/ o$ _
  17. # Contract instance in concise mode
    ' `$ p/ g& A: Q, c3 z
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)$ P- ?% T/ p# k0 r; i
  19. # Getters + Setters for web3.eth.contract object ConciseContract
    6 [- ]- d4 n! I! w' U* p! `
  20. #print(format(contract_instance.getGreeting()))
    4 a! U! W( G( x+ F. r
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码

4 M" ~7 Q$ E) }  o- A4 W, G/ w$ Q" y  K0 Z- v% i
. A1 p+ \; R5 p$ ~: [3 g
这是我所做的:1 |8 W; g( `( K

5 M* I* B. U- _8 h; H导入的 web3 库和所有其他必需的模块7 _0 Y" P5 E7 P& n6 C, B3 ^% g
通过指向 Ropsten Infura 节点启动 web3 提供程序8 s) A: ^4 i( w) D  ]9 ]/ t
通过指向 abi 和 contract_Address 创建合约实例(来自上一步)
* d9 O" q" G; |; J1 e% K调用 getGreeting() 方法并在控制台打印结果* S& T- Z# e' y  d0 h
结论; {& @/ L5 |4 }3 y. `

( h% H# `, \- h6 x$ U$ P您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。% }- G+ K8 _7 ~3 k8 U0 E  N
3 S4 t2 [8 d) f; m' v( ~, F, c

: G+ C* `. d. Y" w* ?& x* v4 w3 b参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程
* }7 K: x4 K# A* Q3 J5 ?
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13