web3.py过滤器filter
先简单说明一下,我还不是很熟练使用filter,而且在使用过程还出现了许多未解决问题,以下仅是将简单的实现过程记录以便日后翻查。
1.首先是智能合约中的事件event
以太坊中事件event和日志logs具有很大的联系,可以说事件的触发就是为了将一些信息记录到日志中。
在智能合约中定义事件:
复制代码
1
2
3
4event UserRegisterLog(address indexed addr,string publicKey); event BookRegisterLog(address indexed owner,string bookKey,string bookInfo); event MakeOrderLog(address indexed owner,address indexed consumer,uint indexed orderID,ConsignmentStyle style);
在智能合约中触发事件(emit):
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14function UserRegister(string memory _name,string memory _publicKey,string memory _wxAccount) public { bytes memory nameBytes = bytes(_name); require(nameBytes.length != 0); require(Users[msg.sender].addr == address(0)); require(Users[msg.sender].ifRegister != true); Users[msg.sender].name = _name; Users[msg.sender].publicKey = _publicKey; Users[msg.sender].wxAccount = _wxAccount; Users[msg.sender].addr = msg.sender; Users[msg.sender].ifRegister = true; emit UserRegisterLog(msg.sender,_publicKey); }
2.我使用事件解决的问题
毕业设计主要是一个书籍交易系统,需要实现的功能就是卖方A在发布订单后需要及时知道什么时候有人下单,也就是当买方B下单购买时,卖方A的客户端有消息提醒之类的。
于是了解了以太坊的事件,觉得可用,就尝试了一下。
以太坊智能合约事件监听主要有两种方式:
- 第一种主要是监听自身发送的交易所触发的事件,例如上面的UserRegister()智能合约被调用时监听其触发事件的部分示例代码如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45"""生成区块链打包回执""" def ProduceFuncReceipt(self,_txn_dict,_privateKey=None): ''' 利用离线签名交易机制打包区块链交易 :param _txn_dict: 交易事务哈希 :param _privateKey: 私钥 :return: ''' signed_txn = self.web3.eth.account.signTransaction(_txn_dict, private_key=_privateKey) # print('signed payload => {0}'.format(self.web3.toHex(signed_txn.rawTransaction))) tx_hash = self.web3.eth.sendRawTransaction(signed_txn.rawTransaction) receipt = self.web3.eth.waitForTransactionReceipt(self.web3.toHex(tx_hash)) return receipt """用户注册""" def UserRegister(self,_useraddr,_name,_publicKey,_wxAccount,_privateKey): ''' 用户注册函数,在智能合约登记用户地址、名称、公钥、微信号 :param _useraddr: :param _name: :param _publicKey: :param _wxAccount: :param _privateKey: :return: ''' nonce = self.GetNounce(_useraddr) txn_dict = self.myContract.functions.UserRegister(str(_name),str(_publicKey),str(_wxAccount)) .buildTransaction({ 'chainId':9, 'gas':3000000, 'gasPrice':self.web3.toWei('1','gwei'), 'nonce':nonce, }) # 因为注册时还未登入,所以要连同私钥一起传递 logs = self.UserRegisterLog(self.ProduceFuncReceipt(txn_dict,_privateKey)) if len(logs) == 0: return False print('用户注册logs=>:{0}'.format(logs[0]['args'])) return logs[0]['args'] """注册--事件日志读取,被UserRegister调用""" def UserRegisterLog(self,_receipt): rich_logs = self.myContract.events.UserRegisterLog().processReceipt(_receipt) return rich_logs
- 第二种是利用某些特征参数监听特定的事件,不一定是与自身账户有关的事件。
在这里就使用到 过滤器filter。
可以看到上面在智能合约定义事件时,有些参数是带有 indexed 修饰的,这些就是特征参数。
使用后台线程利用filter实现事件监听的部分实力代码如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14def MadeOrderListenning(self,event_filter,poll_interval): while True: for event in event_filter.get_new_entries(): print("监听事件:",event) time.sleep(poll_interval) def MadeOrderListenning_ThreadStart(self): event_filter = self.myContract.events.MakeOrderLog.createFilter(fromBlock="latest", argument_filters={ 'consumer': '0xb94ccf8aba77ce293692dbdfe919a20357ee6335' }) worker = Thread(target=self.MadeOrderListenning,args=(event_filter,3)) worker.start()
其中argument_filters就是以json格式传入特征参数(用indexed修饰的参数)。
成功监听到事件触发(这个图比较久,和代码应该有些出入):
3.到上面已经简单实现事件监听,但实际毕设使用过程存在许多问题(尚未解决)
遇到的问题有:
- websocket close
- RuntimeError: cannot call recv() while another coroutine is already waiting for the next message
最后
以上就是寂寞水蜜桃最近收集整理的关于Windows下使用web3.py进行以太坊Dapp开发笔记--第4篇(过滤器filter)的全部内容,更多相关Windows下使用web3内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复