在ethers.js里,使用contractWithSigner.on()的方式,监听合约的某个事件或者地址上的交易。合约的事件,会通过emit event的方式发出,使用contractWithSigner.on() 注册了该事件,就可以实现监听了。下面以监听EventValue.sol里的ValueChanged事件为例,进行说明。

1、部署合约

    a) 参考这篇文章 [用ethers.js部署合约],来部署EventValue.sol合约,得到合约地址为:0x850A0D21Da477Ea95D44d00f2B534CB0DF8eef92
    //EventValue.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;contract EventValue {event ValueChanged(address indexed author,uint oldValue,uint newValue);uint _value;constructor(uint value) public {uint tmp = _value;_value = value;emit ValueChanged(msg.sender, tmp, value);}function getValue() view public returns (uint) {return _value;}function setValue(uint value) public {uint tmp = _value;_value = value;emit ValueChanged(msg.sender, tmp, value);}
}

    b) 创建文件夹和文件

mkdir -p test/ethers
cd test/ethers## 3个脚本
touch 7.er_listenEvent.js
touch 8.any_setValue.js
touch 9.owner_setValue.js

2、编写监听脚本和测试脚本

2.1 监听脚本

    监听合约事件的脚本为7.er_listenEvent.js
    // 7.er_listenEvent.js

const {ethers} = require("ethers")
const fs = require('fs')let provider = new ethers.providers.JsonRpcProvider('http://localhost:8545')function getHexString(prikeyPath) {const privKeyFile = fs.readFileSync(prikeyPath).toString().trim();const privKey = new Buffer.from(privKeyFile, 'hex');    return privKey
}async function listenEvent(){var privKey  = getHexString(".secret")let wallet = new ethers.Wallet(privKey,provider)var contractAddr = '0x850A0D21Da477Ea95D44d00f2B534CB0DF8eef92'//var contractAddr = '0x305Dd19C5FBAd6b24649A030681C7c494b5481e2'var jsonStr = fs.readFileSync('./build/contracts/EventValue.json')var jsonInfo = JSON.parse(jsonStr)var jsonAbi  = jsonInfo.abi    let contract = new ethers.Contract(contractAddr,jsonAbi,provider)let contractSign = contract.connect(wallet)let curValue = await contractSign.getValue()console.log('curValue=',ethers.BigNumber.from(curValue).toNumber())let tx = await contractSign.setValue(300)console.log('txHash=',tx.hash)await tx.wait()//1) 监听ValueChanged事件(不区分合约创建者与普通用户)contractSign.on("ValueChanged",(author,oldValue,newValue,event) => {console.log('---- anyUser ---')console.log('user=',author)console.log('oldValue=',ethers.BigNumber.from(oldValue).toNumber())console.log('newValue=',ethers.BigNumber.from(newValue).toNumber())console.log('eventNumber=',event.blockNumber)});//2) 在这些事件中,找出是合约创建者发起的调用交易let filter = contractSign.filters.ValueChanged(wallet.address)contractSign.on(filter,(author,oldValue,newValue,event) => {console.log('--- the Ower ----')console.log('ower=',author)console.log('oldValue=',ethers.BigNumber.from(oldValue).toNumber())console.log('newValue=',ethers.BigNumber.from(newValue).toNumber())console.log('eventNumber=',event.blockNumber)})
}listenEvent()

2.2 普通用户测试脚本

    普通用户的测试脚本为8.any_setValue.js
    // 8.any_setValue.js

