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

Remix Solidity单元测试调用合约函数时sender未切换为指定账户问题

问题根因

你遇到的问题本质是Remix单元测试的调用模型和预期不符,核心有两个关键点:

  • 你在测试函数上加的/// #sender: account-1注解,仅作用于「外部账户调用测试合约的enterSuccessfullyMultipleEntrants方法」这一步,所以测试函数内的msg.sender确实是account1,符合你断言的结果。但你在测试函数内部调用lotto.enterDebug1时,发起调用的主体是测试合约本身的地址,所以LottoMock合约的enterDebug1方法拿到的msg.sender是测试合约地址,既不是account1也不是account0。
  • 你判断调用方是account0,大概率是在LottoMock的逻辑里误用了tx.origin来记录参与者。Remix执行单条测试用例时,会先执行beforeEach再执行测试函数,两个步骤是在同一个交易内完成的,你的beforeEach指定了调用方为account0,所以整个交易的tx.origin固定为account0,哪怕测试函数的msg.sender被设置为account1,tx.origin也不会变化,这就是你拿到account0的原因。

解决方案

如果要模拟不同外部账户调用LottoMock,不能直接在测试合约内调用LottoMock的方法,需要改用底层调用显式指定调用方:

function enterSuccessfullyMultipleEntrants() public payable {
    Assert.equal(lotto.getLotteryBalance(), uint256(500000000000000), "One user has already entered.");
    Assert.equal(lotto.getQuantityOfEntrants(), uint256(1), "Expecting an existing entry.");
    Assert.equal(msg.sender, TestsAccounts.getAccount(1), "Invalid sender");

    // 模拟account1调用enterDebug1方法
    address account1 = TestsAccounts.getAccount(1);
    (bool success, bytes memory returnData) = address(lotto).call{
        from: account1,
        value: 500000000000000
    }(abi.encodeWithSignature("enterDebug1()"));

    // 对应原来的try catch逻辑
    if (success) {
        Assert.ok(false, 'succeed unexpected');
    } else {
        if (returnData.length >= 4) {
            string memory reason = abi.decode(returnData[4:], (string));
            Assert.equal(reason, "debug", "debug.");
        } else {
            Assert.ok(false, 'failed unexpected');
        }
    }
    
    Assert.equal(lotto.getLotteryBalance(), uint256(1000000000000000), "expecting lottery balance equal to entrance fee for two users after entering");
    Assert.equal(lotto.getQuantityOfEntrants(), uint256(2), "second user should have successfully entered the lottery");
}

额外建议:除非你明确需要获取交易的最初发起方,否则不要在业务逻辑里使用tx.origin,改用msg.sender即可,既符合常规业务需求,也能避免tx.origin带来的安全风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 20:45:03