Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
2905 1 0
什么是 DApp* i5 Q. k" K& I" T: p; V& y: ~
. W% f3 b# @9 ]5 _/ J
“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 库与区块链进行交互。
4 w1 W( a/ h- J. ~1 f5 P% c: _& x& _* Y7 }/ ~- ?
Dapps 开发包括三个简单的步骤:1 j3 q$ m# a: m: K5 d8 j7 K; ~8 b! _
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约
    % L) O5 `) U* f# R# ~4 b! D
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。
1 w& U$ d7 F# j$ g5 F, e! i  @6 N1 L3 r, s( l% m# V
安装
  O/ O) G' O0 N8 z; ?$ x: ]5 S
Python 2.7 +
+ \3 t2 W9 \+ C# x: p8 l& MNode.js
1 H5 f) m' f, {( \1 N+ J6 mTruffle; y" {! F+ X3 d( q9 S

" l# T( H% E- b1 Q
7 K$ s+ `( t; i8 @npm install -g truffle
" u' t+ i) l# ~0 c+ O  q1 A) `# BPip
( H: C8 ~6 ~% @8 r0 }, d5 K3 lnpm i pip# |1 q3 m! _1 f4 p
web3.py) f( L6 S" J. R$ h+ g
pip install web33 Q2 X# R, `7 g1 d+ s2 I
8 K. l3 J8 X- z& ?; q) K
3 p, @/ G  C" N4 E( y1 x
Infura 项目 API
7 @* }: J7 `2 p! f0 Q5 b前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。
/ y3 J  s! K5 K3 c5 |1 l7 W
, R2 W9 q! X( C( o智能合约
/ A3 [; m6 b9 @2 _( i/ Q) a0 v2 ]$ p0 ]
每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。1 }. ?0 y4 b2 {% Y) _; d
0 v1 B/ e, @2 C2 `: d
  1. pragma solidity ^0.5.7;" Z9 A0 R7 [6 K" O
  2. contract greeter{
    " e0 p4 t. U  J1 ?$ R
  3.     string greeting;; q1 ~9 T/ Z$ O" ]! O) ]" D' S
  4.     function greet(string memory _greeting)public{5 a5 B% C1 b/ ]2 ?, u) r9 E
  5.         greeting=_greeting;, Q0 q& R+ y" G$ X3 A
  6.     }
    2 Q, b* y4 z# J8 e+ F' e6 B
  7.     function getGreeting() public view returns(string memory) {8 ?% M- g" ?0 S' h& s
  8.         return greeting;
    , @7 h) Y. b. o2 V$ s
  9.     }
    ( w# L2 n, l1 I) X+ t
  10. }
    $ [' e; S; E9 }) Y
复制代码
0 H& C& A* ^2 ~% k% m) H6 Z% y& Z

4 |, q" ~" l2 d5 C您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。
  a, z6 z4 d0 b
5 j9 q5 c' l6 c1. 在区块链网络上部署智能合约- R+ Z) O$ f( c; J4 R, ]; j

0 z  ]  r; A( U. O# d+ N( U* Ia) 创建项目:$ {: f* M# Q" _! k4 o: `

% @( ~+ M0 w& C5 ]# u! `mkdir pythonDapp2 ]( P( Y- T6 e( K) |
cd pythonDapp
' c6 F+ J: F; atruffle init
# ^4 i, a9 W5 Y7 K* p! {
: G# K& ~& K8 x6 ~9 z0 s  u7 K& C! Y) l0 h. H) M  I, P5 V. M
成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。
! O/ _/ t4 K- W
$ N  b: Y! G+ G6 p5 }: ]% sb) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:2 h% g; F" O0 }. `% {  U% d

6 q1 \8 j( i$ ^. M5 G1 U% N! |0 A" E: z8 i
( a& d; P! D* a5 u) f& g3 O2 ]9 ]
truffle compile
% w/ Z9 w8 l* V3 x, R0 V0 r  _(or)' S, f$ p) P# B6 E3 l: J) B5 B
truffle.cmd compile #(for windows only)! m  M7 c( r' v( T1 K

