Solidity中如何限制仅合约B可调用合约A?
问题解答
首先明确:把合约B中的aContract设为private无法解决你的问题。原因很简单:合约A部署后,它的地址会作为链上公开数据存在(比如可以通过创建A的交易日志、区块数据查询到),即使B里的变量是private,外部依然能找到A的地址并直接调用它的public函数。private只是限制其他合约无法直接读取B中的aContract变量,但无法隐藏A本身的链上地址,也没法限制外部对A的调用。
要实现「仅合约B能调用合约A」的需求,必须在合约A内部添加权限控制,具体做法有两种:
方法一:在A中记录部署者(即合约B)的地址,添加调用校验
修改合约A,在构造函数中保存部署它的地址(也就是B的地址),然后在setDummy等需要限制的函数里检查调用者是否为该地址:pragma solidity ^0.8.17; contract A{ bool public dummy; address public immutable owner; // 用immutable节省gas constructor() { owner = msg.sender; // 部署时msg.sender是合约B的地址 } function setDummy (bool x) public{ require(msg.sender == owner, "Only contract B can call this"); dummy = x; } function getDummy () public view returns(bool){ return dummy; } } contract B { A private aContract; // 这里设为private不影响权限,只是隐藏变量,但A地址还是能查到 function initialize () public{ aContract = new A(); } }方法二:使用自定义的
onlyOwner修饰器
和方法一逻辑一致,只是用修饰器让代码更简洁:pragma solidity ^0.8.17; contract A{ bool public dummy; address public immutable owner; modifier onlyOwner() { require(msg.sender == owner, "Only contract B can call this"); _; } constructor() { owner = msg.sender; } function setDummy (bool x) public onlyOwner{ dummy = x; } function getDummy () public view returns(bool){ return dummy; } } contract B { A private aContract; function initialize () public{ aContract = new A(); } }
补充说明:即使把B中的aContract设为private,外部还是能通过链上分析找到A的地址,但因为A加了权限控制,外部调用setDummy会被拒绝,只有合约B调用时才会生效。这样就实现了你要的「仅合约B能操作A」的需求。
内容的提问来源于stack exchange,提问作者luca gualandi
相关产品推荐
相关产品推荐

