在上一章使用expess监听web3事件之一:环境搭建_lixiaodog的博客-CSDN博客中我们搭建好了EXPRESS的开发框架,在本章我们将在这个框架下调用WEB3模块监听目标合约。实际上如果单纯为监听合约,并不需要EXPRESS,但是一个真正的DAPP会有相当数量数据会存储到本地,而并不是使用的时候才去链上查找 ,那样太慢了,正常是做法是把链上数据同步到本地的数据库,客户使用时,直接查询本地数据。而为客户提供这个查询能力一般是通过提供一组供客户调用的API来实现的。这个时候EXPRESS就会提供大量的方便的模块供我们使用, 为了方便演示所以采用了EXPRESS。
在根目录下创建一个文件夹,并创建3个文件,目录结构如下:
代码如下:
contracts.js
const config ={
GameManage:require("../../build/contracts/GameManage.json"),
GameManageProxy:require("../../build/contracts/GameManageProxy.json"),
TutorialToken:require("../../build/contracts/TutorialToken.json"),
BaseDesk:require("../../build/contracts/BaseDesk.json"),
}
module.exports = config;
eventbus.js
var mitt = require("mitt");
const emitter = mitt();
module.exports = emitter;
watcher.js
var Web3 = require('Web3')
var config = require('./contracts.js')
var contract = require('@truffle/contract')
var emitter = require('./eventbus.js')
const watcher = {
contracts: {},
instances: {},
eventManager: {},
roomList: {},
roomInfo: {},
deskInfo: {},
player: {},
start: function (options) {
console.log('watcher start')
this.web3Provider = new Web3.providers.WebsocketProvider('http://127.0.0.1:8545')
this.eventManager = emitter
web3 = new Web3(this.web3Provider)
this.web3 = web3
this.initContract()
},
initContract: async function () {
this.contracts.GameManageProxy = contract(config.GameManageProxy)
this.contracts.GameManageProxy.setProvider(this.web3Provider)
this.contracts.GameManage = contract(config.GameManage)
this.contracts.GameManage.setProvider(this.web3Provider)
this.contracts.GameManageProxy.deployed()
.then((instance) => this.contracts.GameManage.at(instance.address))
.then((instance) => {
this.instances.GameManage = instance;
console.log("watcher start");
this.startWatch();
})
this.contracts.TutorialToken = contract(config.TutorialToken)
this.contracts.TutorialToken.setProvider(this.web3Provider)
await this.contracts.TutorialToken.deployed().then(
(instance) => (this.instances.TutorialToken = instance),
)
this.contracts.BaseDesk = contract(config.BaseDesk)
this.contracts.BaseDesk.setProvider(this.web3Provider)
},
startWatch: async function () {
let self = this;
//开始监听所有事件
this.watchTarget = new this.web3.eth.Contract(
config.GameManage.abi,
this.instances.GameManage.address,
)
this.allEvent = this.watchTarget.events.allEvents(function (
error,
result,
) {
if (error) {
console.log('event error', error)
} else {
//此处响应所有事件
self.eventManager.emit(result.event, result.returnValues);
console.log("event", result);
}
})
},
}
module.exports = watcher
这里可以替换任何自己想要监听的合约。
在响应事件的地方,一般是添加数据库写入操作等等。
在APP.JS里加入代码:
watcher.start();
app.watcher = watcher;
此时打开我们的在上一系列中的ROOMLIST页面:
addRoom的响应函数如下:
//添加桌子
addDesk(row, index) {
let deskInfo = DataDef.DeskInfo();
deskInfo.name = 0;
deskInfo.addr = this.$store.state.userInfo.data.userData.username;
deskInfo.creator = this.$store.state.userInfo.data.userData.username;
deskInfo.owner = this.$store.state.userInfo.data.userData.username;
deskInfo.password = "";
deskInfo.token = myWeb3.instances.TutorialToken.address;
deskInfo.bonus = 0;
deskInfo.state = 0;
myWeb3.instances.GameManage.createDesk(row.name, deskInfo,{from:this.$store.state.userInfo.data.userData.username, value: myWeb3.web3.utils.toWei('10')})
.then(res => {
console.log(userCharge);
})
},
执行后,我们的后台会收到event: 'DeskCreated'
到此,我们的事件接收服务已经编写完成,接收到事件可以做保存数据的操作。本文中为了方便,把服务建立 在EXPRESS中,实际上应该和API服务剥离,这样某一服务出了问题,不至于影响链上数据的保存。