4 ?  x, [+ e" H3 t6 a- s/ I
; c5 z# o6 S5 O: X- M上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。
3 W; t6 w3 r$ I; ^$ ?0 w
/ f# d! A0 x% ^c) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。8 g. X+ p& d* P; Y2 _, ]% }
/ L9 U: M, q' k9 S$ F! M5 ~
  1. import json
      Q" @! \8 _' f- e  ^$ z$ O# m) d
  2. from web3 importWeb3, HTTPProvider
    6 O& K0 A( w, w& e: I2 |2 ~& u8 U
  3. from web3.contract importConciseContract/ b5 m2 Y" i: [* M
  4. # web3.py instance) h3 Z$ }: d' N" P4 X2 t* }$ U4 L; J
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))
    * x+ R  g* ]/ |2 y
  6. print(w3.isConnected())$ x! ^. m- E6 i6 X% g) s
  7. key="<Private Key here with 0x prefix>"8 G$ G3 z; y* e8 t( ~( I
  8. acct = w3.eth.account.privateKeyToAccount(key)
    . ?# I2 K5 G1 s  K2 G. ^
  9. # compile your smart contract with truffle first
    - U8 w0 }- h/ a
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))" ?8 ?- C5 |9 t- K! d5 |  E
  11. abi = truffleFile['abi']9 ~6 {/ S: }* R7 Q* C
  12. bytecode = truffleFile['bytecode']
    7 M# ~4 u$ A5 g! L! V
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi)/ g; Q7 V& h$ ?9 o7 ]: ^& ~1 n- V
  14. #building transaction# ]: {6 M1 R" C
  15. construct_txn = contract.constructor().buildTransaction({
    0 E! j+ n" I- a% c) n1 R
  16. 'from': acct.address,
    # `' g4 l2 n% W4 }0 ?2 u
  17. 'nonce': w3.eth.getTransactionCount(acct.address),& B- O0 x* D9 U9 P( K7 r* T
  18. 'gas': 1728712,7 c' D, ]. W5 J( ^5 q9 H9 p' |& n
  19. 'gasPrice': w3.toWei('21', 'gwei')})
    ) G( G' Q2 |6 h. Y
  20. signed = acct.signTransaction(construct_txn)
    1 G* k: t& [5 Z* s
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)
    5 g5 p- f6 l6 W5 W: z& w+ Z
  22. print(tx_hash.hex())
    $ _( y" e9 {3 _' e! Q. ?# u
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)# i# L$ {' a  M5 V' \5 ^5 ]& F% c
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码

$ d: X$ N$ B# A! d3 _5 f9 |. ~7 V
* R* C* h9 V, F1 c
这是我所做的:
, R, P8 e! P: W) H, I4 j+ V5 w( w" L( g# S* g
导入的 web3 库和所有其他必需的模块! Z- k" t& ^3 V
通过指向 Ropsten Infura 节点启动 web3 提供程序( x7 i: U* i6 G$ `3 ^9 N3 v
添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。
0 V) ]3 t1 r1 U通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例, X4 {* t, q! u- E+ c
添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。8 M& m; I2 m6 W- y$ S6 A
使用我们的私钥签署交易并在网络上广播。
% s5 M# R* k; l在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。# @* o; ?  l# [4 e: \. ]. N
2. 向部署的合约发送交易
7 E% h! w  N1 a) x) b2 ?3 R
' W1 v, d" F( `* V在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。
6 R& V' S# f5 z3 h8 b& f$ o
  1. import json
    , T# W. \; y# K; ^
  2. from web3 importWeb3, HTTPProvider
    - x6 k+ m+ k/ |. d: n2 X4 I+ T+ K
  3. from web3.contract importConciseContract% E2 W% M3 h/ j
  4. # compile your smart contract with truffle first
    ) h3 A- \' w* g
  5. truffleFile = json.load(open('./build/contracts/greeter.json'))# X+ K3 d5 W$ Y6 ]3 o9 }# B
  6. abi = truffleFile['abi']* s& |9 X7 q4 ?; \$ N/ e' H
  7. bytecode = truffleFile['bytecode']
    ' C- o6 S& ~/ _% a8 r9 y
  8. # web3.py instance
    ; ?+ F9 \7 G& o7 z. E/ F! c
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify
    9 f3 i% s, S5 B, L  I
  10. print(w3.isConnected())$ M: s1 j7 D* b5 }( P+ ]$ I; V
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify
    % M6 K6 P) k3 @6 x1 }1 m
  12. key="<Private key with 0x prefix here>"#modify! }9 n6 \8 L. ^- p
  13. acct = w3.eth.account.privateKeyToAccount(key)& B! S2 b) l3 a+ t! j. ]+ D3 y
  14. account_address= acct.address# _: A" d3 B& B4 q; M* n5 I& G
  15. # Instantiate and deploy contract
    0 j. G) D  Q( F& e) g
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    # V! {7 k- Z( X
  17. # Contract instance, K- t. w$ V% U- h
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    ! b5 w1 t0 U  l' P2 @/ r7 z" ^
  19. # Contract instance in concise mode/ b' g- _$ }3 U% O! Q3 |8 q- y: n. m$ w
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    7 W* w# `: f' y, d- H, e, X9 f" H
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})
    2 t" c! `3 }  c
  22. #Get tx receipt to get contract address' q5 @! N. G5 @7 |6 Z; g6 H% E
  23. signed_tx = w3.eth.account.signTransaction(tx, key)
    $ {* }" d* |. M. R% A
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)% }. w' [- u  w% \  o: }* j
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)
    6 l+ W" U+ n7 O6 d- K4 E/ N
  26. print(hash.hex())
