Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
3023 1 0
什么是 DApp
% j% _  }: h% `# }0 X# V
6 ^% s7 e' \1 Q" U- |- J5 @“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 库与区块链进行交互。# [  l2 t) M+ p5 J" b5 K0 ]

) S9 G' s2 r3 g) x1 ]' ^Dapps 开发包括三个简单的步骤:3 K3 h/ F$ t1 i: E' a
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约' T5 K( c& O" b+ @
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。. J5 E1 ]9 d6 ?! C5 q* g( t, y/ Z

( _! }* b3 T6 y# ]  e9 L* i2 X& H安装
; g, J+ R# p1 a3 O) W% q- O% l" d3 v
Python 2.7 +5 D% Z( T- I& X: j: S& H/ l
Node.js
* K5 R% a) }# M# v4 Q& C7 KTruffle9 o" V0 q- V* N. P4 ]/ v
/ e( B& |# `8 q4 }, ^
6 y: m( {! c% O* x0 j
npm install -g truffle
* `1 y/ M( _& m" \6 u' kPip
  F+ B" Q2 B2 R6 |" |- O) l) K5 i0 ~npm i pip& p$ A/ J- _0 u( c, {/ o7 z- M! l
web3.py5 Z/ U2 R' _) b2 l2 M5 p3 v# O; V
pip install web3
- ]- X. ~' B8 |3 N% A" N
+ j! X* q( P! Q: G: A+ D1 E
$ L+ G) v, A+ E  K+ J$ T: W7 kInfura 项目 API# P  z! N2 k4 u& y, v- E. ^
前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。
$ ^9 A& F( e. v! R, l+ _1 T3 B' s$ ~" x+ Z5 i6 U
智能合约8 P) r, a6 [4 A

* Z5 O6 F3 T6 v! |5 ?* Y3 _* t# H. ?每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。
" ~6 T4 o4 Y& g
; s" r; b" T1 o" h+ z) Y5 V
  1. pragma solidity ^0.5.7;
    & y; g( [2 m/ N( C9 G4 I' s
  2. contract greeter{
    * x. _6 u% v- T" @3 ?! m
  3.     string greeting;! ~) t+ f9 }8 h6 G
  4.     function greet(string memory _greeting)public{& z3 q+ q1 G  \, \7 `! T$ t/ I4 ]
  5.         greeting=_greeting;8 f! ]8 ^8 G* [6 G& @$ m8 Z) m: ^9 ]
  6.     }1 z$ o$ ]. b8 e! k- I/ R8 T0 I
  7.     function getGreeting() public view returns(string memory) {
    $ {% [% ^- j5 N0 h5 x
  8.         return greeting;
    & w% _5 g6 b* {) Z4 K
  9.     }2 J/ J/ E, j5 ^3 }9 D
  10. }
    1 s! o% F5 |, q* l! N8 M; u
复制代码
: E+ o( z0 U6 K) P

1 K5 y# m2 S- C1 g  V2 M您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。2 t; j% V/ m- r' a7 h
' b$ p; A# r% k1 n
1. 在区块链网络上部署智能合约5 T, w+ P) x& @, z& G: v! y0 d7 t
2 i) a( j7 U9 R  Z8 ^
a) 创建项目:9 K1 W; [6 ]7 W+ [6 u

  P. G- a: c$ u4 `* ]1 x( \mkdir pythonDapp$ C! R/ M7 E* Z' c6 E6 C4 b- ?8 u
cd pythonDapp
  {) u9 N+ a/ R) [# B% Utruffle init  j" S% u- X, t! n7 T8 r  T, l

  C& r8 [( N6 K4 `
: x, w- a. k7 D* }成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。  f4 n+ ^, r9 M$ N; B1 _. C

6 B3 H+ i. `6 F6 e* m# |" r3 `0 Mb) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:0 ?( o) w* `" n( A  B' `3 D

) K" R6 d' s9 i7 q/ F# |. T8 s- x+ n) ]( F2 p5 D9 j! i

  p6 f6 E6 e' d( _- Ttruffle compile9 ?, ?" a$ Z; P7 Y& a  E5 F  U
(or)
+ b8 X: P* {& O; ftruffle.cmd compile #(for windows only)
" u1 S$ r3 E: Y0 v1 {$ O) q( E# r

* C$ j4 v1 ~- }+ |上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。
9 g, Y+ R. t$ Z3 Y3 ~/ C/ U% k" ^4 N1 g+ r% B
c) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。: T+ J/ ?* v2 R7 L! N% A1 P9 |8 U

