You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Hardhat解码合约匿名事件得到空数组,求问题排查

问题:解码合约中的匿名事件得到空数组,哪里出错了?

我用Hardhat开发合约,编写了一个带匿名事件的简单合约,但尝试解码事件日志时得到的结果是空数组,求帮忙排查问题。

合约代码

pragma solidity ^0.8.9;
contract Lock {

   event DataStored(address admin, uint256 indexed data) anonymous;
   uint256 data;
   function storeData(uint256 data) external {
      data = data;
      emit DataStored(msg.sender, data);

   }
}

部署脚本(deploy.js)

const hre = require("hardhat");
const contract = require("../artifacts/contracts/Lock.sol/Lock.json");
const abiDecoder = require('abi-decoder');

async function main() {
  const Lock = await hre.ethers.getContractFactory("Lock");
  const lock = await Lock.deploy();

  await lock.deployed();

  console.log(
    ` deployed to ${lock.address}`
  );
  tx = await lock.storeData(10);
  const transactionReceipt = await tx.wait()
  abiDecoder.addABI(contract.abi);
  const decodedLogs = abiDecoder.decodeLogs(transactionReceipt.events);
  console.log(transactionReceipt.events)
  console.log(decodedLogs);
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

运行结果

deployed to 0x21dF544947ba3E8b3c32561399E88B52Dc8b2823
[]

问题原因与修复方案

1. 匿名事件的日志存储位置错误

匿名事件没有事件签名,ethers.js不会将其解析到交易回执的events字段中,而是存放在logs字段里。你当前代码用transactionReceipt.events获取日志,自然得到空数组。

2. 合约状态变量赋值逻辑错误

合约中storeData函数里的data = data;是将函数参数赋值给自己,并没有修改合约的状态变量uint256 data;。如果需要更新合约状态,应该改为this.data = data;,或者给状态变量重命名避免混淆:

uint256 public storedData;
function storeData(uint256 data) external {
  storedData = data;
  emit DataStored(msg.sender, data);
}

修正后的部署脚本

将transactionReceipt.events替换为transactionReceipt.logs:

const hre = require("hardhat");
const contract = require("../artifacts/contracts/Lock.sol/Lock.json");
const abiDecoder = require('abi-decoder');

async function main() {
  const Lock = await hre.ethers.getContractFactory("Lock");
  const lock = await Lock.deploy();

  await lock.deployed();
  console.log(` deployed to ${lock.address}`);

  tx = await lock.storeData(10);
  const transactionReceipt = await tx.wait();
  
  abiDecoder.addABI(contract.abi);
  // 改用logs字段获取匿名事件日志
  const decodedLogs = abiDecoder.decodeLogs(transactionReceipt.logs);
  
  console.log(transactionReceipt.logs);
  console.log(decodedLogs);
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

修正后的运行结果

此时会看到transactionReceipt.logs输出包含匿名事件的原始日志,decodedLogs也会正确解析出事件内容:

deployed to 0x21dF544947ba3E8b3c32561399E88B52Dc8b2823
[
  {
    address: '0x21dF544947ba3E8b3c32561399E88B52Dc8b2823',
    topics: [ '0x...' ],
    data: '0x...',
    // 其他日志元数据
  }
]
[
  {
    name: 'DataStored',
    events: [
      { name: 'admin', type: 'address', value: '0x你的钱包地址' },
      { name: 'data', type: 'uint256', value: 10 }
    ],
    address: '0x21dF544947ba3E8b3c32561399E88B52Dc8b2823'
  }
]

内容的提问来源于stack exchange,提问作者Jack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 18:31:03