Eig*_*ice 4 ethereum solidity smartcontracts web3js
现在,任何人都可以setMyString调用FirstContract. 我试图将对该函数的访问限制为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");
}
}
Run Code Online (Sandbox Code Playgroud)
Solidity 目前没有一种简单的方法来根据接口验证地址。
您可以检查字节码,是否包含指定的签名(公共属性和方法的)。这需要比通常的 StackOverflow 答案更大的范围,所以我只是描述这些步骤而不是编写代码。
首先,定义您要查找的所需签名列表(名称和参数数据类型的 keccak256 哈希的第一个 4 字节)。您可以在我的其他答案中找到有关签名的更多信息(此处和此处)。
文档中的示例显示了如何获取任何地址(在您的情况下msg.sender)的字节码作为bytes(动态长度数组)。
然后,您需要循环返回的bytes数组并搜索 4 字节签名。
如果全部找到,则意味着msg.sender“实现了接口”。如果外部合约中缺少任何签名,则意味着它没有实现该接口。
但是......我真的建议您重新考虑白名单的方法。是的,您需要维护列表并setIsSecondContract()在新 成员第一次SecondContract想要调用该函数时调用。但对于s函数setMyString()的所有调用者来说,它的燃气效率更高,并且首先更容易编写和测试功能。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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1986 次 |
| 最近记录: |