Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
3678 1 0
什么是 DApp
& X# X4 g% X0 ?" {2 v6 V* ^& e, K4 C5 `0 Q6 l& 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 库与区块链进行交互。
* }# d7 A+ F3 E: E, ~8 h$ \
! E/ z2 p) Z; T- ]Dapps 开发包括三个简单的步骤:
0 X0 w- u, G: a2 s' w( @
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约
    : l/ x9 t8 b# p6 e+ s! P/ S* M8 [
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。
. k: |1 G- z, m  ~* I0 j6 j
* n# G% w; e0 ^7 z7 P安装0 U3 C1 H6 G1 R+ E0 w0 A
8 v; \  k9 x) v9 g! ^
Python 2.7 +
, i; x  S* D) e  rNode.js
' [1 `, D6 |$ rTruffle
0 M/ S" \4 L8 n& Y% F  f1 E5 X# c& H% Z& h! W
( i, }* U2 E" j7 w1 r3 U# J5 p
npm install -g truffle: q* \! U' y  |. v0 R: p" Q8 T; |
Pip# U1 D) j6 W! d( X# I+ J( H
npm i pip
8 y! `& }: Q$ ?( P) P) n, Jweb3.py6 s3 y2 I. g! K( m/ P. T: E3 L, ^
pip install web3
" u1 P1 ~6 U9 \5 c" l- B$ j2 E# A9 w
( ^6 j9 ^/ C& n( t- e1 `- {5 P) D- s1 @. D
Infura 项目 API
. S6 ?, |% i) W: o; b前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。
' E2 `9 U+ f( ~) p+ N4 W+ e8 }* I* H  Y3 p1 y" d* U1 K6 w
智能合约+ {9 q6 V3 v2 E( Y' I2 ~

( v" N  }/ x7 h% B- s. p* r/ w% Y' x每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。
9 ?) v: c8 P2 h3 x: _/ E: D0 X/ T
  1. pragma solidity ^0.5.7;, Z' ?$ A- M( X- ]% R9 `
  2. contract greeter{
    7 w3 a1 p. p+ @7 w2 X+ h
  3.     string greeting;- n  i7 ]- I9 O6 X# D
  4.     function greet(string memory _greeting)public{0 G5 r8 |4 v+ [% \" l% N* z
  5.         greeting=_greeting;, p1 a, E* v% r6 `6 F$ [+ N
  6.     }
      t/ J! ?  G7 ?6 M3 P, W
  7.     function getGreeting() public view returns(string memory) {/ `" I3 I/ Q; @2 a+ _( l) Q2 ?9 q
  8.         return greeting;
    % [5 P/ u- P# O. t( q
  9.     }3 T* \$ G! G3 a% _
  10. }$ \4 C3 u# o$ _/ I1 R6 W
复制代码
% A; C$ L5 ^( p6 a/ G
2 Z. X' R- B6 T1 L) G, q; K
您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。7 f& r7 i3 c; Y9 i

4 q' @: C8 x' |' V; D1. 在区块链网络上部署智能合约
1 T, [- ]% X! U+ ]  y3 u, B8 o* E6 X# C1 K! ]3 e
a) 创建项目:/ x4 u" [. s% R0 D9 v. `
/ \4 x9 e( D7 f0 a' J* f
mkdir pythonDapp
6 H# z' A& v5 Acd pythonDapp
4 J: x, p+ N  Q: W' ?1 p" gtruffle init, d6 ~6 F% n" k4 t0 q& b$ T

7 z1 D7 z. L1 ~, F8 y, H( d, [+ O  k! F+ Z8 X
成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。
& Z& P% v" U- H$ x& O6 A; E, J
5 v/ W4 B0 y  b2 T7 C9 b$ Ab) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:, q1 s# o; n) t; Q, j2 C6 c

4 F- l& E$ j+ F4 c
* @/ ~9 h; Y0 s, y1 k. ^, S# A5 I  V# G. I; i) a. f3 g2 X' {
truffle compile
' f8 {9 m* C7 k, y, s2 N5 u(or)
# L. x& \1 p! w6 O- w, l7 }+ ytruffle.cmd compile #(for windows only)
  W1 `) m& T8 i1 P5 d4 C$ D/ o1 p6 b" x6 P8 {

3 p; k6 Y6 l. |1 ~0 g. s上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。
& z9 n( Q# `8 i( V! I$ v8 I8 w/ W* e* Q, Z
c) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。
! q3 \3 j. s" R+ ?% Q6 H4 I9 G
  m6 {- m4 T# l) P$ g/ R
  1. import json
      A! ?9 t9 ?3 p- O
  2. from web3 importWeb3, HTTPProvider+ J! [; Z4 P- g1 P$ B
  3. from web3.contract importConciseContract
    1 D9 K" |% n. [: r0 g" F" T" M
  4. # web3.py instance
    6 ~( t; X9 }9 B/ V& M
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))
    / s( A: U1 \1 X
  6. print(w3.isConnected())* j( w( Z$ }! R7 h
  7. key="<Private Key here with 0x prefix>"
    + W) b4 P9 ]1 p1 I' Q6 V* o) ^
  8. acct = w3.eth.account.privateKeyToAccount(key). t9 R/ w! \5 ~0 ]  x# k9 X$ A
  9. # compile your smart contract with truffle first0 t. L6 H/ [0 Q, l( b) A$ N, ?0 z
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))/ X% z0 I. r8 f# ?: C( J
  11. abi = truffleFile['abi']
    / W, Y% K% X) m5 j- K9 p
  12. bytecode = truffleFile['bytecode']! f7 [1 i3 g0 i5 q' {9 z, p/ p
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi)9 b: I$ T" z$ S% f1 }% W# Y
  14. #building transaction
    - M& }/ f$ t* J6 ~
  15. construct_txn = contract.constructor().buildTransaction({
    ( a# Q' L" f1 a0 B/ h. O
  16. 'from': acct.address,
    - M2 j7 w6 ]# ]  S) @
  17. 'nonce': w3.eth.getTransactionCount(acct.address),4 A3 b+ L, E3 _
  18. 'gas': 1728712,2 {) Y  g8 v3 [- B4 I' N
  19. 'gasPrice': w3.toWei('21', 'gwei')})  M: q5 g7 r8 d/ j* j1 P; e" X' u
  20. signed = acct.signTransaction(construct_txn)
    - F  q2 E9 l' a+ Y
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)
    $ j- _" m- [* n8 R! ^8 t
  22. print(tx_hash.hex())+ W0 Z$ d- ^1 P6 a, L
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)
    ' n6 d: Z* y8 n, s5 S
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码
: C/ C# D* a5 x5 k6 o4 C; Q+ q

