本文介绍了检查msg.sender是否为特定类型的合同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在,任何人都可以调用FirstContract中的setMyString函数。我正在尝试将对该函数的访问限制为SecondContract的一个实例。但不是一个特定的实例,任何SecondContract类型的协定都应该能够调用setMyString

contract FirstContract{
    String public myString;

    function setMyString(String memory what) public {
        myString=what;
    }
}

contract SecondContract{
    address owner;
    address firstAddress;
    FirstContract firstContract;
    constructor(address _1st){
        owner=msg.sender;
        firstAddress=_1st;
        firstContract=FirstContract(firstAddress);
    }
    function callFirst(String memory what){
        require(msg.sender==owner);
        firstContract.setMyString("hello");
    }
}

推荐答案

Solity当前没有根据接口验证地址的简单方法。

您可以检查字节码,看它是否包含(公共属性和方法)指定的签名。与通常的StackOverflow答案相比,这需要更大的范围,因此我将只描述步骤,而不是编写代码。

首先,定义要查找的签名列表(名称和参数数据类型的前4个字节的keccak256散列)。您可以在我的其他答案herehere中找到有关签名的更多信息。

documentation中的一个示例显示如何将任何地址(在您的示例中为msg.sender)字节码作为bytes(动态长度数组)。

然后您需要遍历返回的bytes数组并搜索4字节签名。

如果您发现它们都全部,则表示msg.sender";实现了接口";。如果外部合同中缺少任何签名,则表示它没有实现该接口。


但是...我真的建议你重新考虑一下你加入白名单的方法。是的,当newSecondContract想要第一次调用setMyString()函数时,您需要维护列表并调用setIsSecondContract()。但是对于FirstContractsetMyString()函数的所有调用者来说,它更省油,而且更容易编写和测试功能。

contract FirstContract{
    String public myString;
    
    address owner;
    mapping (address => bool) isSecondContract;
    
    modifier onlySecondContract {
        require(isSecondContract[msg.sender]);
        _;
    }
    
    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }
    
    function setIsSecondContract(address _address, bool _value) public onlyOwner {
        isSecondContract[_address] = _value;
    }

    function setMyString(String memory what) public onlySecondContract {
        myString=what;
    }
}

这篇关于检查msg.sender是否为特定类型的合同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-14 16:05