Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
2703 1 0
什么是 DApp5 h  e+ F1 [& n" \# }

+ @3 L9 c8 h8 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 库与区块链进行交互。
8 K0 l% i& e0 D8 t* X: P" E* n# S0 x2 U4 j
Dapps 开发包括三个简单的步骤:
4 ^2 c) A/ l) B+ Z  c8 w
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约, s( {. P5 A8 ~- z
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。' f8 |, H: T# I8 s2 r% x

$ C( x3 P+ @( g) t: R9 y  }+ a; m安装2 }) c# E9 T6 Z# h2 l9 F9 e4 i- C

- ^1 `4 ]) d& y; q; d6 VPython 2.7 +
- ~# P' X+ u: k! Q# ]3 c$ K% c9 CNode.js5 l. Z0 b& J+ v, A7 A' N$ _9 L# c
Truffle
8 x. q* q) c) k# c" A8 b/ h( G( _
% t' T- K1 q$ o& W  ^3 p# L; w" w, N+ }' p; R0 }4 k
npm install -g truffle9 p" \; R+ u3 k4 h1 q
Pip
* L& c4 S) W9 a% `npm i pip/ d: B( P. M5 ]! L/ x- k
web3.py
/ \2 Q# T: ]4 E6 R' `" S, {pip install web36 o  h+ ]4 s/ b# k- `/ V1 [
- b1 f9 w$ M3 X0 ?1 X6 X
! B1 |; E: q5 [- [
Infura 项目 API7 x  `& ]4 z4 U  e  {
前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。
; \! M2 h9 X  f: ~& g5 y, c# I% F: S
智能合约: N. L/ @1 D7 C( q+ c

; O5 g6 l/ k$ B0 |每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。
" s; c8 N  ~$ F, |$ `7 u( e, x) O7 k; t, u! n
  1. pragma solidity ^0.5.7;. p8 L- \' m7 ~4 y% f( f
  2. contract greeter{
    3 H' j5 `4 N; }
  3.     string greeting;
    : Q4 B0 E" }. m
  4.     function greet(string memory _greeting)public{8 o, D4 ^8 o$ J# ^
  5.         greeting=_greeting;
    ' z$ I3 [+ j( i. X
  6.     }" {6 t- x; b% C, K$ ?1 Q* s6 T
  7.     function getGreeting() public view returns(string memory) {$ }% @: Y/ j+ z
  8.         return greeting;; d6 J- @% o$ p) Y. h& l2 n
  9.     }( E3 X6 y. E0 R* J
  10. }
    1 t3 _9 k8 {: e
复制代码
- p0 u; h+ ~" x- {4 {. Y" T

6 P: b% j0 s5 i! `5 A您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。
9 l" X% A+ z; y( v; e9 g. ~) L6 ?( k5 ~" a
1. 在区块链网络上部署智能合约
8 z; i2 T! ?* q) L0 x* @+ [' m9 ?8 R* n9 [7 `# e' W  }% ]8 s% L$ `
a) 创建项目:9 R/ E9 t) B/ Z. [5 B: [
3 B8 Y5 c5 D$ k
mkdir pythonDapp
$ T1 L! U" I, R* D* r3 s1 |cd pythonDapp
- T1 b; |  ^) ^4 B' rtruffle init2 J* B; C$ V$ Y% i" D
* k, M+ I3 M$ q) y
2 }4 m' P0 x# C  q" G
成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。
2 G0 @6 P0 B( t6 @' Z/ h( i+ `. C6 f
b) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:1 P# q& c8 e5 m% S" F' T! m+ X
% r; M& `' C7 G! V, i

- _8 K! q! u8 ?1 W8 n: T3 W
) p. \9 N0 Z5 i- K: s* f6 dtruffle compile8 F: U4 Q9 y8 L2 [& L. ~
(or)
# r0 e. u6 K+ otruffle.cmd compile #(for windows only)
: T& g" K) Q6 L* L9 {" V
9 {. M( ?' ?. Z* L$ W/ C; R, y4 P. O3 l9 Q- a* C8 l7 C
上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。. R+ k; N+ d6 e# i: [+ z& e
$ F* W( N- _2 k0 q! U8 g( S- j
c) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。+ Y: H( o+ K& ]' Z7 ~. f

/ g/ U" z+ y* p
  1. import json
    ( b2 ?. r, Y- a' j+ V. B
  2. from web3 importWeb3, HTTPProvider0 @; C! z6 }- q" ~3 D3 Z" V/ i
  3. from web3.contract importConciseContract' t+ e0 M; i8 {) `& |
  4. # web3.py instance
    + W& P9 C$ Q* X5 q! x
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))7 W: X# N# S1 D" o2 M$ r% J- O6 r+ y
  6. print(w3.isConnected())9 A( N* \4 G+ y- W
  7. key="<Private Key here with 0x prefix>"
    % F1 J/ Q2 Z6 _6 a7 V! f- q( T
  8. acct = w3.eth.account.privateKeyToAccount(key)- V" e  h2 e3 _
  9. # compile your smart contract with truffle first6 Y% Y3 ^+ v) \2 Z
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))
    ; [$ m6 w6 W- J# |7 v9 ?
  11. abi = truffleFile['abi']
      I/ k: H) r# f
  12. bytecode = truffleFile['bytecode']! t* t' g7 b6 `, e7 u% \" e
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi)
    * S7 q9 A7 {  z
  14. #building transaction, X' V; b# S1 P- C( [% E2 t4 \
  15. construct_txn = contract.constructor().buildTransaction({
    8 S, \" Q* j, m" n
  16. 'from': acct.address,( A$ q- ^# e" _, r4 j. y! d$ C1 _
  17. 'nonce': w3.eth.getTransactionCount(acct.address),
    8 L3 V2 ~4 ~" i# }8 M+ K* ?) t
  18. 'gas': 1728712,, f  e2 z+ }! R! c( w. p5 U
  19. 'gasPrice': w3.toWei('21', 'gwei')})% \4 b, t, O7 k  f0 C
  20. signed = acct.signTransaction(construct_txn). q; R( t$ M; y/ R/ ]
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)
    , j$ K+ y1 {+ j
  22. print(tx_hash.hex())1 D; c$ `" L  g+ r
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)5 D8 M; b0 h. T* i& [
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码
3 n: k' A0 k& O2 }3 {: f

7 x( N4 Z8 B! o& ]
$ H: K8 c* D3 Q# j5 ?  b这是我所做的:/ R9 ]5 s/ ?: N: \* K
- W2 b. H7 @; W
导入的 web3 库和所有其他必需的模块
, }8 i0 g: ?- X, u6 V/ o) V( u通过指向 Ropsten Infura 节点启动 web3 提供程序
/ x) B5 W  O5 C$ B5 E添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。* K0 L* A. t$ D2 y5 }2 T
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
' Y0 M) K  \5 {  J4 n添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。" a/ k$ n: M5 B6 I
使用我们的私钥签署交易并在网络上广播。2 f' P4 F+ o& ^- p2 B. {) |
在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。& x6 e. L8 r- A4 D7 t% [& a+ s; j
2. 向部署的合约发送交易
9 N7 q8 C: r7 s# v, X
' ^5 m7 |0 X( V在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。8 F) V% r3 A, P6 f  s  D6 v# k0 M
  1. import json8 U' h3 p+ h8 t% c; d3 [$ {
  2. from web3 importWeb3, HTTPProvider4 t3 V+ C2 H, \8 }4 f
  3. from web3.contract importConciseContract
    ! _$ o2 X9 r% }
  4. # compile your smart contract with truffle first. N+ }( w: \4 r
  5. truffleFile = json.load(open('./build/contracts/greeter.json'))% L: J; O% g6 `. a; o
  6. abi = truffleFile['abi']8 e4 `# }$ c* Q7 s/ d) G' y$ `
  7. bytecode = truffleFile['bytecode']
    $ g. P$ D# c+ Y3 E. `4 D% @
  8. # web3.py instance
    * w! A+ Y! ~9 V7 D
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify
    , z5 A. c' r- A( n$ ~
  10. print(w3.isConnected())7 y# m+ U: v( \6 D. {2 Q2 J1 M
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify
    / z3 t) u( |7 t3 h! H0 @
  12. key="<Private key with 0x prefix here>"#modify
    $ e! Q: H: A9 p1 l$ p8 c, I
  13. acct = w3.eth.account.privateKeyToAccount(key): C- l' l4 Q/ M/ I! v- ^( b! H. k
  14. account_address= acct.address/ i, _+ B' K. O# x& h
  15. # Instantiate and deploy contract
    2 Q8 H$ C* d6 V1 q. @. a
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)2 B. }: @0 j9 J  [6 r
  17. # Contract instance" D* i4 K2 F6 {7 u) h* j/ l5 T2 ~# t8 P
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)7 c* |) q3 T4 X5 a% O
  19. # Contract instance in concise mode
    + W* b; p6 H6 ^# k( p/ L' h1 Y
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)
    # c2 t9 L7 O1 M6 V
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})5 P; {5 A1 X8 e" }! v  V
  22. #Get tx receipt to get contract address% M& Y/ n7 e$ i0 K, Q' w1 d
  23. signed_tx = w3.eth.account.signTransaction(tx, key)
    & I! D, I  y3 v* o  {- w# Y
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
    / [; w, }6 ^4 g/ Z' K% L
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)2 k+ E. `( U: H* p2 U
  26. print(hash.hex())
复制代码

+ N1 g  U/ _+ O% w9 z* [
& i& Q3 z9 ?; I( P9 L0 _4 O8 }- Q. ~4 h1 p% m1 o' Y) P4 t3 P
这是我所做的:* W9 N+ H6 e1 x6 z

: Z1 j5 r7 u- l3 _2 ^2 t导入的 web3 库和所有其他必需的模块/ k4 C9 U1 @. d, X' d' D2 x
通过指向 Ropsten Infura 节点启动 web3 提供程序
1 C2 q7 q; g: q7 ~' z. O添加了用于签署交易的帐户地址和私钥* ~# p9 J0 R2 ^% w4 Y9 R
通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
% |2 v, ]! |6 `3 R9 O创建 tx 对象以添加问候语“hello all my goody people”并建立交易" C& P+ n$ H" a8 G! J. h; |
使用我们的私钥签署交易并在网络上广播。
5 ]+ M. f9 D) Y! U+ t在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。1 z- o, x! s6 \8 G; J9 t
3. 从部署的智能合约中读取数据
6 L4 S3 F) c6 j0 R
9 m9 h; O0 j- Q) F' }7 ^' \9 u: X在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。
  z) t9 Z6 z; U1 r5 @/ G
  1. $ W4 P' j0 T4 P# y
  2. import json
    & `3 r( \) k! M, f- d
  3. from web3 importWeb3, HTTPProvider) y# ], V+ H6 c* I( N- y( T5 J
  4. from web3.contract importConciseContract
    , N6 a2 V& U0 y: }5 D9 J7 U  U& t
  5. # compile your smart contract with truffle first
      ?" u( s2 \# m7 V: s& s" O+ R, P3 S8 C4 a
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))* w7 O6 n% B. u9 ?. F9 v  O/ M
  7. abi = truffleFile['abi']: S% w1 z' z5 I( V( e# f4 A
  8. bytecode = truffleFile['bytecode']  K. t+ H5 O9 M3 ~1 \$ c. T
  9. # web3.py instance
    ' V9 V( W0 e8 @% v0 M6 e; `
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))# v. Y( o, Y7 Y! i
  11. print(w3.isConnected())
    $ j5 i2 i, o' Z& s
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")
    ) K0 i, ]- L: S
  13. # Instantiate and deploy contract
    ( _4 I! Y% ]9 G! B5 B! Z5 |4 Q
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)! b5 f2 H6 |% E1 ]' I2 m
  15. # Contract instance
    / v" p2 b, f9 b% K+ W7 G8 O
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)( J6 L% N) M; ~9 d2 `) F9 G. k
  17. # Contract instance in concise mode- w2 n0 F' o$ o# T
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)4 Y9 h2 \. [+ G% S1 Q1 x0 [
  19. # Getters + Setters for web3.eth.contract object ConciseContract! @  F" Z' Z4 G+ m7 k& g
  20. #print(format(contract_instance.getGreeting()))
    . X9 `# N  X* O) `( T! _4 \
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码

2 a' Y: _! E" h1 p4 a0 {! b2 j$ P, _2 u
. ?; |( \9 T# J4 }( z
* C: T: \/ J6 P: P; e9 E这是我所做的:
0 R  b0 H: ^  D/ h- M& m4 \+ |5 I
导入的 web3 库和所有其他必需的模块
9 E( ?( O( Q* t7 Y8 n通过指向 Ropsten Infura 节点启动 web3 提供程序0 R( e- S% N5 n% w: [4 m; q8 g
通过指向 abi 和 contract_Address 创建合约实例(来自上一步)
% g0 C- i5 S; N1 p9 K/ ]; a4 E调用 getGreeting() 方法并在控制台打印结果4 M1 W0 c, H6 A4 N" Q7 |3 s% Z7 r' M
结论
* X% e+ y4 r: e! k" F9 f5 N3 \8 Z0 c# T+ t% N( y5 ?) `2 {
您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。
9 ~: I- r- d4 `; u) O& i5 C6 y  |& k) o6 @6 a5 n

& S5 J( x# e6 v8 I参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程
$ e. }. ]7 m3 r2 z; x
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13