赞
踩
注:使用web3.js的时候,Metamask会自动嵌入一段js代码进入网站,所以我们网站可以自动识别是不是Metamask提供者!
Flask-web3仅对web3.py做了一个封装,用法还是和web3.py一样,只是为了符合flask框架,增加了一个全局对象current_web3,并把区块链服务器配置写入了配置文件中!

Flask-web3内部配置实现之源代码:

(建议使用ganache-cli来测试,而geth,我创建了私有区块链测试,可能是区块同步的问题,geth的console命令行转账测试都没成功,开启挖矿也测试了,没成功.........)
- from flask_web3 import FlaskWeb3
- import json
-
- # 这些import仅仅用来方便注释type:类型,智能提示作用!
- from requests import Timeout
- from web3 import Web3
- from web3.eth import Eth, Contract
- from web3.personal import Personal
-
-
- class Web3Contract:
- def __init__(self):
- self.web3 = FlaskWeb3() # type:Web3
-
- self.eth = self.web3.eth # type:Eth
- self.personal = self.web3.personal # type:Personal
-
- self.abi_json_file_path = 'app/api/v1/eth/truffle/build/contracts/FirstContract.json'
- self.from_addr = self.eth.accounts[0]
- self.private_key_for_senders_account = "longmai123456"
-
- self.start()
-
-
- def start(self):
- # 这里很重要,defaultAccount默认为null,设置一个默认交易转账账号(如果transaction没指定from地址,那么这里是必须的)
- self.eth.defaultAccount = self.eth.accounts[0]
-
- # 交易转账参数(如果不指定发送者,from为默认账号eth.defaultAccount)
- transaction = {
- "from": self.from_addr
- }
-
- # 读取合约的abi-json文件
- contract_interface = self.get_contract_json(self.abi_json_file_path)
-
- # 部署合约地址
- contract_address = self.deploy_contract_address(contract_interface, transaction)
-
- # 获取合约实例
- store_var_instance = self.get_contract_instance(contract_address, contract_interface)
-
- # 调用合约实例方法
- self.invoke_contract_methods(store_var_instance, transaction)
-
- @staticmethod
- def get_contract_json(json_file_path):
- # 通过with上下文管理器读取json文件,更安全!
- with open(json_file_path, 'r', encoding="UTF-8") as f:
- source = json.load(f)
- return source
-
- def deploy_contract_address(self, contract_interface, transaction):
- self.unlockAccount()
- # 注:如果没有设置web.eth.defaultAccount默认账号的话,这里合约部署必须在指定transaction中指定from发送地址!
- tx_hash = self.eth.contract(
- abi=contract_interface['abi'],
- bytecode=contract_interface['bytecode']).constructor().transact(transaction=transaction)
- tx_receipt = self.wait_for_receipt(tx_hash, 120)
-
- return tx_receipt["contractAddress"]
-
- def get_contract_instance(self, contract_address, contract_interface):
- # 获取合约实例!
- instance = self.eth.contract(
- address=contract_address,
- abi=contract_interface['abi'])
- return instance
-
- def invoke_contract_methods(self, contract_instance, transaction):
- # 这里仅方便pycharm智能语法提示使用!
- instance = contract_instance # type:Contract
- # 发送交易之前必须解锁账户!
- self.unlockAccount()
-
- # 调用合约的setInfo方法,并获取交易的hash值!
- tx_hash = instance.functions.setInfo("kirin", 18).transact(transaction=transaction)
- # 获取hash值解码的收据凭证(其中包含当前hash的全部信息,如合约地址,交易账号,gas.....)
- tx_receipt = self.wait_for_receipt(tx_hash, 120)
-
- # 返回solidity的事件log
- event_logs = instance.events.eventInfo().processReceipt(tx_receipt)
- name, age = instance.functions.getInfo().call()
- print("调用solidity返回的值", name, age)
-
- def wait_for_receipt(self, tx_hash, max_seconds):
- try:
- tx_receipt = self.eth.waitForTransactionReceipt(tx_hash, max_seconds)
- except Timeout:
- raise Timeout("合约部署请求超时!!!")
- return tx_receipt
-
- def transfer_to(self):
- self.unlockAccount()
- self.eth.sendTransaction({
- "from": self.from_addr,
- "to": self.eth.accounts[1],
- "value": self.web3.toWei(1, 'ether')
- })
- print("账户收到金额:", self.eth.getBalance(self.eth.accounts[1]))
-
- def unlockAccount(self):
- self.personal.unlockAccount(self.from_addr, self.private_key_for_senders_account, 3600)

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。