如何在Solidity中获取匿名事件的参数?
关于Solidity匿名事件无法获取参数的问题
刚接触Solidity匿名事件,写了个简单的Lock合约测试。部署后调用storeData方法时,非匿名事件能正常获取参数,但匿名事件拿不到参数。
合约代码
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"); 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() console.log(transactionReceipt.events[0]) } main().catch((error) => { console.error(error); process.exitCode = 1; });
现象说明
- 匿名事件:打印的日志仅显示事件基础结构,无法看到
admin和data的具体参数值 - 非匿名事件:日志中可直接看到
admin(调用者地址)和data(传入的10)的参数内容
原因解析
Solidity里的anonymous关键字会让事件不被写入ABI文件,而ethers.js这类工具依赖ABI来自动映射事件参数的名称和值。没有ABI的签名信息,直接打印transactionReceipt.events[0]自然解析不出参数详情。
但匿名事件的参数并非完全不可获取:
- indexed参数(比如示例中的
data):会被放在topics数组里,可直接从对应位置解析哈希值 - 非indexed参数(比如示例中的
admin):需要从data字段手动解码,前提是你清楚参数的类型和顺序
手动解析匿名事件参数示例
如果需要获取匿名事件的参数,可以修改部署脚本手动解码:
async function main() { const hre = require("hardhat"); const { ethers } = hre; const Lock = await ethers.getContractFactory("Lock"); const lock = await Lock.deploy(); await lock.deployed(); console.log(` deployed to ${lock.address}`); const tx = await lock.storeData(10); const transactionReceipt = await tx.wait(); const event = transactionReceipt.events[0]; // 解码非indexed参数(admin) const [admin] = ethers.utils.defaultAbiCoder.decode(["address"], event.data); // 解码indexed参数(data) const data = ethers.BigNumber.from(event.topics[0]); console.log("解析后的参数:"); console.log("admin:", admin); console.log("data:", data.toString()); }
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

