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

非Owner身份下ContractB调用ContractA的set_data函数失败求助

问题原因

ContractA的set_data函数通过require(owner == msg.sender)限制只有合约部署者(owner)能调用。当你用ContractB调用该函数时,msg.sender是ContractB的合约地址,而非ContractA的owner地址,因此触发权限校验失败。

解决方案

方案1:修改ContractA的代码(推荐)

通过调整权限逻辑,允许ContractB调用set_data,以下是两种可行方式:

方式1:添加白名单机制

修改ContractA,新增可调用地址列表,允许指定合约调用:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

contract contractA{
    string data;
    uint public blocknumber;
    address public owner;
    mapping(address => bool) public allowedCallers; // 白名单映射

    constructor() payable {
        owner = msg.sender;
        allowedCallers[owner] = true; // 默认owner在白名单
    }

    // owner可添加允许调用的地址
    function addAllowedCaller(address _caller) public {
        require(owner == msg.sender, "Only owner can add callers");
        allowedCallers[_caller] = true;
    }

    function set_data(string memory _data) public {
        require(allowedCallers[msg.sender], "You are not allowed to call this function");
        data = _data;
        blocknumber = block.number;
    }
}

使用步骤:

  • 重新部署修改后的ContractA
  • 调用addAllowedCaller将ContractB的地址加入白名单
  • 此时ContractB调用set_data即可成功

方式2:使用标准权限管理

借助OpenZeppelin的Ownable合约实现更规范的权限控制,支持owner授权其他地址调用:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@openzeppelin/contracts/access/Ownable.sol";

contract contractA is Ownable {
    string data;
    uint public blocknumber;

    constructor() payable Ownable() {} // 继承Ownable,owner自动设为部署者

    function set_data(string memory _data) public onlyOwner {
        data = _data;
        blocknumber = block.number;
    }
}

使用步骤:

  • 部署ContractA后,调用transferOwnership将权限转移给ContractB地址
  • 若不想转移owner权限,可改用AccessControl合约自定义"Setter"角色,支持多地址调用

方案2:无法修改ContractA的情况

如果不能修改ContractA的代码,无法实现非owner身份让ContractB调用set_data——因为该函数的权限校验是硬编码的仅owner可调用。唯一可行的操作是将ContractB的地址设置为ContractA的owner(前提是ContractA有transferOwnership函数),但这会让原owner失去控制权,需谨慎操作。

你的代码小问题

ContractB中contractA public new;存在命名错误:new是Solidity的关键字,不能作为变量名,建议修改为contractA public contractAInstance;以避免编译错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 11:42:28