Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
2688 1 0
什么是 DApp
3 O1 G( t  E6 S8 e/ ?, Z* R9 m7 T; b" s7 o  i2 v
“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 库与区块链进行交互。
; J& q, M" c0 p( V, H& f
8 e! G: I( r9 RDapps 开发包括三个简单的步骤:1 E, W- J& K6 p7 {
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约
    , [' @4 Q# y8 L2 ~  {# V
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。: M7 ]- q5 M" c6 p/ f
  G7 U" s2 S3 k) E+ r: A
安装& a- h9 Q- k; O  c% `; w

& x5 N1 \3 z8 T! C8 o; Q! T) \- vPython 2.7 +) k/ @- Q6 K& S% V7 s& R
Node.js* i2 Q6 E; ?0 M8 {9 I, B
Truffle
" |  y: P9 x/ n
% Q8 Q1 f. U  e' R, y4 a
% w. u. `$ _  Mnpm install -g truffle
7 f& v9 L/ _5 f5 I1 yPip, g5 }: u# Q' o7 A. q+ M% Z, L
npm i pip* L8 _1 r. i5 f0 u
web3.py- @) W6 a# W0 f- o4 ^
pip install web3
" c) D* f  n: k+ |4 }9 Y  H- n& b# D
# ~7 O" ?* W8 b) w7 h
Infura 项目 API
$ m0 @! l$ V, f7 Y$ d前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。  r" D4 ]9 d; t4 Z3 {

8 s$ J5 ?3 q3 u7 A$ F智能合约
, ?  O5 X3 \) I1 }- K
7 Z3 [! h+ W" H9 v# c8 O每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。, Y/ C2 _0 X* U4 V; {5 m; z8 c

: U6 t; ^/ j7 m/ G7 v
  1. pragma solidity ^0.5.7;
    ! n, |! l& i, W! e: Z2 h
  2. contract greeter{" }% R8 ~. H/ ?
  3.     string greeting;# |7 \1 y# c: q# [4 D
  4.     function greet(string memory _greeting)public{
    : e7 S6 V! ]: b* G
  5.         greeting=_greeting;7 t9 D9 z% B+ Y4 O8 q. I
  6.     }
    * T: _7 A( t1 E8 ~
  7.     function getGreeting() public view returns(string memory) {0 w% y, ^  _$ N& M; O$ {- p( B5 C6 H
  8.         return greeting;9 `) m! J% L) K' a* d1 \# b2 [# \
  9.     }
    & K2 X) Z9 d  J* r. }* d, s( }
  10. }2 [. l- u  w- D# {* ?
复制代码
6 |- p' [. d# {

8 ^, h7 W" L$ z" [# W) k您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。; B/ s9 D) |1 ^& z; X! L: t4 o$ u- w
0 {) ], Z5 {& T1 s5 R
1. 在区块链网络上部署智能合约0 j4 E# d+ |. x% G- k; m9 ~8 `

" G) S9 A1 Y9 E/ i# Ma) 创建项目:$ g& _$ U, y, y, x, G

% ~. p% f. e) o5 I5 Nmkdir pythonDapp2 I1 E6 x/ N9 b: ]3 Y4 G/ j7 w
cd pythonDapp
" f+ y$ h. ?. D+ f, Q- utruffle init
1 ~0 J2 n# d; ?: j2 `$ Z5 l1 \7 J* k# S2 E" c8 x; d

" n# D2 a: K" o# w, x成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。
& C. I* h& _# F0 [% {! e
" A1 g" H; m7 l& [4 J) Jb) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:: C; f7 H. K8 e2 s) S

1 Z( R, B( Q/ Y% x, E7 h
' F4 ?' c: T: a- c6 p4 y3 C3 B1 N8 I: v! V- |  r
truffle compile9 j( m9 J* ^1 f& b; W& i
(or)+ A7 k. D; _% W9 I, G
truffle.cmd compile #(for windows only)! x  w  O4 P5 O; F

) o" n, Y' m' B0 u1 _2 S" I
9 X. t) N3 }& L. w上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。
) Y3 n1 W- K, o: t4 \
7 s; {6 R, O8 v1 ?- h/ vc) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。; L# ]: C. d0 x/ @& C! _+ @2 J1 D

