? ? 在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 user
let 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) 所示:
3.3 owner用戶測驗
node test\ethers\9.owner_setValue.js 702
? ? 如圖(3) 所示:
? ? 由圖(2)、圖(3)可知普通用戶和owner用戶,都可以修改value的值,并且7.er_listenEvent.js腳本監聽到了這個value值的修改,
參考文獻
? ? [1] ethers.js V5 事件監聽
? ? [2] ethers.js Provider使用
? ? [3] ethers.js合約詳解
? ? [4] hardhat里的合約監聽
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/335254.html
標籤:區塊鏈