复制代码
: E  t) n9 S8 O( K0 h; w/ V

- Z0 A" Y7 _& w* w( \% a% R
7 \5 g2 k8 t! _+ A这是我所做的:9 y/ K( j' T( G4 {3 R0 }

& a9 h  T8 H9 ~5 U2 l2 A( m导入的 web3 库和所有其他必需的模块, H% K, j4 a" R+ j6 v
通过指向 Ropsten Infura 节点启动 web3 提供程序
5 B7 H4 C4 ?# L$ ?" h添加了用于签署交易的帐户地址和私钥
. j, k5 Y: ]" O: ?  t% P通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
; S4 V4 v" }& l- s3 ]& X4 x5 s创建 tx 对象以添加问候语“hello all my goody people”并建立交易
7 y: R8 S% c" y; s- j使用我们的私钥签署交易并在网络上广播。
/ b4 o3 I+ C6 ]% @& h在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。/ t1 U* G, P, V8 O! E
3. 从部署的智能合约中读取数据
$ Z: d, r* m5 J$ m3 E3 ?& V$ G, I; X) N3 e$ P- X* G
在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。* D' q5 F, k, }  A

  1. ( y$ W! d. z- b& `6 w
  2. import json2 X  m2 p' V0 _/ ~
  3. from web3 importWeb3, HTTPProvider. @( b5 W' x) x% Z/ n8 s5 n
  4. from web3.contract importConciseContract/ i/ c& p* ?$ P1 Y$ A5 j
  5. # compile your smart contract with truffle first
    " N! J$ E& ?, b& Y% ~9 j- `0 V
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))
    7 [& |: o# \7 z9 L7 Y
  7. abi = truffleFile['abi']
    1 K6 `# Q# P; j
  8. bytecode = truffleFile['bytecode']
    " Q" P4 X% ~- b( t( I3 x' v! {, L
  9. # web3.py instance" r+ O4 l. V9 J1 R- K
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))
    . w- M: T5 E" ]' E% l
  11. print(w3.isConnected())
      ?7 c0 Q( b0 P
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")
    * K+ J( _+ i1 j  F
  13. # Instantiate and deploy contract2 F; S+ ~! q4 z! j0 _2 Y
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    + G& z* k) }) Z; \
  15. # Contract instance  P1 T6 G$ L7 u6 O  p- ~8 Q
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    - X1 N  J3 g/ e/ G' h8 I
  17. # Contract instance in concise mode! h+ C1 b( L5 x4 {
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    . Z! z; V! U8 I' X
  19. # Getters + Setters for web3.eth.contract object ConciseContract: m3 @: ]  Q  o( P  I
  20. #print(format(contract_instance.getGreeting()))" E5 ]7 D/ s/ Q6 x
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码
$ J: @" z* g9 d2 K4 x  E* Z

) m) R( s9 h1 @4 D' u5 O& J6 p( |& z2 O3 h
这是我所做的:
2 x7 G/ j7 B* r% c7 n! z
3 _4 n* H  R# b' U导入的 web3 库和所有其他必需的模块# P0 }. g5 W- o% n6 X
通过指向 Ropsten Infura 节点启动 web3 提供程序' v) X* H+ l* Z* d; K
通过指向 abi 和 contract_Address 创建合约实例(来自上一步)! A4 s. P% ^3 s
调用 getGreeting() 方法并在控制台打印结果& \9 u* t. ?- Y+ S* q
结论- X0 V3 q$ M9 d

1 q9 J( Z$ _) h, j6 O# D! i* q您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。
2 {1 m7 V8 n4 L' |5 M! d* ]% h! t7 _8 f- {  q' a6 C. V

* ?" ?- o  J! j$ l0 Y: E参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程
, s9 V5 M" n; Z( H; X/ E9 V
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13