毕业设计做了相关区块链的项目,在考虑了Hyperledger和Ethereum之后选择使用了Ethereum,因为在Ethereum上用智能合约,代币等更方便。然而对于Ethereum,国内对于Python来开发的教程还不够多,我就想把毕设中踩得坑记录下来。 本文提供的代码上传至https://github.com/crazylnx/bupt-homework/tree/master/%E6%AF%95%E4%B8%9A%E8%AE%BE%E8%AE%A1%E4%BB%A3%E7%A0%81
环境选择 我现在只是将Python与Ethereum的模拟软件Ganache相连。
- 系统:Windows 10
- Python version 3.7.3
- Solidity version 0.5.0
- Ganache version 2.0.1
- Pycharm version 2019.1.1
Python库选择
- Web3.py version 4.9.1
- Easysolc version 0.1.4
步骤
【web3.py|使用Web3.py连接Ethereum】上述软件的安装,自行百度。
库安装,需要注意Easysolc库需要安装solc这个solidity编译工具,具体步骤为,去https://github.com/ethereum/solidity/releases 寻找solidity-windows.zip,并将其解压,获得solc.exe,将solc.exe保存到Pycharm你的项目的根目录。
- Python利用Web3.py连接Ganache软件。
from web3 import Web3, HTTPProvider
w3 = Web3(HTTPProvider("http://localhost:8545")) #有疑问请看web3.py官网
- Python利用easysolc编译并部署solidity文件
from easysolc import Solc #放在文件最上面w3.eth.defaultAccount = w3.eth.accounts[0]//使用账户0来部署。
solc = Solc()
# 编译智能合约并放在当前目录
solc.compile('..\\你的合约文件.sol', output_dir='.')
# 获取智能合约实例 其中abi和bin文件为编译后生成的文件,可以去你的项目目录下找。
contract = solc.get_contract_instance(w3=w3, abi_file='.\\你的合约.abi', bytecode_file='.\\你的合约.bin')
# 部署智能合约
tx_hash = contract.constructor().transact()
tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)#等待挖矿过程
# 获得智能合约部署在链上的地址
contractAddr = tx_receipt.contractAddress
- Python利用合约地址获取合约实例。(有时候知道合约的地址,想用合约中的函数。)
from easysolc import Solc #放在文件最上面
from web3 import Web3, HTTPProvider
w3 = Web3(HTTPProvider("http://localhost:8545")) #有疑问请看web3.py官网
solc = Solc()
contract = solc.get_contract_instance(w3=w3, abi_file='.\\你的合约.abi', bytecode_file='.\\你的合约.bin',address=contractAddr)
- Python使用智能合约函数
- 调用函数
tx_hash = contract.functions.addNewCar(_no,w3.eth.accounts[_no]).transact() #tx_hash为transaction的hash值。
w3.eth.waitForTransactionReceipt(tx_hash) #等待hash值为tx_hash的transaction写入块(挖矿成功)。- 调用public的变量
tx_hash=contract.call().函数名(参数)#查看变量不会产生gas消耗。
- Web3.py给合约打钱
非常重要
对于智能合约内部的转账操作,需要合约能够具备一定的ether,所以就需要先给合约充值,一般为智能合约拥有者给合约充值。
w3.eth.sendTransaction({"from": w3.eth.accounts[0], "to": contractAddr, "value": 50342342300000000000});
#from:充值的账户,to:充值到的地方,value:单位为wei。(1ether=1000000000000000000 Wei)充值需要智能合约中有 fallback()函数,自行百度,很简单。
- Web3.py切换账户
w3.eth.defaultAccount = w3.eth.accounts[0]
推荐阅读