在Hardhat中如何从ethers交易收据中获取触发的事件日志?
原因说明
你调用randomSVG.create()返回的tx是TransactionResponse对象,仅代表交易已被广播到链上,还未完成区块确认,因此不存在logs字段。日志数据仅存在于交易被打包确认后的TransactionReceipt对象中。
解决方法
方法1:等待交易确认后从收据中读取(最常用)
调用交易响应的wait()方法等待交易确认,默认会等待1个区块确认,返回的收据对象会自动包含解析好的合约事件:
const randomSVG = new ethers.Contract(RandomSVG.address, RandomSVGContract.interface, signer) // 发送交易获取交易响应 let tx = await randomSVG.create() // 等待交易确认,获取交易收据 const receipt = await tx.wait() // ethers会基于合约ABI自动解析事件,存储在receipt.events字段 const targetEvent = receipt.events.find(item => item.event === "requestedRandomSVG") // 直接从args中读取事件参数 const requestId = targetEvent.args.requestId console.log("requestId:", requestId)
如果需要读取未解码的原始日志,可以直接访问receipt.logs字段,再通过合约接口手动解码:
const parsedLog = randomSVG.interface.parseLog(receipt.logs[0]) console.log(parsedLog.args.requestId)
方法2:通过合约事件监听获取
如果需要实时捕获事件,可以提前注册事件监听器:
const randomSVG = new ethers.Contract(RandomSVG.address, RandomSVGContract.interface, signer) // 注册单次事件监听 randomSVG.once("requestedRandomSVG", (requestId, event) => { console.log("捕获到requestedRandomSVG事件,requestId为:", requestId) }) // 发送交易 const tx = await randomSVG.create() await tx.wait()
注意事项
请确保传入合约构造函数的ABI中已经包含requestedRandomSVG事件的定义,否则ethers无法自动完成事件解析。
内容的提问来源于stack exchange,提问作者Patrick Collins
相关产品推荐
相关产品推荐

