solidity – Understanding Interfaces in Contracts – Detailed Explanation

interfacessolidity

Recently, I have stumbled upon multiple examples of Solidity contracts that make use of Interfaces, yet seem to define an interface for one and one contract only. Said Interface is then defined in the same file as the contract itself. For example:

interface Icontract {
    function myFunction() public returns (bool);
}

contract MyContract is Icontract {
    function myFuntion public returns (bool) {
        return true;
    }
}

All that published in the same source file.

While I understand the use of Interfaces in general, this seems like a useless addition to me. In my understanding, defining and publishing an interface contract allows other solidity contracts to use it. Anyhow, this way, the interface itself would be only usable with the (concrete) contract itself. This seems as if the interface is specifically defined for describing the public functions of the concrete contract, without the intention of being implemented by multiple other contracts.

Am I missing something here? What is the use of defining an Interface in Solidity in this way?

Best Answer

You're correct, they can be used under an inheritance model as you pointed out above. Also take for example the IERC20 interface which is both used for almost every token and also to define other interfaces such as IERC20Metadata. Inheriting from an interface forces you to define implementations for those methods too.

But another feature is that they provide an interface for your Contract to interact with already deployed ones such as the UniswapRouter.

// https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/interfaces/IUniswapV2Router02.sol
import "./../interfaces/IUniswapV2Router.sol"; 

contract MyContract {

   address UNISWAP_V2_ROUTER = 0x....;

    function swap(...) external {
        uint[] memory out_amounts = IUniswapV2Router02(UNISWAP_V2_ROUTER).swapExactTokensForTokens(
            amount, // amountIn
            minOut, //The minimum amount we want to receive, taking into account slippage
            path, // Path
            beneficiary, // To address
            block.timestamp + 60 // Deadline
        );

    }

}

The approach without using interfaces would be a direct .call() using abi.encodeWithSignature, which is uglier and more difficult to work with.

Related Topic