Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
3676 1 0
什么是 DApp
- R% V' J, ^1 G, R) w( Y( f
  [% f# R. w# a. {, W7 Z! [: m' K“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 库与区块链进行交互。
1 }0 c; B, I0 {+ f* ~( `
) `' z  ~% r/ w. r- l5 `9 C  E) v& IDapps 开发包括三个简单的步骤:
: |8 f+ W8 `7 v
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约) ^! |: H* ^8 f- Q) I: Q& r
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。  Q! w7 q% O" g$ D( D1 ^

$ g& }8 i) f) B9 s' N; K安装: J% s) u" {3 n/ T" F1 l% S

$ ]6 o" F: [% ?& z: P& @Python 2.7 +
6 Z4 D7 ^  F1 p7 N$ xNode.js( M! M* Z! ~( Y  K
Truffle' x) f0 [0 m* a& A  C% v( r
  L7 ?3 o3 [' w  W( n( F
- S- ]& C& G' ~7 u) Y/ t
npm install -g truffle  o) y( E/ i! ]% @
Pip% |: L  S& C7 V9 Q& q4 _0 I4 M# v& M
npm i pip, E/ s# r5 h* H$ J% u
web3.py- ?5 Q+ I$ Q1 C
pip install web3
' [' z0 z. I9 ]
* F+ Q. [; r8 x. v& j9 }0 Z+ U  w) W4 ?1 E) e
Infura 项目 API3 Q  G; [7 _& ~5 C
前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。
2 B% x2 u- e0 X! ]# `8 F& j! J% C6 P" N8 d
智能合约
1 ~# n5 b" L5 ~; A& `6 }. ?! {; W6 x. R4 K6 X) \
每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。/ }, @1 x8 g) I, R* ]/ U  A
' R  E  X, [3 v+ a+ T! U
  1. pragma solidity ^0.5.7;5 M, a' y7 W& V
  2. contract greeter{4 s3 \' N! ^1 P- t1 N
  3.     string greeting;
    6 V# N5 _* J1 z- {# I
  4.     function greet(string memory _greeting)public{" m. C% i* \: x: s( V' N
  5.         greeting=_greeting;
    $ b3 X4 g5 l0 g! g- J$ d
  6.     }
    : ]1 u" }. Y- U# A( \
  7.     function getGreeting() public view returns(string memory) {; S* T, t  E, h
  8.         return greeting;+ R1 K: {" D) {( b$ j
  9.     }- w8 C( N0 {& Z/ A7 ?
  10. }# r6 q5 f( C, |' i
复制代码

( {. n4 V* V1 N* U2 w1 C( B
5 ^4 ?+ G: v! f+ w, ]: \! M# g您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。
, q* w6 |$ ~1 ?8 e: f+ i' u+ j! I* R4 |
1. 在区块链网络上部署智能合约
0 b! l( ~6 \5 ^& H" U4 H5 F2 y/ N0 W  d' q' g
a) 创建项目:
/ N4 @+ ~3 n+ O2 p! W6 n
2 i/ `# h$ W) n, tmkdir pythonDapp
2 r9 g# h) Z; t" ^. Q! Zcd pythonDapp- h3 r$ h+ r: g
truffle init
; [7 _6 I  p# M# e3 h, T) e# e) z7 R% k9 q0 q7 h# s6 p

" m7 A% ^$ D2 X成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。
4 {; u  q5 y5 w7 h8 e8 ^' Q6 x1 V. h! e4 m* C+ a1 P& r' S7 n
b) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:) I" ?. x& W3 X5 b, a

" h. l4 B$ R5 U# w& q: X- g( P9 B/ T5 G3 J  D% R& y1 w/ w
) ^$ E' e$ J. U6 w6 F, c) |
truffle compile. ]+ S! h) M- h4 K! {
(or)6 v. B( j6 W. s6 l1 N
truffle.cmd compile #(for windows only)
( Y3 ^6 _3 N' e/ S4 H
* h. h+ M% _- S2 N1 A. a8 U: G" F9 ?
, u4 |; @5 o, I, _上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。# e& Z/ t/ t; N) }

! |( c% \, `# `7 {) ?c) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。
, V0 ?2 [4 C' V7 Z4 p/ d) B
5 d, o5 _% U7 l8 I
  1. import json" b6 d$ Q8 Y: F! A% }7 j/ O
  2. from web3 importWeb3, HTTPProvider
    2 T6 ?- Q5 X- C) S
  3. from web3.contract importConciseContract/ x5 Q5 V# x5 A9 u* v$ T. a7 b7 C  |3 o
  4. # web3.py instance
    9 s" a# M; L; y- Q+ C
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))0 \4 M# M% P7 M
  6. print(w3.isConnected())
    $ z* X3 r7 c0 ]# {) v; r
  7. key="<Private Key here with 0x prefix>"/ e- J3 h  C' u5 K; b2 T2 r
  8. acct = w3.eth.account.privateKeyToAccount(key)4 K. w7 A( G8 {) M" l
  9. # compile your smart contract with truffle first
    7 z/ f# u. f8 c
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))
    . I3 I2 z: E+ ?. v# Q! e
  11. abi = truffleFile['abi']) {/ n& {- h* ]0 W, U2 z
  12. bytecode = truffleFile['bytecode']
    & E; Y) y/ y9 S9 Q& p
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi)
    1 u3 R: K+ g# |9 b8 l; v7 m, J
  14. #building transaction8 l9 F( C' z' F3 e+ F/ r8 i/ L( }
  15. construct_txn = contract.constructor().buildTransaction({
    4 P" O/ `1 q: q5 P! r+ k$ O9 L" U& s
  16. 'from': acct.address,
    ; _5 N" x  s# j
  17. 'nonce': w3.eth.getTransactionCount(acct.address),
    , }  P4 c) o3 l& j2 I9 d
  18. 'gas': 1728712,
    - _: Y' ]( K! K9 [' T4 h2 j
  19. 'gasPrice': w3.toWei('21', 'gwei')})
    ) a1 e" B' u  c8 u3 h
  20. signed = acct.signTransaction(construct_txn)$ D2 D7 d$ R: t% O2 r5 X
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)
      P+ \# m) U& |! H
  22. print(tx_hash.hex())
    1 Z, b  @% R' ]: M
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)5 W0 p9 e% g  W) M5 |% \
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码
  E0 y8 p( s+ B% k5 }. @$ y2 Q
) P/ b' ]' ]7 E: D$ b+ m9 n

