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

Posted 【03】

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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()
      )
    )
  

使用

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))
    

获取所有事件,用的是浏览器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);

通过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)
)

获取所有事件同理,先获取最新的块高度,因为每次最多只能查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.........')

如何获取事件日志 Web3.py?

【中文标题】如何获取事件日志 Web3.py?【英文标题】:How to get event log Web3.py? 【发布时间】:2021-03-03 02:02:42 【问题描述】:

我正在使用solidity 0.7.4、web3.py 5.12.2 和python 3.7。

我正在使用 Windows 10。

我的目标是在solidity函数中发出一个事件,以便在函数执行后检索日志。

这是我的活动event logString(string arg);

这就是我发出事件emit logString("example string");的方式

在 Remix 上它可以工作,我可以在事务日志中检索我发出的字符串。

当我在 Python 上尝试时,它不起作用。

这是我的 Python 代码:

web3_instance = Web3(HTTPProvider("http://"+host+":"+port, request_kwargs='timeout': timeout))
Platform_contract= web3_instance.eth.contract(address=contract_address, abi=abi, bytecode=bytecode)
coinbase= web3_instance.eth.coinbase
functions= Platform_contract.functions

tx_hash =functions.market_clearing(n_clearings, t_clearing_first,supplier_bids,uniform_pricing,discriminative_pricing).transact('from': coinbase)
tx_receipt = web3_instance.eth.getTransactionReceipt(tx_hash)

log_to_process = tx_receipt['logs'][0]
processed_log = Platform_contract.events.logString().processLog(log_to_process)
log = processed_log['args']['arg']

很遗憾,tx_receipt['logs'] 是空的,我得到了一个异常。

您知道如何检索事件日志吗?

【问题讨论】:

【参考方案1】:

我设法解决了这个问题。我不知道为什么,我必须在 truffle config.js 中准确指定 network_id。然后我再次迁移合约并在该特定 network_id 上运行 ganache-cli。

【讨论】:

以上是关于web3获取所有事件日志与解码的主要内容,如果未能解决你的问题,请参考以下文章

Web3js 小笔记

Web3.js getBlock() 将所有块都作为待处理

使用 web3 和 go-ethereum 在私有以太坊区块链上打开和进行交易时未捕获(承诺)错误

谈谈吓坏马斯克的 ChatGPT 与沸腾的 Web3 AI 赛道

为什么 Web3 与区块链有关

区块链,数字货币,元宇宙,NFT,web3.0都是个啥?