用 Python 中的 web3.py 库开发 Dapp

开源镜像NoSQL容器

picture.image

什么是 DApp

“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 库与区块链进行交互。

Dapps 开发包括三个简单的步骤:

  • 在区块链网络上部署智能合约
  • 从部署的智能合约中读取数据
  • 将交易发送到部署的智能合约

我们将在带有 web3.py 库的 python 环境中一步一步地进行这三个操作要与区块链交互,我们必须连接到任何完全同步的节点。在本教程中,我们指向一个 Infura 节点。确保你有一个以太坊钱包(使用 Metamask chrome 扩展或 myetherwallet 创建以太坊钱包并安全地存储你的私钥)并在其中添加一些测试 Ether 以进行操作。

安装

  • Python 2.7 +
  • Node.js
  • Truffle

      1. `npm install -g truffle`


    
  • Pip

      1. `npm i pip`


    
  • web3.py

      1. `pip install web3`


    
  • Infura 项目 API

前往 Infura 网站并注册。创建一个新项目并复制 Ropsten Infura RPC URL。我们将把我们的智能合约部署到 Ropsten 测试网络。

智能合约

每个程序员都用他们最喜欢的编程语言执行了一个“hello world”程序,以了解运行该语言的基础知识。这是我们使用 Solidity 语言编写的简单的“hello world”版本的智能合约,我们可以在区块链上添加问候语并检索它。Solidity 是编写智能合约最常用的语言,它编译为可以在节点上运行的以太坊虚拟机上执行的字节码。


      1. `pragma solidity ^0.5.7;`
2. `contract greeter{`
3. `string greeting;`
4. 
5. `function greet(string memory _greeting)public{`
6. `greeting=_greeting;`
7. `}`
8. `function getGreeting() public view returns(string memory) {`
9. `return greeting;`
10. `}`
11. `}`


    

您可以通过传递字符串值使用 greet() 方法添加问候语,并使用 getGreting() 方法检索问候语。

1. 在区块链网络上部署智能合约

a) 创建项目:


      1. `mkdir pythonDapp`
2. `cd pythonDapp`
3. `truffle init`


    

成功初始化项目后,转到您的文件夹并在 /contracts 目录中创建 greeter.sol 文件。在网络上部署合约之前,我们必须编译它并构建工件。

b) 智能合约的编译:

因此,对于编译,我们将使用 Truffle solc 编译器。在您的主目录中,运行以下命令:


      1. `truffle compile`
2. 
3. `(or)`
4. `truffle.cmd compile #(for windows only)`


    

上面的命令将在 /contracts 目录中编译你的合约,并在 /build 目录中创建二进制工件文件 greeter.json

c) 部署合约:

打开您的 Python IDLE 编辑器,并在主目录 deploy.py 中使用以下代码创建一个新文件,然后在您的目录中运行 py deploy.py。


      1. `import json`
2. `from web3 importWeb3, HTTPProvider`
3. `from web3.contract importConciseContract`
4. 
5. `# web3.py instance`
6. `w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>"))`
7. `print(w3.isConnected())`
8. 
9. `key="<Private Key here with 0x prefix>"`
10. `acct = w3.eth.account.privateKeyToAccount(key)`
11. 
12. `# compile your smart contract with truffle first`
13. `truffleFile = json.load(open('./build/contracts/greeter.json'))`
14. `abi = truffleFile['abi']`
15. `bytecode = truffleFile['bytecode']`
16. `contract= w3.eth.contract(bytecode=bytecode, abi=abi)`
17. 
18. `#building transaction`
19. `construct_txn = contract.constructor().buildTransaction({`
20. `'from': acct.address,`
21. `'nonce': w3.eth.getTransactionCount(acct.address),`
22. `'gas': 1728712,`
23. `'gasPrice': w3.toWei('21', 'gwei')})`
24. 
25. `signed = acct.signTransaction(construct_txn)`
26. 
27. `tx_hash=w3.eth.sendRawTransaction(signed.rawTransaction)`
28. `print(tx_hash.hex())`
29. `tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)`
30. `print("Contract Deployed At:", tx_receipt['contractAddress'])`


    

这是我所做的:

  • 导入的 web3 库和所有其他必需的模块
  • 通过指向 Ropsten Infura 节点启动 web3 提供程序
  • 添加了用于签署交易的帐户地址和私钥。不要忘记在代码中添加您的凭据。
  • 通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
  • 添加了带有随机数、gas、gasPrice 等参数的construct_txn。此处,gas 是指交易应在以太坊中使用和支付的最大计算资源量。gasPrice 是指在交易中使用该数量的 gas 时的最小 Ether 数量。to 指的是您发送交易的地址。仅当您将 Ether 发送到帐户或智能合约时才需要 to 参数。
  • 使用我们的私钥签署交易并在网络上广播。
  • 在控制台中记录交易哈希和部署的合约地址。根据以太坊的说法,事务处理时间 <20 秒。所以你必须等待 20 秒才能获得部署的合约地址。您的后端现在已成功部署在以太坊区块链上。现在您可以使用此地址与您的智能合约进行交互。复制此合约地址。

