Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
3615 1 0
什么是 DApp
2 S7 S: Y, `8 L! d( f7 ?
: P2 y- ~; Z  O% q“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 库与区块链进行交互。2 \) |7 Q. c" x6 f
, M+ d2 K0 T  \+ F% S; B; a+ g* f
Dapps 开发包括三个简单的步骤:
) c4 v4 G0 w8 s7 H; t/ j! ]0 N2 J; N
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约  j$ g) H' C, G0 D/ F
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。% T1 S5 V4 D0 s7 ?8 v# u# Z

0 W( d4 Y! V5 g1 ?" s+ d$ i3 [安装7 T& m" _0 Z' J

0 M5 S1 [) I& f$ IPython 2.7 +
/ K" o4 I/ A  F* w1 {; Q. _Node.js. v7 Q% P" l6 g7 r- g+ I
Truffle; k+ T. s. s: |5 Y2 i8 }: U9 `  |

9 N/ C$ M9 O" U" O$ i1 i8 D: F/ ]. P7 l$ o7 |
npm install -g truffle
$ U5 f* _, j( G% L: n. K" mPip
+ Y! u) o! U* b9 T* n; n* U6 j) Jnpm i pip: s$ R. s3 x( G5 [' I. b  e8 M
web3.py
9 p  d8 r* {7 G: S9 }# E/ ^pip install web3
  T1 I6 ]- n5 V4 L" L: W
/ `  o4 w2 {. O, R3 k& S- r. u' F& z# V! n+ y, Y% R7 J
Infura 项目 API
8 O2 z5 b4 \7 a& M前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。! v% b5 q- r3 Z2 X
# `/ M6 t# c# ^+ g7 @
智能合约) H$ t! Y3 f( h

: v  j: w9 V* m每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。
: y" n4 v3 {- Q* x
; B2 x0 j& N" K( j, X5 Q
  1. pragma solidity ^0.5.7;
    2 o9 Z1 }5 T5 s, Q  @
  2. contract greeter{
    : l2 U9 i2 j. Y  L2 \
  3.     string greeting;
    1 g% f; [6 `5 w5 }8 N7 s0 C
  4.     function greet(string memory _greeting)public{; }# B6 `+ ]3 l' W- T, \
  5.         greeting=_greeting;, n  p6 A7 {* ]- j$ V
  6.     }# g% `( d# Y# L) ]8 W# R$ J5 e0 U
  7.     function getGreeting() public view returns(string memory) {4 x6 N3 r$ k% _( T& ~
  8.         return greeting;* d/ w+ z$ S2 f) [- n+ a% g
  9.     }+ n( I5 A3 p( u3 i: T8 d' h/ {; S
  10. }9 x) F/ }7 r& ]9 c0 F2 y, `
复制代码

# s) f7 L6 E3 e5 @) U7 Y) N
% |# `$ I* {' I0 n1 q& m您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。
! U8 f9 v  T7 g  M3 s4 u, ^* M+ @+ R. h; R. j" z
1. 在区块链网络上部署智能合约9 N. ~. M4 ~7 m! ?# f+ h2 Y7 ?

5 U8 m2 i( G) B' A) R/ t$ ia) 创建项目:2 R0 s: _, @3 D7 w( K$ z# p( v) L
8 n4 v. H1 \, V# m7 s5 _
mkdir pythonDapp
: C- v5 y  h3 [- v3 ]cd pythonDapp2 Q* ~' _8 c5 V2 G; c0 O: J5 N
truffle init5 P& x7 k7 z6 k1 l9 b! r

3 X9 C, Y/ s' l: T' N5 N1 o7 w$ N9 I. m1 Y7 p
成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。
; E+ \4 h0 G8 O4 A, R
6 U4 v4 y- v1 G: xb) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:
# T! w0 x- K: N* u& `8 \" O+ ]& V

