Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

用 Python 中的 web3.py 库开发 Dapp

常德小学生
1290 1 0
什么是 DApp; s. n+ [: l" r; J0 N: E  F
% H* p* T) Q( G2 R2 C2 o+ \
“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 库与区块链进行交互。# Y2 A& w. A( R( n+ P' n9 ?* v

3 W' F9 ~& \7 A% s1 aDapps 开发包括三个简单的步骤:
$ s6 _4 T6 ?5 l8 `
  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约
    . s1 E" H7 p  y6 p
我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。& t" q0 f$ ^' Y6 X: ~+ l% [# P  s
6 D  k( Z' X  i9 ?- V6 ^
安装4 z" r; c; H* L4 Y4 J! R

( [& o$ y! w  k9 Y  jPython 2.7 +
( D! K+ }. I( Y: T+ z! UNode.js
  X, U: S' @0 D* s0 e+ D& eTruffle
8 O" \# _) p  k6 Y8 O, s9 N4 M
* C0 t5 g9 N3 Z1 d% o# E7 N4 D4 c+ S0 r/ E& x
npm install -g truffle* Z4 D) \- Q4 K2 M) w' s) L; C0 |
Pip
9 `* a5 l+ ]+ Nnpm i pip
. F! X# S# X/ Pweb3.py
1 l4 ?- @$ e- a; X+ E! F- g% y: `# ipip install web3  r2 b# b0 d/ c

* C+ r5 e& {9 F; i. h
4 ^3 ?& ]# H# v' a3 zInfura 项目 API
% l) ~6 F7 e5 B$ m* {- W前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。
' O7 r0 U5 K0 ]: l/ z$ d% K3 [6 V6 O8 C! i+ U0 S! e
智能合约
3 I* ^  M" S' c) `: Q6 n; S! b3 c& L
每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。6 @- M- f1 j+ n3 E0 d- \

