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

使用truffle test测试Gaming合约时遇owner成员查找错误求助

问题:Truffle测试Gaming合约时出现Owner成员不可访问错误

使用truffle test测试Gaming合约时触发如下错误:

TypeError: Member "owner" not found or not visible after argument-dependent lookup in contract Gaming

错误出现在测试代码的owner = gaming.owner();行。


Gaming.sol 合约代码

pragma solidity ^0.5.0;

contract Gaming {
    /* Our Online gaming contract */
    address owner;
    bool public online;

    struct Player {
        uint wins;
        uint losses;
    }

    mapping (address => Player) public players;

    constructor() public payable {
        owner = msg.sender;
        online = true;
    }

    modifier isOwner() {
        require(msg.sender == owner, "Only owner can call this function");
        _;
    }

}

TestGaming.sol 测试代码

pragma solidity ^0.5.0;

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/Gaming.sol";

contract TestGaming {
    uint public initialBalance = 10 ether;
    Gaming gaming;
    address owner;

    function beforeAll() public {
        gaming = Gaming(DeployedAddresses.Gaming());
        owner = gaming.owner();

    }

    function testWithdrawFunds() public {
        uint ownerBalanceBefore = owner.balance;
        gaming.withdrawFunds();
        uint ownerBalanceAfter = owner.balance;

        Assert.equal (initialBalance, ownerBalanceAfter - ownerBalanceBefore, "The owner's balance should have increased by 10 ether");
}

解决方案

  1. 核心问题原因
    Solidity中未显式指定可见性的状态变量默认是internal级别,外部合约(包括测试合约)无法直接访问。Gaming合约中的owner变量没有设置可见性,因此测试合约无法调用gaming.owner()获取它。

  2. 修复方法(二选一)

  • 方法一:将owner变量设为public
    修改Gaming.sol中的address owner;为:
address public owner;

Solidity会自动为public变量生成对应的owner() getter函数,测试代码无需修改即可正常调用。

  • 方法二:手动实现getOwner函数
    如果不想将owner变量直接设为public,可以在Gaming合约中添加一个public的getter函数:
function getOwner() public view returns(address) {
    return owner;
}

然后将测试代码中的owner = gaming.owner();改为:

owner = gaming.getOwner();
  1. 额外修复:补充withdrawFunds函数
    测试代码中调用了gaming.withdrawFunds(),但Gaming合约中并未实现该函数,需要补充:
function withdrawFunds() public isOwner {
    payable(owner).transfer(address(this).balance);
}

注意:Solidity 0.5.x中需要显式将owner转为payable类型才能执行转账操作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 02:36:22