事件event一般是智能合约中的日志,你每调用一个方法,它执行后会得到什么结果呢:是成功还是失败?这一般可以通过事件来得到确定的答案。虽然在send()方法中有个shouldPollResponse设置为true参数,但是得到它的结果要等待60秒,这时间有点太感人了!回到事件的方法,这估计是确定性的最好方案了。
async function triggercontract(){
try {
let instance = await tronWeb.contract().at('TQQg4EL8o1BSeKJY4MJ8TB8XK7xufxFBvK');
instance.Transfer().watch((err, eventResult) => {
if (err) {
return console.error('Error with "method" event:', err);
}
if (eventResult) {
console.log('eventResult:',eventResult);
}
});
let res = await instance.transfer('TWbcHNCYzqAGbrQteKnseKJdxfzBHyTfuh',500).send({
feeLimit:100_000_000,
callValue:0,
shouldPollResponse:true
});
console.log(res);
} catch (error) {
console.log(error);
}
}
triggercontract();
这是tron的手册给出的方法。这方法是简单好用,但是watch的方法却是时灵时不灵的!OMG,这对于需要确定性结果的区块链简直是灾难啊!
watch方法这么不靠谱,还是要自己想办法啊。watch的方法虽是时灵时不灵的,但事件却会实实在在产生的,这是确定性的。看来只有自己想办法查询并过滤事件以得到确定性的结果了。
async buy(){
this.isLoading = true
this.confirmFlag = false
let instance = this.$store.state.TronC2cInstance
let hash = await instance.buyerSubmit(this.conformUid).send({feeLimit:20_000_000})
//过滤事件以确定上链成功
let i = 0
let checkConfirm = async ()=> {
i++
if(i>9){
//循环10次
clearInterval(timer)
}
//过滤事件,每3秒10条,10次
let res = await this.tronWeb2.getEventResult(this.tsteemOtc, {eventName:'BuyerSubmit', size:10})
let checkEvent = async ()=> {
return new Promise(resolve => {
for(let t = 0; t < res.length; t++ ){
if(hash === res[t].transaction){
clearInterval(timer)
resolve('ok')
}
}
if(i === 10){
resolve('false')
}
})
}
let event = await checkEvent()
if(event === 'ok'){
this.$router.push({path: 'mybuyer/'+this.conformNum})
}else{
alert("出错啦!请刷新后重试!")
}
}
//设置定时器以更新
let timer = setInterval(checkConfirm, 3000)
// 通过$once来监听定时器,在beforeDestroy钩子时被清除。
this.$once('hook:beforeDestroy', () => {
clearInterval(timer)
})
}
自己写的方法测试了几次,得到了还算满意的结果。大致思路是:轮询10次,每3秒查询一次事件,每次10条,遍历对照操作以判断是否成功。从以上过程中基本可以得到函数是否正常上链的结果了!