2 c7 Q; t! A" [
/ z5 F9 ?  d0 struffle compile
' S/ u# i# b* t/ C% _+ x(or)
6 Y/ i# X3 s, c3 D! s1 c5 dtruffle.cmd compile #(for windows only)
# t, v3 v# U0 j+ j9 \' h( @/ N
& ^6 E0 }- C$ ~' ?5 t, d: _: x+ @7 f' [# h
上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。* h: d" }! `3 g" n: p1 u

3 N$ [1 H% D& J; D- P3 \% I- mc) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。
9 D4 |7 C. W$ ]: C. f; h+ B' Q$ R2 {8 @
  1. import json
    ( h& k3 Z# G7 I- x, ^. C# V
  2. from web3 importWeb3, HTTPProvider" q/ t& _5 Q+ Q, B9 d$ r
  3. from web3.contract importConciseContract1 j* f4 G" r, J( ]1 P4 Y& X; v
  4. # web3.py instance/ J, W4 ]6 M9 q" e, M
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))
    ( \3 p2 Y$ @+ Y8 w( f8 S! o7 p
  6. print(w3.isConnected())2 [4 O, x- t  |6 l( o7 t
  7. key="<Private Key here with 0x prefix>"5 B# U0 P0 {3 r/ @" d
  8. acct = w3.eth.account.privateKeyToAccount(key)
    1 R( ^7 _% Y, ]
  9. # compile your smart contract with truffle first
    8 p5 B8 o3 \7 S- }
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))  ^0 p. g# `/ n1 u0 F
  11. abi = truffleFile['abi']2 X' U, r& J  J' w' R; w
  12. bytecode = truffleFile['bytecode']
    4 V# O: y% b" p" c, J. r6 A, G
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi)
    : Q6 s3 y, s( R% _- h! E
  14. #building transaction- {: w7 k1 E. o' \% [
  15. construct_txn = contract.constructor().buildTransaction({  E( R& g8 p+ m/ m0 M+ w
  16. 'from': acct.address,
    ) [, i% L5 l. R8 N
  17. 'nonce': w3.eth.getTransactionCount(acct.address),# _( I8 C8 d9 M& n
  18. 'gas': 1728712,- V' f% L2 I& p' z6 j) f* T+ V
  19. 'gasPrice': w3.toWei('21', 'gwei')})# b; ?, U" }6 x+ A2 P: r% m0 _
  20. signed = acct.signTransaction(construct_txn); h0 O: K: ?0 L7 }
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)
    ! L0 i7 `) c8 Z" E9 m: b- I8 U
  22. print(tx_hash.hex())
    & [' O5 m! {) z' g% M; }% I+ J
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
    # u. D5 V( ^5 `1 o( l) m
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码
9 c& N# R- |4 `& L( ?

8 V0 Y2 j2 I! w; O% v/ m" e! p+ D) x& G; F9 j0 ?
这是我所做的:2 J% e8 ]" u; ~, z; [- B1 |8 _3 a

) \4 f6 K, \, U6 O导入的 web3 库和所有其他必需的模块; M1 }5 M! `8 o# M' |0 Y1 ?
通过指向 Ropsten Infura 节点启动 web3 提供程序; r. k* m1 B' Z, n* Q+ G
添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。
) B8 A. K( U5 ?; z, ]) g通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例: j( ]0 y- i; I  ^
添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。
+ b2 W0 K, W/ g1 k1 T  B使用我们的私钥签署交易并在网络上广播。
/ v, A  c( H6 w5 l在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。$ U2 d, P, }7 F6 o
2. 向部署的合约发送交易
( v# c4 r' t$ s( c
& M/ k. c  `' o5 u8 Y, P在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。
+ i2 _1 J5 A# X, E8 S' `$ S4 K- a
  1. import json1 H: J, G" z- ]4 |9 e. L2 F
  2. from web3 importWeb3, HTTPProvider
    " w& `+ `1 Z, F( `  M( g( j
  3. from web3.contract importConciseContract. N% U5 e' R  d/ R
  4. # compile your smart contract with truffle first2 g5 a/ z6 u0 i" f
  5. truffleFile = json.load(open('./build/contracts/greeter.json'))
    ( B* Z6 G' M: k1 `, n
  6. abi = truffleFile['abi']
    . i2 d& v& z9 u2 w4 }6 g
  7. bytecode = truffleFile['bytecode']
    7 x$ ]0 W9 L* \; v" t( D
  8. # web3.py instance
    # H+ S% E6 z- W0 X2 n0 [
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify
    " F6 k  G  M1 r( H% k3 |0 c0 l$ c
  10. print(w3.isConnected())/ U  Z% p& V# R
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify* w* A8 W9 M$ h( T  ]8 J1 z
  12. key="<Private key with 0x prefix here>"#modify  a1 f2 O3 U! g  D( U* Q
  13. acct = w3.eth.account.privateKeyToAccount(key)
    7 J1 v, l' A7 {$ _' p7 b8 a
  14. account_address= acct.address2 M7 B) g: T, N1 w& A4 N
  15. # Instantiate and deploy contract7 b7 O6 J6 D2 {; N7 Y
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    2 u2 r8 P" @0 w9 t- C) w
  17. # Contract instance! v. }$ T; o3 ~  Y$ Q* y9 N
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    0 s( ^/ l) X# }2 c
  19. # Contract instance in concise mode  R. `! G/ t  i3 j
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)8 t' x1 I' O  c) F8 X
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})
    # @: F' f+ C9 t, A
  22. #Get tx receipt to get contract address& ~5 l, t! A9 \6 I
  23. signed_tx = w3.eth.account.signTransaction(tx, key)1 W/ G+ t6 N: z+ c
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
    ' Q" Q+ [! {7 B7 u7 ]
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)1 ~5 q4 q4 {) D* E
  26. print(hash.hex())
