Windows下使用web3.py进行以太坊Dapp开发笔记--第4篇(过滤器filter)_runtimeerror: cannot call recv while another corou-程序员宅基地

技术标签: 区块链  过滤器  Web3.py  event  

web3.py过滤器filter

先简单说明一下,我还不是很熟练使用filter,而且在使用过程还出现了许多未解决问题,以下仅是将简单的实现过程记录以便日后翻查。

1.首先是智能合约中的事件event

以太坊中事件event和日志logs具有很大的联系,可以说事件的触发就是为了将一些信息记录到日志中。

在智能合约中定义事件:

event 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):

function 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()智能合约被调用时监听其触发事件的部分示例代码如下:
"""生成区块链打包回执"""
    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实现事件监听的部分实力代码如下:

def 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
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41907714/article/details/106643231

智能推荐

mysql修改字段名称脚本_mysql数据库修改字段及新增字段脚本-程序员宅基地

文章浏览阅读1.3k次。1.修改字段的长度ALTER TABLE MODIFY COLUMN 字段名 数据类型(修改后的长度)例句:ALTER TABLE test_table MODIFY COLUMN id INT(20)2.修改字段的名称alter table change 。例句:ALTER TABLE test_tableCHANGE attence_name NAME VARCHAR(20)3...._mysql 修改字段脚本

黑马程序员学习日记(4)--继承、多态-程序员宅基地

文章浏览阅读466次。---------------------- ASP.Net+Android+IO开发S、.Net培训、期待与您交流! -----------------------继承:用法。。父类派生子类;子类可以用父类的所有属性方法,还可以有自己的方法属性。子类除了不能继承父类的构造函数和析构函数外,可以继承父类所有的成员和方法。子类不能直接修改父类的私有成员,只能通过父类的公有方法对其

1028: C语言程序设计教程(第三版)课后习题8.2-程序员宅基地

文章浏览阅读675次。题目描述求方程 的根,用三个函数分别求当b^2-4ac大于0、等于0、和小于0时的根,并输出结果。从主函数输入a、b、c的值。输入a b c输出x1=? x2=?样例输入4 1 1样例输出x1=-0.125+0.484i x2=-0.125-0.484i 1 #include <stdio.h> 2 #include <math.h..._1028:c语言程序设计教程(第三版)课后习题8.2

汇聚交换机-程序员宅基地

文章浏览阅读1.9k次。按照网络构成方式,网络交换机被划分为接入层交换机、汇聚层交换机和核心层交换机。汇聚层交换机,是多台接入层交换机的汇聚地点。汇聚层交换机的作用是将接入节点统一出口,同样也做转发及选路。它必须能够处理来自接入层设备的所有通信量,并提供到核心层的上行链路。汇聚层交换机需要具备高转发性能,通常也是三层交换机。但不是每个网络都需要汇聚交换机,交换机的选择取决于网络环境的大小及设备的转发能力。简而言之,就是汇聚

宝塔Nginx 安装check模块nginx_upstream_check_module_宝塔 安装 nginx_upstream_check_module-程序员宅基地

文章浏览阅读2.1k次。第一步:在宝塔安装nginx,选择编译安装第二步:在这个基础上加新增模块nginx_upstream_check_module,步骤如下1.执行命令获取nginx_upstream_check_module模块: wgethttps://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master2.进入..._宝塔 安装 nginx_upstream_check_module

c/c++易错点收集(持续更新)_c++易错题总结-程序员宅基地

文章浏览阅读1.7k次,点赞7次,收藏27次。收集了c,c++语言在学习和应用的时候一些易错点,加入了个人分析。仅供参考,有错误的地方请多多指出_c++易错题总结

随便推点

Matlab 绘制两端带尖角(两端尖尖,尖色头条)的colorbar_matlab画图例带尖角-程序员宅基地

文章浏览阅读4.6k次,点赞6次,收藏22次。其实这样的colorbar可以直接手动画出来,不多说,直接上代码cmap = [69 117 180 116 173 203 171 217 233 254 224 144 253 174 77 244 109 67 215 48 39 165 0 38]/255;%画图的部分代码colormap(ax,cmap);xmin = -1..._matlab画图例带尖角

pb与java_Java中使用PB教程-程序员宅基地

文章浏览阅读1.6k次。前言之前在写Netty的时候,说过要写一篇关于PB的应用,所以现在兑现承诺。在应用的过程中,发现了很多问题,本文主要介绍两个最关键的问题。PB如何与java项目融合,自动刷新编译,以及pb文件如何与其他项目共用,互不影响。java中如何实现pb的Extension概述ProtocolBuff 是 google 提出的的一种数据交换格式,跨语言,跨平台,可扩展。基于这种特性广泛的用于网络数据通信。目..._java开发pb接口

线程的同步_package com.atguigu.java1; //死锁的演示 class a { publi-程序员宅基地

文章浏览阅读230次。线程的同步1.背景2.同步代码块和同步方法package com.atguigu.java;/** * 例子:创建三个窗口卖票,总票数为100张.使用实现Runnable接口的方式 * * 1.问题:卖票过程中,出现了重票、错票 -->出现了线程的安全问题 * 2.问题出现的原因:当某个线程操作车票的过程中,尚未操作完成时,其他线程参与进来,也操作车票。 * 3.如何解决:当一个线程a在操作ticket的时候,其他线程不能参与进来。直到线程a操作完ticket时,其他_package com.atguigu.java1; //死锁的演示 class a { public synchronized void

大数据Spark(三十三):SparkSQL分布式SQL引擎_sparksql作为分布式sql查询引擎-程序员宅基地

文章浏览阅读1.1k次。停止使用:在实际大数据分析项目中,使用SparkSQL时,往往启动一个ThriftServer服务,分配较多资源(Executor数目和内存、CPU),不同的用户启动beeline客户端连接,编写SQL语句分析数据。Spark Thrift Server将Spark Applicaiton当做一个服务运行,提供Beeline客户端和JDBC方式访问,与Hive中HiveServer2服务一样的。回顾一下,如何使用Hive进行数据分析的,提供哪些方式交互分析?_sparksql作为分布式sql查询引擎

Python 代理爬取网站数据_python 发送代理爬取网站-程序员宅基地

文章浏览阅读907次。代理IP通过https://www.kuaidaili.com/free/ 获取,我使用的的是http协议的代理。根据自己需求选择http或者https 协议的页面。访问量会有增长,但效果不是非常理想,后面找时间在研究下、废话不多说,直接上代码。# -*- coding:utf-8 -*-import requestsimport randomimport timeim..._python 发送代理爬取网站

Spark的关键技术回顾-程序员宅基地

文章浏览阅读2.4k次,点赞46次,收藏69次。目录前言Spark的关键技术回顾一、Spark复习题回顾1、Spark使用的版本2、Spark几种部署方式?3、Spark的提交任务的方式?4、使用Spark-shell的方式也可以交互式写Spark代码?5、你对RDD是怎么理解的?6、Spark如何实现容错?7、Spark共享变量?8、Spark的任务执行?9、Spark的RDD的几种类型?10、Spark的Transformation算子有几类?11、RDD创建的三种方法?12、RDD-Dat

推荐文章

热门文章

相关标签