簡體   English   中英

檢查 msg.sender 是否是特定類型的合約

[英]Check if msg.sender is a specific type of contract

現在,任何人都可以在FirstContract中調用setMyString function 。 我正在嘗試將對 function 的訪問限制為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 答案大一點的 scope,所以我只描述步驟而不是編寫代碼。

首先,定義您要查找的簽名列表(名稱的 keccak256 hash 和 arguments 數據類型的第一個 4 個字節)。 您可以在此處此處的我的其他答案中找到有關簽名的更多信息。

文檔中的一個示例顯示了如何將任何地址(在您的情況下為msg.sender )字節碼作為bytes (動態長度數組)獲取。

然后,您需要遍歷返回的bytes數組並搜索 4 字節簽名。

如果全部找到,則意味着msg.sender “實現了接口”。 如果外部合約中缺少任何簽名,則意味着它沒有實現接口。


但是......我真的建議你重新考慮你的白名單方法。 是的,當SecondContract想要第一次調用setMyString() function 時,您需要維護列表並調用setIsSecondContract() 但是對於FirstContractsetMyString() 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM