Solidity合约Fallback触发的事件未在Ganache及测试中显示的问题
问题分析与解决方案
1. 合约代码笔误修正
你的ContractB中变量类型定义错误,BookTicket应该改为ContractA,否则会出现类型不匹配问题:
contract ContractB { ContractA public targetContract; // 修正类型错误 constructor(address _targetContract) { targetContract = ContractA(payable(_targetContract)); } function callFallbackUsingSignature() public { (bool success,) = address(targetContract).call(abi.encodeWithSignature("nonExistingFunction()")); require(success); } }
2. 测试用例的正确写法
你之前的测试用例错误地使用了await包裹函数调用,导致断言逻辑失效(无论参数对错都会通过)。正确的写法是直接传递函数调用的Promise给expect,让测试框架监听交易的事件流:
const { ethers } = require("hardhat"); it("正确触发并验证logMsgData事件", async function () { // 计算fallback接收到的msg.data:对应nonExistingFunction()的ABI编码 const expectedMsgData = ethers.utils.abi.encodeWithSignature("nonExistingFunction()"); const expectedMsgValue = 0; // 注意:不要用await包裹contractB.callFallbackUsingSignature() await expect(contractB.callFallbackUsingSignature()) .to.emit(contractA, "logMsgData") .withArgs(expectedMsgData, expectedMsgValue); });
3. Ganache中查看事件的方法
Ganache默认只显示顶层交易的日志,而logMsgData是在ContractA(被调用的合约)中发射的,属于内部交易的日志。你需要:
- 在Ganache的交易列表中找到
callFallbackUsingSignature()对应的交易 - 展开该交易的Internal Transactions面板
- 找到
ContractB调用ContractA的内部交易条目,查看其Logs就能看到logMsgData事件
关键错误点总结
- 合约类型定义笔误导致潜在的调用异常
- 测试用例误用
await,使得事件断言逻辑未正确生效 - Ganache中需查看内部交易日志才能看到被调用合约的事件
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