const {ethers} = require("ethers")
const fs = require('fs')let provider = new ethers.providers.JsonRpcProvider('http://localhost:8545')function getHexString(prikeyPath) {const privKeyFile = fs.readFileSync(prikeyPath).toString().trim();const privKey = new Buffer.from(privKeyFile, 'hex');    return privKey
}function isNumber(val) {return !isNaN(val);
}async function preGetValue(contract) {let value = await contract.getValue()let valone = ethers.BigNumber.from(value).toNumber()console.log("curValue=",valone)
}async function preSetValue(contract,num) {let tx = await contract.setValue(num)console.log('tx=',tx.hash)await tx.wait()
}async function doValue(num){// var privKey  = getHexString(".secret")// other userlet privKey = '0x0272...d322'let wallet = new ethers.Wallet(privKey,provider)var contractAddr = '0x850A0D21Da477Ea95D44d00f2B534CB0DF8eef92'var jsonStr = fs.readFileSync('./build/contracts/EventValue.json')var jsonInfo = JSON.parse(jsonStr)var jsonAbi  = jsonInfo.abi    let contract = new ethers.Contract(contractAddr,jsonAbi,wallet)await preSetValue(contract,num)await preGetValue(contract)
}var count = process.argv[2]
if (isNumber(count)) {doValue(count)
} else {console.log('please input a number')
}

2.3 owner用户测试脚本

    合约的部署者,也叫owner用户,其测试脚本如下
    // 9.ower_setValue.js

const {ethers} = require("ethers")
const fs = require('fs')let provider = new ethers.providers.JsonRpcProvider('http://localhost:8545')function getHexString(prikeyPath) {const privKeyFile = fs.readFileSync(prikeyPath).toString().trim();const privKey = new Buffer.from(privKeyFile, 'hex');    return privKey
}function isNumber(val) {return !isNaN(val);
}async function preGetValue(contract) {let value = await contract.getValue()let valone = ethers.BigNumber.from(value).toNumber()console.log("curValue=",valone)
}async function preSetValue(contract,num) {let tx = await contract.setValue(num)console.log('tx=',tx.hash)await tx.wait()
}async function doValue(num){var privKey  = getHexString(".secret")let wallet = new ethers.Wallet(privKey,provider)var contractAddr = '0x850A0D21Da477Ea95D44d00f2B534CB0DF8eef92'var jsonStr = fs.readFileSync('./build/contracts/EventValue.json')var jsonInfo = JSON.parse(jsonStr)var jsonAbi  = jsonInfo.abi    let contract = new ethers.Contract(contractAddr,jsonAbi,wallet)await preSetValue(contract,num)await preGetValue(contract)
}var count = process.argv[2]
if (isNumber(count)) {doValue(count)
} else {console.log('please input a number')
}

3、进行测试

3.1 开启事件监听

node test\ethers\7.er_listenEvent.js

3.2 普通用户测试

node test\ethers\8.any_setValue.js 700

    如图(2) 所示:

图(2) 普通用户,设置value

3.3 owner用户测试

node test\ethers\9.owner_setValue.js 702

    如图(3) 所示:

图(3) owner用户,设置value

    由图(2)、图(3)可知普通用户和owner用户,都可以修改value的值,并且7.er_listenEvent.js脚本监听到了这个value值的修改。

参考文献

    [1] ethers.js V5 事件监听
    [2] ethers.js Provider使用
    [3] ethers.js合约详解
    [4] hardhat里的合约监听

