[英]Check if msg.sender is a specific type of contract
As it is now, anyone can call the setMyString
function in the FirstContract
.现在,任何人都可以在
FirstContract
中调用setMyString
function 。 I'm trying to restrict access to that function to an instance of SecondContract
.我正在尝试将对 function 的访问限制为
SecondContract
的实例。 But not one specific instance, any contract of type SecondContract
should be able to call setMyString
.但不是一个特定的实例,任何
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 currently doesn't have an easy way to validate an address against an interface. Solidity 目前还没有一种简单的方法可以根据接口验证地址。
You can check the bytecode, whether it contains the specified signatures (of the public properties and methods).您可以检查字节码,它是否包含(公共属性和方法的)指定签名。 This requires a bit larger scope than a usual StackOverflow answer, so I'm just going to describe the steps instead of writing the code.
这需要比通常的 StackOverflow 答案大一点的 scope,所以我只描述步骤而不是编写代码。
First, define the desired list of signatures (1st 4 bytes of keccak256 hash of the name and arguments datatypes) that you're going to be looking for.首先,定义您要查找的签名列表(名称的 keccak256 hash 和 arguments 数据类型的第一个 4 个字节)。 You can find more info about signatures in my other answers here and here .
您可以在此处和此处的我的其他答案中找到有关签名的更多信息。
An example in the documentation shows how to get any address's (in your case msg.sender
) bytecode as bytes
(dynamic-length array). 文档中的一个示例显示了如何将任何地址(在您的情况下为
msg.sender
)字节码作为bytes
(动态长度数组)获取。
You'll then need to loop through the returned bytes
array and search for the 4-byte signatures.然后,您需要遍历返回的
bytes
数组并搜索 4 字节签名。
If you find them all , it means that msg.sender
"implements the interface".如果全部找到,则意味着
msg.sender
“实现了接口”。 If any of the signatures is missing in the external contract, it means it doesn't implement the interface.如果外部合约中缺少任何签名,则意味着它没有实现接口。
But... I'd really recommend you to rethink your approach to whitelisting.但是......我真的建议你重新考虑你的白名单方法。 Yes, you'll need to maintain the list and call
setIsSecondContract()
when a new SecondContract
wants to call the setMyString()
function for the first time.是的,当新的
SecondContract
想要第一次调用setMyString()
function 时,您需要维护列表并调用setIsSecondContract()
。 But it's more gas efficient for all callers of the FirstContract
's setMyString()
function, as well as easier to write and test the functionality in the first place.但是对于
FirstContract
的setMyString()
function 的所有调用者来说,它的 gas 效率更高,并且首先更容易编写和测试功能。
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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.