6 L$ H8 M9 A0 |* j2 t. g
  1. import json; r: ?8 S9 t8 V5 j; K6 x) v* u
  2. from web3 importWeb3, HTTPProvider, p+ ^. V  y' s" f- b& B
  3. from web3.contract importConciseContract, K& {. ~/ d# f$ k
  4. # web3.py instance
    # Q( ^7 T6 Q8 R% b+ x$ v! T8 [7 Q
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))* \0 g4 S0 c5 P7 {! S5 S
  6. print(w3.isConnected())
    * Y& m1 a0 K& A
  7. key="<Private Key here with 0x prefix>"
    , P  y6 y$ g/ l
  8. acct = w3.eth.account.privateKeyToAccount(key)- }/ C0 I. e1 \5 u* e
  9. # compile your smart contract with truffle first
    & y! _+ k0 ^! |% S8 ~. w  S7 [
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))7 I0 L9 a( @/ y9 z8 l
  11. abi = truffleFile['abi']& I4 I6 [7 F4 @0 }5 q1 S
  12. bytecode = truffleFile['bytecode']
    3 u/ a/ e0 E( S: F& ]1 F9 N( M
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi)
    % O. V( H# y2 m. ]- O6 ?4 K1 |
  14. #building transaction$ R" W8 I7 j+ ~
  15. construct_txn = contract.constructor().buildTransaction({6 H- r# D4 V/ _% f7 H6 Y* k+ T
  16. 'from': acct.address,
    * C  p/ N# I# V% f* C4 R4 l( ]
  17. 'nonce': w3.eth.getTransactionCount(acct.address),
    % K: Q; K" r: d
  18. 'gas': 1728712,
    8 z$ L. U4 |. y* r4 k# }) b
  19. 'gasPrice': w3.toWei('21', 'gwei')})2 n" P, m3 g2 Y1 X( a/ T( h
  20. signed = acct.signTransaction(construct_txn)
    " z8 e! O4 @( z" C
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)
    2 T, j( N8 F% ~+ y
  22. print(tx_hash.hex())
    8 }7 M0 p# y/ D4 O+ {
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)+ C8 a' p" q1 |# o4 J; n
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码
( ^# w8 Y* t& D3 s" d2 L

8 m3 c* P/ O/ G( Z( a
7 q; M( p) R! |! T, v这是我所做的:
2 ]; S9 Z1 ^0 t& A4 ?! C+ _
. @; z; ?$ J! j导入的 web3 库和所有其他必需的模块
: m4 N0 U4 v/ e通过指向 Ropsten Infura 节点启动 web3 提供程序( c3 y3 f" ~+ y5 ~
添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。
- V& B9 ]# `+ m* ^: b7 C0 P通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
0 _/ H7 p: @; d1 u# I; L添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。
% W. g8 O  T% L* J+ I0 P( N" g使用我们的私钥签署交易并在网络上广播。+ N- k/ d; `9 g: ]$ t2 i0 b6 @
在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。- J7 P, s' N2 b& X. W
2. 向部署的合约发送交易+ \: _& j! y. b( h; t4 [7 p$ @
( m" z5 z) P0 l, w1 l  M  o
在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。" E8 q# D# h1 e
  1. import json( ?7 F, }) i: F5 c" W9 s
  2. from web3 importWeb3, HTTPProvider
    5 E* Z2 L, A4 y9 S. s
  3. from web3.contract importConciseContract) R+ W, l% \" l5 B9 t# s
  4. # compile your smart contract with truffle first) C0 e+ k# b* ~7 t9 i
  5. truffleFile = json.load(open('./build/contracts/greeter.json'))1 I9 @  ]0 l" i8 W6 v7 A
  6. abi = truffleFile['abi']
    * o, c- O( m( R! a5 E2 }  t
  7. bytecode = truffleFile['bytecode']% ^: r# r3 N4 \& u/ A  Y
  8. # web3.py instance
    % A+ c: J3 c# A! Z0 z
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify/ y5 [2 e+ v" N; f6 p& q
  10. print(w3.isConnected())
    & q# g+ z. i5 {# C8 d
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify8 m3 B' c' g& }/ S
  12. key="<Private key with 0x prefix here>"#modify
    8 }8 |" X- k% C  L2 [1 H" z- t
  13. acct = w3.eth.account.privateKeyToAccount(key)
    ; ]- p; l( w$ r" |
  14. account_address= acct.address; z. z5 u- O" B! l8 H- i* X
  15. # Instantiate and deploy contract' I7 y: C8 i, n, M0 X- x7 k
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    ( S8 W* z. D$ W3 b
  17. # Contract instance
    1 H; s8 e8 {1 e- I" I2 Y
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)/ ~+ y. R2 ~' D8 E
  19. # Contract instance in concise mode
    * S5 c' T% |+ N/ A0 u
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    # s: @+ |) |: I+ y" Q+ X
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})% M9 Q5 N# c3 E! k9 E+ T
  22. #Get tx receipt to get contract address3 S, k1 N" o# l3 G6 k" x/ O
  23. signed_tx = w3.eth.account.signTransaction(tx, key)4 @9 N7 O8 d; x8 W7 j) k: O
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
    + \, I. ~7 d+ D. R! n
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)
    6 m8 M. K5 ]: v6 W0 v3 b# I0 w& ?
  26. print(hash.hex())
