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

Solidity如何使用chai测试函数是否被其他合约调用

结论

chai-spy 无法直接实现该测试需求。
chai-spy是面向JavaScript/TypeScript运行环境的函数监听工具,仅能捕获JS上下文内的函数调用行为,无法感知EVM执行层中Solidity合约之间的内部消息调用,因此不能直接用来验证链上合约的跨合约调用逻辑。

原因说明

你在JS测试代码中拿到的ContractA实例,本质上是web3/ethers.js封装的链上合约通信代理,仅能处理你从JS层主动发起的对ContractA的调用。当你调用ContractB的shouldCallA方法时,整个调用逻辑会被提交到EVM中执行:ContractB对ContractA的调用是EVM内部的消息传递,完全在节点执行层完成,不会走JS层的合约代理对象,因此你用chai-spy给JS层的ContractA方法打的监听桩完全不会被触发。

可行的实现方案
  • 方案1:使用Solidity测试框架配套的链上调用断言
    这是最便捷的实现方式,Hardhat、Waffle等常用Solidity测试框架都提供了配套的chai断言插件,可以直接捕获EVM执行过程中的跨合约调用行为,不需要修改业务合约代码。
    测试示例代码:
    const { expect } = require("chai");
    const { ethers } = require("hardhat");
    // 引入框架配套的chai匹配器后即可使用链上调用断言
    require("@nomicfoundation/hardhat-chai-matchers");
    
    describe("ContractB 调用测试", () => {
      it("调用shouldCallA时应当触发ContractA的shouldBeCalledByOthers方法", async () => {
        // 部署测试合约
        const ContractA = await ethers.getContractFactory("ContractA");
        const contractA = await ContractA.deploy();
        await contractA.deployed();
    
        const ContractB = await ethers.getContractFactory("ContractB");
        const contractB = await ContractB.deploy(contractA.address);
        await contractB.deployed();
    
        // 核心断言:调用B的方法时,会按预期调用A的目标方法
        await expect(contractB.shouldCallA()).to.call(contractA, "shouldBeCalledByOthers");
      });
    });
    
  • 方案2:通过事件埋点验证调用
    这是兼容性最强、最稳妥的验证方式,不需要依赖框架的底层调用捕获能力。只需要在被调用的shouldBeCalledByOthers方法入口添加事件触发逻辑,测试时验证对应事件被抛出即可证明方法被调用。
    改造后的ContractA示例:
    contract ContractA {
      // 定义调用标记事件
      event CalledByOther(address caller);
    
      function shouldBeCalledByOthers() external {
        // 方法入口抛出事件
        emit CalledByOther(msg.sender);
        // 原有业务逻辑
      }
    }
    
    测试时直接断言调用shouldCallA的交易中抛出了CalledByOther事件即可。
  • 方案3:使用链上合约Mock工具
    如果需要更灵活的打桩、调用统计能力,可以使用专门适配EVM环境的合约Mock工具(比如Smock),这类工具可以在EVM层生成合约的mock实例,功能和JS层的spy一致,可以统计mock合约方法的调用次数、入参,也可以自定义方法返回值,完全满足跨合约调用的验证需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:33:29