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

如何通过Hardhat测试Solidity的fallback()函数

问题根因

Ethers.js 生成的合约实例会基于合约ABI做本地方法校验,你调用ABI中不存在的nonExistentFunction时,错误直接在JS层抛出,根本不会构造交易发送到链上,自然无法触发合约的fallback逻辑。

修复方案

放弃直接调用合约实例上不存在的方法,手动构造交易,传入不存在的函数选择器作为calldata,发送到合约地址即可触发fallback。修改后的测试代码如下:

const { expect } = require('chai');
const { ethers } = require('hardhat');

describe('Demo', () => {
  let deployer;
  let demoContract;
    
  before(async () => {
    [deployer] = await ethers.getSigners();
    const factory = await ethers.getContractFactory('Demo');
    demoContract = await factory.deploy().then((res) => res.deployed());
  });
    
  it('should invoke the fallback function', async () => {
    // 手动构造交易,calldata传入不存在的函数选择器即可
    const tx = await deployer.sendTransaction({
      to: demoContract.address,
      data: "0x53229aa6" // 为nonExistentFunction()计算出的4字节函数选择器,任意无效选择器都可触发fallback
    });
    // 等待交易上链拿到收据后再做事件断言
    await expect(tx.wait())
      .to.emit(demoContract, 'Error')
      .withArgs('call of a non-existent function');
  });
});

注意点

  • data字段不需要固定填示例值,只要传入的4字节前缀不匹配合约内任何已存在函数的选择器,都会触发fallback,比如填0xdeadbeef效果完全一致
  • 必须调用tx.wait()等待交易确认后再做事件校验,否则事件还未被链上执行抛出,断言会失败
  • 该写法兼容本地Hardhat网络与RSK测试网,不需要修改hardhat.config.js配置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 17:18:21