波场中监听事件的方法 / 学习智能合约#31

Words
358
Reading
2 min
Listen
Play
6y

tron

事件event一般是智能合约中的日志,你每调用一个方法,它执行后会得到什么结果呢:是成功还是失败?这一般可以通过事件来得到确定的答案。虽然在send()方法中有个shouldPollResponse设置为true参数,但是得到它的结果要等待60秒,这时间有点太感人了!回到事件的方法,这估计是确定性的最好方案了。

watch监听事件

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条,遍历对照操作以判断是否成功。从以上过程中基本可以得到函数是否正常上链的结果了!

波场中监听事件的方法 / 学习智能合约#31 | Ecency