2. 向部署的合约发送交易

在我们的合约中,有一个方法greet()。我们可以单独使用这种方法在我们的合同中添加问候语。让我们看看我们如何使用 web3.py 来做到这一点。打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 sign.py。然后在您的目录中运行 py sign.py。


      1. `import json`
2. `from web3 importWeb3, HTTPProvider`
3. `from web3.contract importConciseContract`
4. 
5. 
6. `# compile your smart contract with truffle first`
7. `truffleFile = json.load(open('./build/contracts/greeter.json'))`
8. `abi = truffleFile['abi']`
9. `bytecode = truffleFile['bytecode']`
10. 
11. `# web3.py instance`
12. `w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/<API key>")) #modify`
13. `print(w3.isConnected())`
14. `contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>") #modify`
15. `key="<Private key with 0x prefix here>"#modify`
16. `acct = w3.eth.account.privateKeyToAccount(key)`
17. `account_address= acct.address`
18. 
19. `# Instantiate and deploy contract`
20. `contract = w3.eth.contract(abi=abi, bytecode=bytecode)`
21. `# Contract instance`
22. `contract_instance = w3.eth.contract(abi=abi, address=contract_address)`
23. `# Contract instance in concise mode`
24. `#contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)`
25. 
26. `tx = contract_instance.functions.greet("Hello all my goody people").buildTransaction({'nonce': w3.eth.getTransactionCount(account_address)})`
27. `#Get tx receipt to get contract address`
28. `signed_tx = w3.eth.account.signTransaction(tx, key)`
29. `#tx_receipt = w3.eth.getTransactionReceipt(tx_hash)`
30. `hash= w3.eth.sendRawTransaction(signed_tx.rawTransaction)`
31. `print(hash.hex())`


    

这是我所做的:

  • 导入的 web3 库和所有其他必需的模块
  • 通过指向 Ropsten Infura 节点启动 web3 提供程序
  • 添加了用于签署交易的帐户地址和私钥
  • 通过指向 Truffle 编译的工件文件greeter.json的abi和字节码启动合约实例
  • 创建 tx 对象以添加问候语“hello all my goody people”并建立交易
  • 使用我们的私钥签署交易并在网络上广播。
  • 在控制台中记录交易哈希。您可以使用您的交易哈希在 etherscan 上检查交易状态。一旦交易被矿工验证,我们的问候语将被添加到区块链上。您可以使用 getGreeting() 函数检索问候语,如下所述。

3. 从部署的智能合约中读取数据

在我们的合约中,有一个方法 getGreeting() 可以检索我们在区块链中添加的问候语。我们将使用 web3.py 调用此方法 打开您的 Python IDLE 编辑器并使用以下代码创建一个新文件 read.py。运行 py read.py 读取问候语。


      1. `import json`
2. `from web3 importWeb3, HTTPProvider`
3. `from web3.contract importConciseContract`
4. 
5. 
6. `# compile your smart contract with truffle first`
7. `truffleFile = json.load(open('./build/contracts/greeter.json'))`
8. `abi = truffleFile['abi']`
9. `bytecode = truffleFile['bytecode']`
10. 
11. `# web3.py instance`
12. `w3 = Web3(HTTPProvider("https://ropsten.infura.io/<ApI Key here>"))`
13. `print(w3.isConnected())`
14. `contract_address = Web3.toChecksumAddress("<Deployed Contract Address here>")`
15. 
16. `# Instantiate and deploy contract`
17. `contract = w3.eth.contract(abi=abi, bytecode=bytecode)`
18. `# Contract instance`
19. `contract_instance = w3.eth.contract(abi=abi, address=contract_address)`
20. `# Contract instance in concise mode`
21. `#contract_instance = w3.eth.contract(abi=abi, address=contract_address, ContractFactoryClass=ConciseContract)`
22. 
23. `# Getters + Setters for web3.eth.contract object ConciseContract`
24. `#print(format(contract_instance.getGreeting()))`
25. 
26. `print('Contract value: {}'.format(contract_instance.functions.getGreeting().call()))`


    

这是我所做的:

  • 导入的 web3 库和所有其他必需的模块
  • 通过指向 Ropsten Infura 节点启动 web3 提供程序
  • 通过指向 abi 和 contract_Address 创建合约实例(来自上一步)
  • 调用 getGreeting() 方法并在控制台打印结果

结论

您现在应该了解如何使用 web3.py 部署、交互和签署交易。让我们通过查看我使用 web3.py 创建的实时 DApp 并在此处使用 Flask 作为前端服务器来将所有部分组合在一起。它将帮助您更深入地了解使用 Python 进行 DApp 开发。

picture.image picture.image picture.image

picture.image

picture.image

点击下方阅读原文加入 社区会员

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
字节跳动客户端性能优化最佳实践
在用户日益增长、需求不断迭代的背景下,如何保证 APP 发布的稳定性和用户良好的使用体验?本次分享将结合字节跳动内部应用的实践案例,介绍应用性能优化的更多方向,以及 APM 团队对应用性能监控建设的探索和思考。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论