/ ]8 I( F( ^" L1 n
  1. pragma solidity ^0.5.7;
    % F7 x$ k. Y) }" r
  2. contract greeter{
    # |. M. N' X" l& i
  3.     string greeting;7 t& v$ S. R. g* a5 B0 @% y
  4.     function greet(string memory _greeting)public{  u4 v  G/ t' p# H8 U8 v) K# ^
  5.         greeting=_greeting;
    5 _, u* ?# l3 l) U
  6.     }6 g5 X, m# F/ f
  7.     function getGreeting() public view returns(string memory) {
    $ W% \! e7 [9 g
  8.         return greeting;
    : E: M" w" E% N% v! ^
  9.     }0 M8 M; S) w! p2 N( ^
  10. }+ ]5 z7 `: Y# S. y; v( P& P
复制代码

1 n) x" A0 ~( |+ G5 T1 Q4 d2 x3 L8 L, \9 P
您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。% l( P! k+ S( d. C: j; N: N

7 F7 W+ t, A3 B, d: n3 Z/ L9 ?1. 在区块链网络上部署智能合约1 y* ]) d% O& _  g4 `# R% Q
4 B! {2 D7 h9 @2 {3 x
a) 创建项目:
3 S2 e, c% C& k# g( E0 h# ^8 u) x% W' j" ~$ i( a' S' [! ~/ U
mkdir pythonDapp- T% K' z: |" u/ V/ f# m. N; {
cd pythonDapp5 u7 T. L+ G2 K7 @2 @
truffle init2 S6 f( _1 q+ w5 n

5 {% S0 B1 N. {! _4 d  f3 Q  `  O- I/ x: l6 y
成功初始化项目后,转到您的文件夹并在 /contracts目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。
4 c) |6 s9 N% S4 @8 s# {/ c( W# ]" D& g! f- |( K, j
b) 智能合约的编译:因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:
4 g+ q6 x" G  Q! r
8 c4 ?+ d& S: F" B9 f
4 @" Y0 p" i+ i$ w5 U
5 y0 n# u2 }2 P/ w$ w& {4 ztruffle compile- a/ _! c& y: p4 l
(or)# U, u7 V$ y' R2 W7 Z2 p
truffle.cmd compile #(for windows only)
+ A8 D' o4 ?; i0 n4 [
; a; Y6 k0 Q2 P% {* b: v3 A9 k6 ^% I1 Q( h+ D: t, }5 x
上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json。
' v4 V7 z4 W# Y% M2 V
4 ~# y% B4 t8 }c) 部署合约:打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。- r, x( }+ m% v" m! H  K! D
' _* Q1 E; f+ {* O7 ^1 N& `
  1. import json. x1 f" ?: f# ]7 H% ]
  2. from web3 importWeb3, HTTPProvider5 I! g# R% d- j+ ~( {" x7 Z
  3. from web3.contract importConciseContract
    3 v6 V! g1 n5 T8 R" k* G/ p
  4. # web3.py instance
    , r, n- c* N3 E1 p0 H9 K
  5. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))- i% |* Y, G* w1 f! K
  6. print(w3.isConnected())
    7 ^6 E3 O+ f$ B0 D! D0 I" I  f
  7. key="<Private Key here with 0x prefix>"! h( o/ N* O$ k* X  k  }
  8. acct = w3.eth.account.privateKeyToAccount(key)
    ' h  a: {1 Y% I9 O- W
  9. # compile your smart contract with truffle first1 ^0 a$ {" o- O; _6 v$ |$ J. J% L
  10. truffleFile = json.load(open('./build/contracts/greeter.json'))
    ; o9 i6 _1 \! w. ~
  11. abi = truffleFile['abi']3 i) @' U$ [; Y" w! |+ D3 I9 D
  12. bytecode = truffleFile['bytecode']* Z( q2 S7 b8 I( X
  13. contract= w3.eth.contract(bytecode=bytecode, abi=abi)
    - a+ ~3 N; g$ e( j: r+ L( {6 y
  14. #building transaction$ e6 f* [6 y# U5 a+ d! Q# T! h
  15. construct_txn = contract.constructor().buildTransaction({& r" m% v8 T- O- E" `% e
  16. 'from': acct.address,) t6 R& c9 c( T$ }
  17. 'nonce': w3.eth.getTransactionCount(acct.address),
    % k' \4 c6 [9 p& q% K* r/ V
  18. 'gas': 1728712,  @' F% R; |0 |0 m3 Q" ]1 R9 X4 |, v
  19. 'gasPrice': w3.toWei('21', 'gwei')})
    6 V" _- b0 c, d" V% U0 D/ @
  20. signed = acct.signTransaction(construct_txn)
      z: K- a+ Z$ i
  21. tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction). g( x9 c* a- O& M- ?
  22. print(tx_hash.hex()), `- F  ?% g3 I- F: t
  23. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)) L8 r& E: E1 Z* c7 k6 @" l
  24. print("Contract Deployed At:", tx_receipt['contractAddress'])
复制代码

% l1 o# Z4 _0 g: w$ }
' ?' j7 o7 P+ [% k  E  c7 g6 D
# D# @5 w% I; n  Z* L% s' K这是我所做的:* ]2 W: g3 J( |
8 n; S6 T& N  N4 O7 U
导入的 web3 库和所有其他必需的模块
5 w4 H- Y8 A/ U8 N通过指向 Ropsten Infura 节点启动 web3 提供程序3 p  T# H8 B# t  r; j$ {* D
添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。
" w) K8 P# {, h  t6 P通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
4 y$ V" h7 k0 H6 Y, n添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。
0 a. q5 S3 F+ O, I' \使用我们的私钥签署交易并在网络上广播。
( K; G  F  a" D$ K- a/ E" T' p/ g" Q在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。- v! n5 }, M! W
2. 向部署的合约发送交易+ |1 g! N* O5 k* L

' ?" _5 q  K; _/ y( A" K0 i: X在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。  i; q; l: \7 C" p
  1. import json
    . U4 |2 K* w- E
  2. from web3 importWeb3, HTTPProvider
    # I$ G& [( n8 @. I8 K8 b' a
  3. from web3.contract importConciseContract5 v0 J0 L- b3 n
  4. # compile your smart contract with truffle first
    9 [3 ?. b% H4 S. c! `
  5. truffleFile = json.load(open('./build/contracts/greeter.json'))
    0 w# s# l* ]# v: `0 g% @/ u
  6. abi = truffleFile['abi']5 E9 O$ j8 T' |
  7. bytecode = truffleFile['bytecode']
    . e" I. P; i. F
  8. # web3.py instance
    ) C+ U* p+ ^3 j8 H! h( C- s
  9. w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify
    3 F/ s+ ^" T! @. o# a0 S
  10. print(w3.isConnected())
    $ H- n! {0 G1 z; r
  11. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify" _1 r' c8 {! f* u7 w
  12. key="<Private key with 0x prefix here>"#modify
    6 J% S7 w. R) [( q/ d
  13. acct = w3.eth.account.privateKeyToAccount(key)
    , g9 T5 o, K1 D( h+ u8 X1 [" F
  14. account_address= acct.address# Y3 x% o+ [: S, B1 B
  15. # Instantiate and deploy contract# m  q- q4 k/ w
  16. contract = w3.eth.contract(abi=abi, bytecode=bytecode)
    ( e9 y  \3 u' s) F" U! J8 ]5 P
  17. # Contract instance
    % s" @% G2 _0 D( F! k
  18. contract_instance = w3.eth.contract(abi=abi, address=contract_address)
    ' R/ v, }% n. g
  19. # Contract instance in concise mode
    8 q5 m/ I( w3 T( G+ y/ x# N; `) m( @
  20. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)3 o) |( I# y, P0 P
  21. tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})
      A: f# q( |! Z  f+ Z0 E  u
  22. #Get tx receipt to get contract address3 \! `3 k7 w4 R$ q9 N0 o+ V$ E- z
  23. signed_tx = w3.eth.account.signTransaction(tx, key)3 p$ ?/ ^" v: [1 _' U
  24. #tx_receipt = w3.eth.getTransactionReceipt(tx_hash)
    ' c' D7 @. o$ w' h8 L: M6 [
  25. hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)
    ; B7 o7 N5 j. S, j
  26. print(hash.hex())
复制代码
: `" |/ ^2 C) [+ F$ E& j

+ R; Y$ z3 C, Q8 W0 x9 Q. K
3 a2 @2 A/ Z. b; a这是我所做的:4 Z' ~- c0 s* J, j9 s+ I
+ x) Z) `  v$ a  m& F  p
导入的 web3 库和所有其他必需的模块
: _7 k0 K; R; N! t$ o1 ]: E通过指向 Ropsten Infura 节点启动 web3 提供程序) N* B' x: z( U
添加了用于签署交易的帐户地址和私钥
) L" i/ r6 O* V" s, t通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例9 C  Z, O5 p1 L# j- t% y, J
创建 tx 对象以添加问候语“hello all my goody people”并建立交易
9 ~1 Z+ T) I+ V$ H3 R3 O, j7 r使用我们的私钥签署交易并在网络上广播。
! }1 t4 H; W# W1 R+ o* j/ e在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。
4 M; \9 B0 m) X& X) B' Z* U/ x3. 从部署的智能合约中读取数据
, o* l7 G7 A9 \( p5 @8 v+ S8 {% h" _- W) _7 D3 c, }7 O% D
在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。
; b/ l6 p5 W8 C6 O
  1. 7 x. i  a2 j+ ]
  2. import json8 M% i5 [- |% }( F7 V& {" ~8 m4 U
  3. from web3 importWeb3, HTTPProvider
    ; ^- p. e4 @3 l! j" `9 u! B, k
  4. from web3.contract importConciseContract8 t. }' i" B5 G5 o
  5. # compile your smart contract with truffle first7 |8 ~6 x- A+ b
  6. truffleFile = json.load(open('./build/contracts/greeter.json'))8 J; M6 K& T0 V4 L9 M
  7. abi = truffleFile['abi']
    % b; {5 R4 K+ R7 E+ {8 f  E
  8. bytecode = truffleFile['bytecode']6 w- L( v5 v" k4 z- k/ h
  9. # web3.py instance
    " l  D0 y- H# G0 i
  10. w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))6 T# l) z) V. D/ n1 K) _
  11. print(w3.isConnected())4 j( a, E% M& p) v; }$ b1 G$ r
  12. contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>"): {( M  [% _+ Z
  13. # Instantiate and deploy contract
    + V& h( H+ C6 q$ Y- x7 E
  14. contract = w3.eth.contract(abi=abi, bytecode=bytecode)4 M5 Q* p7 c4 \
  15. # Contract instance6 D3 I( z7 t% L6 l
  16. contract_instance = w3.eth.contract(abi=abi, address=contract_address)- G) c( f4 y7 K4 D+ Y- [
  17. # Contract instance in concise mode
    2 p8 R6 G1 G) [( Q4 l+ K0 C) n1 O
  18. #contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)9 N9 F  J1 o+ k" L3 Q  l6 ^- G
  19. # Getters + Setters for web3.eth.contract object ConciseContract
    + R7 \6 g6 {6 t$ }+ v3 @# @
  20. #print(format(contract_instance.getGreeting()))
    ' |% E$ W6 ^7 R9 I
  21. print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))
复制代码
3 X, f# ^" I) N

) u$ Z5 w6 I9 m/ L& H* W
4 d3 w9 H( k: x3 U) a( R: @. e! w这是我所做的:) l' P% b1 \* B

4 {! @) }/ h6 b+ ^9 J导入的 web3 库和所有其他必需的模块. N- C. D" q- t: u1 m5 b* p
通过指向 Ropsten Infura 节点启动 web3 提供程序
* ]& l/ X9 m+ G1 a; v4 X通过指向 abi 和 contract_Address 创建合约实例(来自上一步)$ O. c% x4 ~# U. n% p; U3 c
调用 getGreeting() 方法并在控制台打印结果
' S5 n- u2 J/ n" S5 h$ Y9 P结论5 n! L! B; y; p6 k( B# H8 \0 t
" ]( g2 Z' N- W3 O9 ]! g
您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。
# H. x$ S& ^- c1 w# y2 ?5 m4 q9 t# N3 l1 ^' v- j
5 w9 f7 l+ W* L3 {' Z5 \% L
参考 @温室小书生室dpython利用web3.py开发以太坊应用dapp的实战教程  H& L1 ]. h1 m9 [  G
标签: Python Python Python
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

常德小学生 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    13