7 d# r- N$ y, C$ ?# k" Q
  1. import json
    ) T, h( l) }! q; }- D  V& u( l8 W
  2. from web3 importWeb3, HTTPProvider
    2 }3 {8 Y$ t& M" v7 w4 \8 [
  3. from web3.contract importConciseContract( @5 q0 b6 \( |
  4. # web3.py instance2 Q' e# P5 G$ ^* K
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))
    / H' @4 r) K3 E# c* y9 h3 G
  6. print(w3.isConnected())4 T% Y. c- }3 K3 p
  7. key="<Private Key here with 0x prefix>". I' ]9 J& @7 t% b( ]
  8. acct = w3.eth.account.privateKeyToAccount(key)
    & r: l4 A0 ?( N; ^. T
  9. # compile your smart contract with truffle first
    & c# t5 ?; b* A0 f: N: J
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))
    . E  S, `. @* f
  11. abi = truffleFile['abi']: B+ L; Y4 Y- o+ R
  12. bytecode = truffleFile['bytecode']
    : A6 l4 O5 B" S+ a
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi)- @& |5 f9 m1 W8 S, ]$ f! m0 t. L
  14. #building transaction
    3 `. Q5 k. a$ A( j. a
  15. construct_txn = contract.constructor().buildTransaction({
    6 R2 U' a0 @' o  z5 q7 w
  16. 'from': acct.address,. v* @# k- _: T$ w
  17. 'nonce': w3.eth.getTransactionCount(acct.address),% l: T! r% n( F, H7 a" w/ M. g
  18. 'gas': 1728712,4 i1 C+ ^" v9 Q6 ~# k1 K  P' `7 \
  19. 'gasPrice': w3.toWei('21', 'gwei')})
    . \( I& ^3 d# g  `) O
  20. signed = acct.signTransaction(construct_txn)
    % y6 g  l& Z! r1 A9 e
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)9 m4 R5 h2 m/ K2 j
  22. print(tx_hash.hex())7 y6 ?. C; g1 C  q( v8 k
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)& z2 \( H8 ~" v
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码
7 E8 F, E" l3 j2 Y" g- X# @3 u

6 w0 H, d: E; e- h! r
  y( t, ~7 k& `这是我所做的:
3 T/ r: y+ L) ?. q1 _1 o1 z. c& e5 |( o/ _: L5 ~' ~
导入的 web3 库和所有其他必需的模块( I, u; b) G% R7 }9 b
通过指向 Ropsten Infura 节点启动 web3 提供程序
& n/ T2 s& B2 ~添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。
1 H+ _8 g/ u3 K6 N& ?通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
! X# |3 F" x% b: O) G添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。/ A( n: [* Z0 V% ~4 l
使用我们的私钥签署交易并在网络上广播。$ p5 n0 x) h; Z# H! Y& X1 x
在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。
. J. g* M; @  @6 ?2 `& P( k. l2. 向部署的合约发送交易
+ _8 G6 E7 z9 L' Q& ?/ F7 Y* r! q+ ^! k
在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。) _: Y. ?1 U2 L: V5 Y5 a
  1. import json% i+ s  i% f( d1 [, N* m: f/ B: K
  2. from web3 importWeb3, HTTPProvider8 k5 m& x& |2 d0 {+ U
  3. from web3.contract importConciseContract
    3 U/ ?1 }9 C& X$ o; _  v
  4. # compile your smart contract with truffle first0 N! v1 Z6 n5 L4 N
  5. truffleFile = json.load(open('./build/contracts/greeter.json'))& m' H$ r4 D3 w9 G. S6 A: g* ?0 B. F
  6. abi = truffleFile['abi']4 Q# L, z6 L) k& O+ `; m' A3 z
  7. bytecode = truffleFile['bytecode']1 J6 j+ Z- k% {0 Q+ o
  8. # web3.py instance
    ) \8 [+ L( S% |, V( |: n; K* V) @6 P
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify
    9 `# s- p) g2 L8 M% ]
  10. print(w3.isConnected()), R1 u( k$ ~. _7 i' D+ A7 ~
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify
    ' a, o/ W8 [. m7 R: B
  12. key="<Private key with 0x prefix here>"#modify
    4 M- @3 h* y! x& a* @" g4 B
  13. acct = w3.eth.account.privateKeyToAccount(key)  F% R# O- s( y& e2 M
  14. account_address= acct.address
    & Z& x& x; i2 r$ Y6 n& C6 q. ^8 [
  15. # Instantiate and deploy contract
    9 e/ p" U8 H  b3 X. y
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    0 |! z( E+ ~6 H- ?% E$ p
  17. # Contract instance
    - W  ^- L5 A+ M
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)1 d7 A8 @6 l) D5 T) |) d' F
  19. # Contract instance in concise mode! [- s& P: A+ S
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    ! f, i" s) y% O
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})
      j2 r$ ^1 L. X4 e# |
  22. #Get tx receipt to get contract address
    4 v0 l# ^, t  \8 t& i2 ?+ y& r
  23. signed_tx = w3.eth.account.signTransaction(tx, key)7 I3 V1 y& \$ y4 W# @9 P
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)) {: r! f' g- K  {* R. W* I* B
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)
    8 h8 ^9 n: h5 g
  26. print(hash.hex())
复制代码
. Q0 z% u& [0 Q8 x5 G& s

% ?- ~* W/ ~0 z& V) D# X/ X, Y/ i& w+ s! [" n& m' u# g# J3 Q% B
这是我所做的:
& h$ m5 T( l: z5 ?# N/ r) ~
9 F. Y7 l9 \! `1 M导入的 web3 库和所有其他必需的模块; m! V+ W7 u/ G% \
通过指向 Ropsten Infura 节点启动 web3 提供程序
% p" _$ e9 G: v7 S# ~) h1 ?添加了用于签署交易的帐户地址和私钥
. @- }/ K3 R& t6 ]4 O通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
9 ?& h" l5 O$ T5 }* `5 X8 j' V, Y创建 tx 对象以添加问候语“hello all my goody people”并建立交易
9 W9 r$ ?3 C& I  M* N使用我们的私钥签署交易并在网络上广播。
" U2 q* m" A2 O: T在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。  ^- @0 C) ^( d- m7 w# T
3. 从部署的智能合约中读取数据: V0 K: F! M% z0 h

3 D! X5 ~' o7 S* U5 |/ T在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。
7 K1 @/ ]. w! a4 \* }7 x

  1. ; p0 _. _6 o, m0 i: p
  2. import json
    ' U; G: J! }* B' U2 y! [$ V
  3. from web3 importWeb3, HTTPProvider
    % ^6 ]& e- t8 g' S0 X* O
  4. from web3.contract importConciseContract
    : }* i( f/ y- c
  5. # compile your smart contract with truffle first
    4 w: }* X- ?4 G& J: h8 A! t" r
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))
    3 A& F5 o. s7 F4 Q: a0 z/ m' d
  7. abi = truffleFile['abi']( y6 ?4 b' Y( t, y. _5 k, W7 }
  8. bytecode = truffleFile['bytecode']
    2 @* J% c% v5 {; ^9 H
  9. # web3.py instance
    ) d! p  {/ |# R* V4 x# A# t
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))
    & ~* y* F( j! `) ^% D. `( F1 T
  11. print(w3.isConnected())# r3 r8 R- i9 T  B
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")
    - v% L; j9 P: ^6 X5 A' c. A
  13. # Instantiate and deploy contract
    , w. i% u1 c1 e+ @( [
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    5 r' G: F3 N" L8 ^' V) g
  15. # Contract instance  U$ C7 S; Z2 J3 P2 Q# C! S( U% Q
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    # A9 K# n8 |' y, I  S0 y* s$ o
  17. # Contract instance in concise mode  K; |& ^9 v* {1 `7 ?) i3 m# A
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)' H. W* a; m8 I" u% W7 S: B3 z0 ~
  19. # Getters + Setters for web3.eth.contract object ConciseContract
    9 u8 s  T; A1 Q! r0 h; [6 _
  20. #print(format(contract_instance.getGreeting())), r. u7 y2 i' r4 h+ D+ u- t7 `/ o
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码
% a+ N& z3 O1 }9 G  t. W
) B6 N, @! n# E* P
) n2 A* l0 Z4 y7 m
这是我所做的:
: W# L' h. ^& @! b& N) h
& @5 r9 `. z. h" X3 |导入的 web3 库和所有其他必需的模块6 Z5 X+ _0 n6 p, M6 S" R: {8 I
通过指向 Ropsten Infura 节点启动 web3 提供程序
5 b! {: M7 R/ h通过指向 abi 和 contract_Address 创建合约实例(来自上一步)7 H- v) m8 j9 E+ h
调用 getGreeting() 方法并在控制台打印结果
4 d: e: `/ ~' _8 m$ x结论
4 S; a7 I6 `8 t( d# @
' }- f' g0 q& L+ u% g您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。# K& F3 q: {3 _

- v6 t1 k% q1 `( W6 t4 H! W3 x) j7 n/ }0 L3 I
参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程
7 C: X' X/ U% L) Q) }1 }8 F
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13