Ethereum 检查msg.sender是否为特定类型的合同

Ethereum 检查msg.sender是否为特定类型的合同,ethereum,solidity,smartcontracts,web3,Ethereum,Solidity,Smartcontracts,Web3,现在,任何人都可以调用FirstContract中的setMyString函数。我试图将对该函数的访问限制为SecondContract的一个实例。但不是一个特定实例,任何类型为SecondContract的契约都应该能够调用setMyString contract FirstContract{ String public myString; function setMyString(String memory what) public { myString=w

现在,任何人都可以调用
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");
    }
}

Solidity目前没有一种简单的方法来根据接口验证地址

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

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

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

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

如果您找到它们all,则表示
msg.sender
“实现接口”。如果外部合同中缺少任何签名,则意味着它没有实现接口


但是。。。我真的建议你重新考虑你的白名单方法。是的,当一个新的
想要第一次调用
setMyString()
函数时,您需要维护列表并调用
setIsSecondContract()
。但是对于
FirstContract
setMyString()
函数的所有调用者来说,它更高效,而且从一开始就更容易编写和测试功能

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;
    }
}