监听Solidity合约事件相关推荐

  1. html5 浏览器退回事件,html5的pushstate以及监听浏览器返回事件的实现

    这篇文章主要介绍了html5的pushstate以及监听浏览器返回事件的实现,主要介绍了pushstate的使用,以及监听浏览器的解决等问题,感兴趣的可以一起来了解一下 pushstate与监听浏览器 ...

  2. js监听多个事件_JavaScript中的事件与异常捕获解析

    这篇文章主要给大家介绍了关于JavaScript中事件与异常捕获的相关资料,文中通过示例代码介绍的非常详细,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批 ...

  3. vue 监听页面滚动事件:触发animate.min.css动画特效

    一.问题答疑: 1. animate.css 如何在vue项目中引入?或引用? 2. 如何监听滚动事件,触发animate.class动画播放? vue 监听滚轮滚动事件,for循环 ,动态id,代码 ...

  4. element-ui 搜索框组件:监听input键盘事件 - 代码篇

    踩坑:vue + element-ui 框架监听input键盘事件 - 含demo演示 代码示下: html部分: <el-inputplaceholder="职位 | 地区 | 工作 ...

  5. jquery监听窗口大小改变事件jquery.resizeend

    方法一: $(function(){// Bind the resize event. When any test element's size changes, update its// corre ...

  6. vue输入框输入触发事件_.vue文件中监听input输入事件oninput详解

    .vue文件其实是一个组件,关于它的说明我之前也写过一篇文章,地址:.vue文件,今天这篇文章要讲的是.vue文件中监听input的输入值变化事件.需求是这页面中,改变input的值,就调用一个事件, ...

  7. jquery 监听td点击事件_安卓开发监听点击事件的一种方法

    本人是菜鸟一只,学习安卓纯属兴趣.没有真正上过编程课程,所有知识都是在网上获取的.今天分享的是监听点击事件的一个方法,这个方法的好处是代码较简洁. 如图,点击保存时,把上面的数据入库. 实现如下: 在 ...

  8. Bootstrap3 滚动监听插件的事件

    滚动监听插件的事件 Bootstrap为滚动监听插件提供了一个事件 activate.bs.scrollspy,每当一个新的导航项目被激活时,就会触发该事件,并自动为导航条的相应菜单项添加了一个 .a ...

  9. Java中使用JNA实现全局监听Linux键盘事件

    title: Java中使用JNA实现全局监听Linux键盘事件 date: 2019-05-03 19:08:00 Java中使用JNA实现全局监听Linux键盘事件 用JNA实现的键盘监听,在Wi ...

  10. Java中使用JNA实现全局监听Windows键盘事件

    title: Java中使用JNA实现全局监听Windows键盘事件 date: 2019-05-02 21:55:00 Java中使用JNA实现全局监听Windows键盘事件 前言: 一直打算做一个 ...

最新文章

  1. 不存在_MySQL数据存在就更新,不存在就添加
  2. leetcode 刷题140 141
  3. Minor GC和Full GC
  4. leetcode51. N皇后
  5. 我太难了!男子打赏女主播被骗9.6万,求助“好心人”再度被骗...
  6. 测试接口python常用命令_用python实现接口测试(四、操作MySQL)-阿里云开发者社区...
  7. [Tools] JD-GUI(Java Decompiler)
  8. 04-10 swagger 接口管理体系
  9. lynis check log
  10. 怎么样可以通过阿里云APP进行备案 阿里云备案一般多长时间
  11. unity安装2020或2019出现空白错误
  12. JS实现拼音搜索汉字(支持首字母匹配)
  13. python爬虫:爬取链家深圳全部二手房的详细信息
  14. 基于微信小程序的智慧社区系统
  15. Android 11源码 Framework修改默认usb连接模式为MTP模式
  16. 鸡兔同笼python程序怎么写_属鸡-生肖鸡-属鸡人的命运-华易算命网
  17. Java项目:停车位预定管理系统(java+JSP+JavaScript+HTML+Mysql)
  18. 超级管理器Android,超级文件管理器官方最新版下载
  19. React实现登录表单
  20. 什么是标签(Tags)

热门文章

  1. TARA-威胁建模方案4
  2. 让Excel工作簿中宏自动运行的两种方法
  3. 接口,implement,多继承
  4. Linux iproute2 命令家族(ip / ss)
  5. scrollbars属性,MultiLine 属性
  6. linux下制作u盘启动光盘,用SYSLINUX做启动U盘、光盘
  7. ssh远程重装Centos系统
  8. 机器学习笔记 - 简单了解模式识别
  9. 2022-02-03:有一队人(两人或以上)想要在一个地方碰面,他们希望能够最小化他们的总行走距离。 给你一个 2D 网格,其中各个格子内的值要么是 0,要么是
  10. 英文地址翻译原则:先小后大。如**号**路**区,