• web3获取所有事件日志与解码


    获取所有事件&解析参数

    封装获取所有事件的方法

    const getEvents = (address, topic0, fromBlock = 1) => {
        return new Promise((resolve, reject) => {
          axios({
            method: 'get',
            url: `https://api.hecoinfo.com/api?module=logs&action=getLogs
    &fromBlock=${fromBlock}
    &toBlock=latest
    &address=${address}
    &topic0=${topic0}
    &apikey=982S8JF95E4K4J46SMA2Y4I93UZH5WRMIC`
          }).then(async res => {
            let result = res.data.result
            if (result.length >= 1000) {
              result = result.concat(await getEvents(address, topic0, Number(result[result.length - 1].blockNumber+1)))
            } else {
              resolve(result)
            }
          }).catch((e) => {
            reject()
          })
        })
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    使用

    import {getWeb3 as getClientWeb3, Contract as ClientContract} from '@chainstarter/multicall-client.js'
    
    //事件名称
    const eventName = 'CreatePropose'
    const web3 = getClientWeb3(ChainId.HECO)
    // 事件abi
    const eventAbi = abis.find(item => item.name === eventName && item.type === 'event')
    // 获取事件topic0
    const topic0 = web3.eth.abi.encodeEventSignature(eventAbi)
    // 获取eventName所有事件
    const datas = await getEvents(voteMain.address, topic0, 1)
    
    const eventsData= []
    // 解析参数
    for (let i = 0; i < datas.length; i++) {
          const eventItem = web3.eth.abi.decodeLog(eventAbi.inputs, datas[i].data,
            datas[i].topics.slice(1))
          eventsData.push(eventItem)
          calls.push(voteNFTContract.tokenURI(eventItem.NFTtokenId))
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    获取所有事件,用的是浏览器api

    文档地址:https://hecoinfo.com/apis#logs

    虽然不限制块高度,但是api数据返回最高1000条,值得注意的是,一个块中可能存在多个事件,如果要严谨一点,将 Number(result[result.length - 1].blockNumber+1) 的+1去掉,然后将结果进行去重即可


    获取topic0,encodeEventSignature

    通过web3.eth.abi.encodeEventSignature(eventName);


    解析log data 使用 decodeLog

    通过web3.eth.abi.decodeLog(inputs, hexString, topics);

    注意,参数 3 topics,带有日志索引参数的topic的数组,如果是非匿名事件则不带topics[0],否则带topics[0]

    像以下这种,是带有日志索引参数的 indexed

    event CreatePropose(uint indexed propID, string  subject,string  content,uint NFTtokenId,  uint iwoAmountUSDT,uint warPrice,uint stakeAmount,uint begin);
    
    • 1

    通过getPastEvents获取事件

    import {getWeb3} from "@chainstarter/multicall-client.js";
    const web3 = getWeb3(ChainId.BSC)
    var contract = new web3.eth.Contract(contractABI, adderss);
    //get event
    contract.getPastEvents('EventA', {filter: {}, fromBlock: 10000, toBlock: 'latest'}).then((res) => {
      console.log(res)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    获取所有事件同理,先获取最新的块高度,因为每次最多只能查5000个块,所以每次fromBlock与toBlock递增查询,当需要查询很多块的时候,这将不适用,不建议使用,但是用来监听最新块,用这个方法还是挺好的

    方法参数解码

    const funcName = 'claim'
    const funcAbi = abis.find(item => item.name === funcName && item.type === 'function')
    const encodeFunS = web3.eth.abi.encodeFunctionSignature(funcAbi)
    const paramsData = '0x' + decodeParams.replace(encodeFunS, '')
    const data = web3.eth.abi.decodeParameters(funcAbi.inputs, '0x0.........')
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    Docker面试整理-Docker镜像和容器有什么区别?
    Python实现XMind测试用例快速转Excel用例
    react native 使用阿里字体图标库
    css通过行内样式绑定背景图片
    CRM客户管理系统主要用途
    跨域(浏览器)
    MAC 使用内置Apache 运行PHP
    面试官问我为啥B+树一般都不超过3层?3层B+树能存多少数据?
    MQ通道常用知识列举(一)
    FastJson2.0介绍和使用
  • 原文地址:https://blog.csdn.net/weixin_43840202/article/details/126162945