/ D' w; t7 V! I这是我所做的:+ p+ Q* u4 r$ }9 m( Y

# V( [  W# f0 A导入的 web3 库和所有其他必需的模块
( l" a# \8 C. u% z$ F通过指向 Ropsten Infura 节点启动 web3 提供程序( f3 L5 g' C1 n, a4 i0 |& E
添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。, m) A' _# Y- \; d
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
2 M9 \/ y9 D" `# O添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。9 S1 L4 J  i9 G3 F+ I0 _+ w' P: z  ~
使用我们的私钥签署交易并在网络上广播。
: S. k( H! c; s3 a+ c在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。, N; L% F8 {  P+ T
2. 向部署的合约发送交易1 L4 t0 T# E3 Q( i  L; t2 \# X; e4 @

  h2 c3 A; A/ M9 A9 U" w4 J在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。, B+ m  O& d3 [- j2 K) g7 ?- E
  1. import json" y% s* x6 t! I* D8 [1 M4 T6 v: o* T
  2. from web3 importWeb3, HTTPProvider  \3 d4 K9 y. G+ I1 p  ~) [, W
  3. from web3.contract importConciseContract
    8 I) F% W& B2 ^. V' B& S8 u
  4. # compile your smart contract with truffle first
      f' k  B- A* [( o8 Q# @
  5. truffleFile = json.load(open('./build/contracts/greeter.json'))
    ; p- j! Y$ h7 @, A
  6. abi = truffleFile['abi']
    & W/ u. N6 V. ?9 f) V
  7. bytecode = truffleFile['bytecode']) T$ T7 x4 |4 O0 Y& |4 O7 x; F4 o
  8. # web3.py instance
    5 O# N& v& a! M$ Z% N7 {
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify$ S- g! R9 {& X2 L
  10. print(w3.isConnected())9 [; c/ ^- w' M) E! R
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify
    0 T( J4 I2 F) @2 ]# \- {  W
  12. key="<Private key with 0x prefix here>"#modify) }/ V. Y1 r2 k+ D1 R4 b7 v' U* V
  13. acct = w3.eth.account.privateKeyToAccount(key): O+ e% R; I, X, p
  14. account_address= acct.address
    ( {' M2 u3 @1 ?+ ^) z% p9 i
  15. # Instantiate and deploy contract
    1 L/ I2 g. E, W/ A: R4 P4 E
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    ( x; [! [/ m1 Z
  17. # Contract instance. r3 f  h* f1 L4 d8 n5 p
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    , m% D/ G! `# ]' B3 }+ h  ]0 r
  19. # Contract instance in concise mode
    , S3 L% n5 }/ H9 L6 U7 I/ @' y
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)- d6 R& e2 Q" S+ v, [
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})
    # J, Z3 f: X, C6 k
  22. #Get tx receipt to get contract address
    $ c5 Z- k* ^8 k4 q5 c, D
  23. signed_tx = w3.eth.account.signTransaction(tx, key)
    * E" Z( b$ c9 V. {4 o# i6 a
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)1 g* d  E/ a  R) A' u# P- U
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)
    3 H. e' b9 M2 i
  26. print(hash.hex())
复制代码
; \4 z  d9 w3 t  y  L) w
9 [$ T$ k4 J3 _/ y
8 _; {4 t# M' B' |/ ~! v& b
这是我所做的:- C0 ]3 p2 S. ]  o7 f' t/ Q

4 J6 Y/ o; h6 Q+ N9 Q导入的 web3 库和所有其他必需的模块. F: g( A& J9 b& V, R
通过指向 Ropsten Infura 节点启动 web3 提供程序
# @2 y; I% Q8 M! Y( h' l添加了用于签署交易的帐户地址和私钥
0 G& |. h- k" t) A( P通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例7 i5 I& Q/ e9 H; ]
创建 tx 对象以添加问候语“hello all my goody people”并建立交易
% e* }$ e5 d& L7 [; _- }/ S使用我们的私钥签署交易并在网络上广播。
9 l8 [, w6 q$ y5 ~5 X% `* o: [" a5 _在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。) O' _9 z& e& ~. ^
3. 从部署的智能合约中读取数据7 D% z! f7 r; l: Y3 n

& Y/ H, O/ R2 k6 L) r; {* w7 M在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。9 d$ Y) g  o. p7 M
  1. % i. m2 w3 @7 [2 G2 M: [3 f# [3 V
  2. import json* U" w9 J0 ^+ e5 q. {6 b
  3. from web3 importWeb3, HTTPProvider# q6 v& N4 J2 \9 P6 ]% m+ x, n
  4. from web3.contract importConciseContract
    ( x9 o& x- h. N
  5. # compile your smart contract with truffle first
    3 D3 q" N. L0 l% J% ~
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))8 U# i# g0 q5 x3 g2 O
  7. abi = truffleFile['abi']0 z# O8 ^0 j) I, y& L2 ?% F
  8. bytecode = truffleFile['bytecode']
    8 D/ c2 [2 K0 F$ ]- s
  9. # web3.py instance
    ( {/ ^9 S) y$ |7 i+ M* r# \$ A
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))
    ' `2 x0 Z  n8 I: ], R; a% l3 Z1 n
  11. print(w3.isConnected())
    8 }4 [4 s. u* q' J7 K4 F
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")9 d& h6 i" y+ G' \) l) T
  13. # Instantiate and deploy contract
    " _: ~* n& S' Z: a9 D4 W/ g
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)$ K  r8 i! ~) \! O
  15. # Contract instance2 \6 f7 W" l1 ]9 m, c* E
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    9 S( ~$ d) a2 R9 n* k
  17. # Contract instance in concise mode
    7 ~7 D* J* u1 R5 f5 l* O4 `, o% W
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)* J# ]9 e2 B. Y' U8 s
  19. # Getters + Setters for web3.eth.contract object ConciseContract
    0 t1 G3 x1 W2 i% X* i0 i7 y
  20. #print(format(contract_instance.getGreeting()))- Z7 `* E4 g$ g$ r( J
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码

% ]) p1 |( e! k1 a$ w2 {, j7 F9 i5 }# |

3 N( V  e; G6 T1 r0 {, e这是我所做的:  [# |9 k" G4 |0 B3 Y4 p& B% d

7 m' ~' T% A2 p7 Y( N3 ~% }导入的 web3 库和所有其他必需的模块, Z6 d" {. X" F9 i2 P
通过指向 Ropsten Infura 节点启动 web3 提供程序: }0 ?% I0 `3 u
通过指向 abi 和 contract_Address 创建合约实例(来自上一步)
+ R8 A( c7 o4 v1 d. M9 R调用 getGreeting() 方法并在控制台打印结果
* g) ~$ A. d' j结论
: [$ [9 g' p* J/ ?- n! W6 E% g+ ]6 \( Q: b2 h8 F: ~
您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。
! V4 P6 c! S* E; }  [
* m) {' }8 Q) q/ d0 I, f! `8 _5 Y: C: C1 j; i  ], Z% x5 |* E
参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程4 O/ U! u3 z7 [8 b* _  B- m
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13