复制代码
. L0 z- I" m- ~# R* Q' O
) T4 b4 _& n% n* k$ V! d7 V

: ?' o0 w) m; K# I' Y1 A# y6 [( [' k这是我所做的:
9 N, a9 \- x# a' |1 B. C& i6 O! u: Z9 i  o; l$ B8 s
导入的 web3 库和所有其他必需的模块/ z' M! O; ?4 \/ C! n+ l; l% X
通过指向 Ropsten Infura 节点启动 web3 提供程序
; M; ]. g4 W) w$ d; N8 _添加了用于签署交易的帐户地址和私钥  u" }+ _% o# L8 K2 E. p3 Z
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
5 c  l9 U8 W7 x$ x3 G创建 tx 对象以添加问候语“hello all my goody people”并建立交易
+ o1 B6 ^5 H7 z" h; H/ t) [使用我们的私钥签署交易并在网络上广播。
/ G- r. l& T, ^% c在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。
9 _; x( @% H1 g3. 从部署的智能合约中读取数据& U& e) }# b( ]7 b3 X
1 X  F0 I# C- S* c- r3 U
在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。5 j2 x% V; c# @5 J

  1. : X1 b  C; Q( ^; u7 F8 Z
  2. import json
    & w( w4 l/ e) w% t+ t. h% W* B) V
  3. from web3 importWeb3, HTTPProvider
    5 w$ |/ ?8 z8 O$ B0 _
  4. from web3.contract importConciseContract! i. W( u, ^1 \1 w
  5. # compile your smart contract with truffle first
    ( J6 y4 V- r% Y  x/ P$ x  ]$ l! z
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))/ i& j0 y4 y* y) S; ^6 i# S- f3 c& e
  7. abi = truffleFile['abi']
    ! {1 i4 C0 z% q) I; t' z( ?3 U( U: k
  8. bytecode = truffleFile['bytecode']
    : `& w: ]$ Q; R) W8 E- N# O. w2 W
  9. # web3.py instance9 n4 X( d" ?! C6 Y1 k
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))
    . Y6 Q2 D1 d+ D6 _
  11. print(w3.isConnected())8 t  v2 s; H+ Q
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")
    6 w8 b1 g' p2 [! n. T, C
  13. # Instantiate and deploy contract/ \$ s- L4 j4 ^& n; o
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)5 E6 T& T$ z& ]# ^
  15. # Contract instance: N" j+ i8 S4 Y& b
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)9 ^7 n& s1 W2 W
  17. # Contract instance in concise mode. k( P6 h. P1 j! Y( t, y0 l
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    - F, x, r- ~. U! N& n4 p
  19. # Getters + Setters for web3.eth.contract object ConciseContract
    % a3 D2 a( |! |+ H8 U. j
  20. #print(format(contract_instance.getGreeting()))+ R) s; Q/ H9 N: t* _' h; P
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码

9 m" I& f# y! b/ K5 c/ y' S
; S/ O3 \% M* ^$ H$ D) x% N
8 @$ U1 l* r& W+ I5 I' r这是我所做的:6 {2 e0 c+ j6 M3 f6 D- o  v

! L* o- i4 v! r$ k7 j5 ]导入的 web3 库和所有其他必需的模块
- Z# a) t% ^! L9 Q通过指向 Ropsten Infura 节点启动 web3 提供程序; @3 r1 g1 d/ g4 d( v. l8 V/ h
通过指向 abi 和 contract_Address 创建合约实例(来自上一步)9 u2 s1 ^9 p4 ^7 f
调用 getGreeting() 方法并在控制台打印结果
/ o& i6 N7 ]2 S% l, w6 L结论2 K: P! w1 \: E) ]. z5 b$ s

1 @. [2 e2 C- m1 M9 F  c您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。
+ f; P9 n. N5 d! t" y2 |. n$ q  ?; N* Z$ s

2 U3 K5 j5 D6 d* L参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程
* E  s' ^8 g) j6 s& F
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13