DEV Community

Cover image for Interfaces in Solidity
Shlok Kumar
Shlok Kumar

Posted on

Interfaces in Solidity

Solidity interfaces allow smart contracts to communicate without having to implement their functionality.

Solidity interfaces are a way to define the structure of a contract without implementing its functionality. They allow contracts to interact with each other in a standardized way, enabling composability between smart contracts. An interface is a contract that defines the function signatures but does not implement them. It acts as an agreement between itself and any contract that implements it. Interfaces can be used to interact with contracts that are already deployed on the blockchain. We need a way to call the functions of these contracts from our contract, and interfaces provide us with this capability.

Interfaces allow for composability between smart contracts, which means that one contract can utilize the solution or build upon it at its own discretion in a completely permissionless way. In Solidity, an interface acts as the contract or an agreement between itself and any contract that implements it. The point of these interfaces is to separate the declaration of the function from the actual behavior or definition of the function. Interfaces are a more restricted form of abstract contracts. They define only function signatures but not their implementation, which means they cannot have any state variables or functions with the implementation code.

Here's an example of how an interface can be defined in Solidity:

// Interface for ERC20 token standard
interface IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
}
Enter fullscreen mode Exit fullscreen mode

In this example, we define an interface for the ERC20 token standard. The interface declares the functions that must be implemented by any contract that wants to conform to this standard. To use an interface in your contract, you simply need to import it and declare a variable of its type:

import "./IERC20.sol";

contract MyContract {
  IERC20 public token;

  constructor(IERC20 _token) {
    token = _token;
  }

  // Use token.totalSupply(), token.balanceOf(), etc.
}
Enter fullscreen mode Exit fullscreen mode

In this example, we import the IERC20 interface and declare a public variable token of its type. We then pass an instance of IERC20 into our constructor and store it in token. We can now use token to call any of the functions declared in the IERC20 interface.

The use of an interface keyword results in the creation of an abstract contract, which is also referred to as a pure abstract contract. Interfaces are identical to abstract contracts. The only thing that interfaces include are declarations of functions; this means that the functions contained within interfaces do not have any statements, nor do they have definitions, nor do they have state variables, nor do they have constructors. Only the external type can be used for functions of the Interface. They are allowed to inherit from other interfaces, but not from other contracts. You can access enums and structs that are contained within an interface by using the dot notation that corresponds to the name of the interface.

Example 1 -

pragma solidity 0.8.0;

// A simple interface
interface simpleInterface{

     // Functions having only
     // declaration not definition
     function getStr(
     ) public view returns(string memory);
     function setValue(
     uint num1, uint num2) public;
     function add(
     ) public view returns(uint);
}

// Contract that implements interface
contract childContract is simpleInterface{

     // Private variables
     uint private num1;
     uint private num2;

     // Function definitions of functions
     // declared inside an interface
     function getStr(
     ) public view returns(string memory){
           return "Blockchain";
     }
     
     // Function to set the values
     // of the private variables
     function setValue(
     uint num1, uint num2) public{
           num1 = num1;
           num2 = num2;
     }
     
     // Function to add 2 numbers
     function add(
     ) public view returns(uint){
           return num1 + num2;
     }
     
}
contract call{
     
     //Creating an object
     InterfaceExample obj;

     function call() public{
           obj = new thisContract();
     }
     
     // Function to print string
     // value and the sum value
     function getValue(
     ) public returns(uint){
           obj.getStr;
           obj.setValue(10, 16);
           return obj.add();
     }
}
Enter fullscreen mode Exit fullscreen mode

Example 2 -

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Counter {
    uint public count;

    function increment() external {
        count += 1;
    }
} 

interface ICounter {
    function count() external view returns (uint);

    function increment() external;
} 

contract MyContract {
    function incrementCounter(address _counter) external {
        ICounter(_counter).increment();
    }

    function getCount(address _counter) external view returns (uint) {
        return ICounter(_counter).count();
    }
}
Enter fullscreen mode Exit fullscreen mode

For more content, follow me at - https://linktr.ee/shlokkumar2303

Top comments (0)