Context
YourContract invokes a function in TargetContract. Only calls from the YourContract interface should be permitted.
Impl
- In your interface contract ⇒ Add supportsInterface selector
// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;
interface IYourContract {
function fSubmitRequest(bytes calldata _pData) external;
// ERC165: Add a function to expose interface detection
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
- In your implementation contract ⇒ Allow your interface contract id
// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;
import "./interfaces/IYourContract.sol";
contract YourContractImpl is IYourContract {
TargetContract public target;
// Implement ERC165's supportsInterface
function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
return interfaceId == type(IYourContract).interfaceId;
}
// Logic call the target contract
function fSubmitRequest(bytes calldata _pData) external override {
......LOGIC HERE......
target.fSubmit(_pData);
}
}
- How to use it in the target contract?
// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;
import "./interfaces/IYourContract.sol";
contract TargetContract {
/// @notice Logic
function fSubmit(bytes calldata _pData) external {
require(_onlyIYourContract(_msgSender()), "Invalid caller");
......LOGIC HERE......
}
/// @notice Check if the caller is allowed
function _onlyIYourContract(address account) private view returns (bool) {
(bool success, bytes memory data) = account.staticcall(
abi.encodeWithSelector(0x01ffc9a7, type(IYourContract).interfaceId) // 0x01ffc9a7 is ERC165.supportsInterface.selector
);
if (!success || data.length < 32) return false;
return abi.decode(data, (bool));
}
}