复制代码

# C# Z1 N  B+ M3 F) ]& O' A* h* W! x+ c- f: X
( F2 M: v: a- P  y5 N2 E
这是我所做的:$ z8 X/ _, L) g/ @

" Q& Y4 f6 F0 X* Y2 ^导入的 web3 库和所有其他必需的模块
, [6 l7 y2 a! y8 @  n) S通过指向 Ropsten Infura 节点启动 web3 提供程序
! b' s" g6 W* ]添加了用于签署交易的帐户地址和私钥
. Q9 P. ^+ p! Q7 I- Q6 w通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例2 Z0 f4 C( n, [! B$ ~: T& c# i! N. U
创建 tx 对象以添加问候语“hello all my goody people”并建立交易
5 p7 k- w9 l3 j8 x# O使用我们的私钥签署交易并在网络上广播。! Q. P% n$ S$ o( a/ t% g# g4 h
在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。( }& Y7 T9 L7 N5 A" o8 }
3. 从部署的智能合约中读取数据
/ {9 E2 O1 ~9 h2 g& Z3 j6 N6 L1 W
8 R( g+ P- T0 F! y) r3 f. g在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。- Z" [5 b2 ~- k- @8 D7 p
  1. 5 v$ h: {9 j" f& P$ H0 X- d
  2. import json
    $ D$ k4 i+ n$ b# K( q! _  q
  3. from web3 importWeb3, HTTPProvider- d1 D5 U1 p0 z: `2 f- C0 n
  4. from web3.contract importConciseContract
    * y' c" l: S- M
  5. # compile your smart contract with truffle first
    . R2 r5 e0 M) c6 z* ^
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))
    " d$ [9 v- l6 L# @6 F7 S% O
  7. abi = truffleFile['abi']
    6 L$ J0 N3 [/ p6 j1 i9 Q
  8. bytecode = truffleFile['bytecode']
    4 C2 W3 P; r  P9 c! Y) i7 s! z
  9. # web3.py instance
    0 Z6 g+ e7 \, n  X1 w) d
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))
    - }. N* O5 \' H' t
  11. print(w3.isConnected())
    ; u7 O5 z. J! ]# B6 W! [8 }
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")
    . ?7 i- O* [3 \3 a
  13. # Instantiate and deploy contract
    * b: \7 e  h. }# B  \
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)4 k/ O0 d+ a4 x, s
  15. # Contract instance& Z) u1 U( l3 {0 B8 E
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    8 g) }8 F$ v+ M
  17. # Contract instance in concise mode6 Q( W6 T* w9 f. K8 L2 g
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    ' `/ e* l! U% x* n$ v" H
  19. # Getters + Setters for web3.eth.contract object ConciseContract6 F% B2 {# f- B5 T+ m9 d% S
  20. #print(format(contract_instance.getGreeting()))
    ) {: R/ }* P" g8 W' z  U8 ^
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码

) Q5 X3 G9 Q3 D/ ]" V. o- W6 Q1 C) G0 y- f: F3 c' r

' y$ g+ m+ e' K$ A" p  g这是我所做的:
$ ~) G, ~' z7 R3 i+ U9 v4 |  O8 L* p) m3 m7 R4 u5 O
导入的 web3 库和所有其他必需的模块
' h8 R7 P: [; e6 d9 e1 E& W通过指向 Ropsten Infura 节点启动 web3 提供程序
- [! t( ~" H' n; Z4 \" [通过指向 abi 和 contract_Address 创建合约实例(来自上一步)4 n, w! @3 J  P" o% o
调用 getGreeting() 方法并在控制台打印结果
. d1 C3 d7 X! }结论$ b2 h* X$ c( V2 O

* @/ Q9 }' c" E/ r$ ~9 Q0 f您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。* l5 |5 P0 E# A6 K$ u) E

& j  T3 ]# ?( H$ C6 W) }1 N
: @! Z. z6 T& p. F参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程( w  P( `+ Y# C7 `* r
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13