6 t) ~/ @" u; V% [" t. V
( U. l! B; \2 h1 D' O9 o这是我所做的:# O+ P6 ^# V8 C0 M* K' x4 A
- @4 V. n1 q8 r7 ^0 U9 b
导入的 web3 库和所有其他必需的模块
/ E, |9 C1 U% i5 g& l通过指向 Ropsten Infura 节点启动 web3 提供程序( Z" k: S% Q5 o/ m; U% |- m
添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。
% S, H) ?" Z6 X! z8 k( f通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
; d' z  V- W/ I# N) b2 X/ a7 B添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。
! _) `, Y  l5 _; B# N; p4 ~3 C; N使用我们的私钥签署交易并在网络上广播。
& D3 \4 _; \, E! r% n* Z在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。* p, u- c" c; c3 s' h1 K
2. 向部署的合约发送交易
' Q! e& q7 I4 V6 W5 }! u, o" [; d
在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。1 z/ ]7 f2 U. S0 h: }
  1. import json2 |9 E7 ^* k  S
  2. from web3 importWeb3, HTTPProvider$ x" r8 `0 \, ~8 p
  3. from web3.contract importConciseContract
    & o) {4 U) x3 y* P
  4. # compile your smart contract with truffle first( O# Q, {/ ~5 g
  5. truffleFile = json.load(open('./build/contracts/greeter.json'))
    / \. @5 B" M% B5 K2 V
  6. abi = truffleFile['abi']
    : c3 @% h) f% t. L
  7. bytecode = truffleFile['bytecode']
    * t$ q4 W; }4 l+ g0 K5 j' K
  8. # web3.py instance
    : G, w# V9 A1 _- C) f# k% r9 l! w# ^
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify
    3 q, g; |+ _( X4 e2 t
  10. print(w3.isConnected())
    . J8 q5 ?! K8 j" Q- P
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify7 m& w  J4 f1 F6 g2 m
  12. key="<Private key with 0x prefix here>"#modify
    2 h+ ?% k" Y, a4 `4 ~3 y, J- @. V
  13. acct = w3.eth.account.privateKeyToAccount(key)
    3 K8 b/ f% B2 M/ K
  14. account_address= acct.address
    # R- V7 i$ ~! H- m5 e+ U
  15. # Instantiate and deploy contract- K% U3 j. o, ~0 }& {
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)7 ~6 e' R  t: ]1 z7 E
  17. # Contract instance- m+ D% l- ]5 \0 Q. I  W8 i) ~- w
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    ' O- D. L$ Z7 A" ^9 l* A
  19. # Contract instance in concise mode/ L8 ]+ D- q8 J
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    $ z" r# i, e$ _3 m/ r
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})3 n4 l# e: h, |0 n& B, E; X# Y/ c; _
  22. #Get tx receipt to get contract address
    5 m3 X1 _% y& a: `  x
  23. signed_tx = w3.eth.account.signTransaction(tx, key)+ @( }! H( v) G5 L& n% M& T
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
    / d$ i9 h! h1 {/ T+ O* b4 U& B
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)& h* R# E4 t) O! D* I0 ~
  26. print(hash.hex())
复制代码

; i7 \8 L# u; A1 l9 n! I5 T6 U/ U
$ y- F+ u# O* H+ Y3 ^
$ T+ h3 W. l+ M0 [* n/ e3 _这是我所做的:
% k7 k0 m6 q2 Y# d& n. o1 O# |0 p* c" F; R, H( K
导入的 web3 库和所有其他必需的模块
* G/ Q* J/ i5 C; w+ T' A0 ^* r通过指向 Ropsten Infura 节点启动 web3 提供程序
) d# g0 [# `- _& C# j1 ^% x* l添加了用于签署交易的帐户地址和私钥" z, h( r; M& i+ n4 f
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
7 D& m( C$ P& I+ A1 u% N创建 tx 对象以添加问候语“hello all my goody people”并建立交易5 \  q  q8 B7 F
使用我们的私钥签署交易并在网络上广播。
: S% ]% R, N" u1 f在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。2 ]2 E4 ^2 _. h9 ~4 }" ~
3. 从部署的智能合约中读取数据
1 R, o; l. r9 k, ^( c# _% G' Y8 ?1 u' ]2 \  \, u
在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。. D$ Q1 z4 `: r6 d* J/ c8 M
  1. ! z& E" A! h& x+ s2 |- D
  2. import json/ \3 C1 C1 C( _2 t
  3. from web3 importWeb3, HTTPProvider
    - V4 }! U# n. f& t# @8 }
  4. from web3.contract importConciseContract/ S2 K! z7 l, _- a6 v8 m
  5. # compile your smart contract with truffle first* J9 f3 E" z) C: N
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))
    $ a6 [- a9 [3 ^, v1 E% j
  7. abi = truffleFile['abi']' C, Z; G7 x8 p, {0 M0 o
  8. bytecode = truffleFile['bytecode']
    0 Z5 t* k4 w" A) t8 G; L3 o7 e
  9. # web3.py instance
    , C, R0 d; W; t% L9 K; i% |
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))
    6 t: R! {2 Z" Q5 k% }
  11. print(w3.isConnected()). I- j- J& E; w) I3 i# b6 o& J
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")
    6 [  ~0 J5 m' y8 Z3 a9 K" o
  13. # Instantiate and deploy contract& }5 G5 r! B$ z0 P1 |8 m6 O
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)+ K3 P1 A2 _6 N8 i
  15. # Contract instance5 D0 V; T% i0 ^  [0 N8 y
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    3 }( P$ @0 y& @! j( q; P5 y
  17. # Contract instance in concise mode
    6 |3 k5 q  R0 S7 c) e
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    & C  [/ f* Z+ `, u$ _4 v( J
  19. # Getters + Setters for web3.eth.contract object ConciseContract$ |4 B& A7 G9 J- {
  20. #print(format(contract_instance.getGreeting()))) `: M0 k+ j3 u4 G
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码

- |( u; o0 C0 T7 N- M. w, R+ G% W. X" y1 T( a9 R

) i. E3 P6 }  h6 C这是我所做的:' h4 o7 \  q! @. g$ y& X

, O# D& [" Q# \5 y. c8 W5 D3 f* g导入的 web3 库和所有其他必需的模块, B2 F4 N% m; S7 J% ~
通过指向 Ropsten Infura 节点启动 web3 提供程序
) h8 y& ^, j! q1 P8 o" K- v通过指向 abi 和 contract_Address 创建合约实例(来自上一步)1 M& d' X7 w: y
调用 getGreeting() 方法并在控制台打印结果
" G, J% y% ?' c3 o结论/ t# B8 v0 P1 Q& l8 p0 l, q

5 k  B' Z" d) C# v& K您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。
) C6 K& G$ A4 i0 V, {5 M, m& C3 \8 t" u/ @. T
2 h- m8 P, A' [8 v. t
参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程5 J. ^$ E5 V4 z5 E. u8 [* J. p7 T
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13