Learning Objectives – after this chapter you will be able to:
  • Declare an interface and list its restrictions.
  • Implement an interface in a contract.
  • Call another deployed contract through its interface.
  • Compare interfaces with abstract contracts.
What is an Interface?
  • In programming, an interface separates what a component can do (function declarations) from how it does it (implementation).
  • In Solidity an interface is a contract-like declaration that lists functions without bodies. Any contract that implements it promises to provide those functions.
  • It acts as the skeleton of a smart contract: other developers can build on it and be sure which functions exist and what they accept and return.
  • Interfaces are declared with the interface keyword and, by convention, their names start with I (e.g. IERC20).
Why do we use Interfaces?
  • To interact with existing contracts on the blockchain without having their source code – you only need the function signatures and the contract address, e.g. reading any ERC-20 token’s balance through IERC20.
  • To define standards: token standards such as ERC-20 and ERC-721 are expressed as interfaces, and libraries like OpenZeppelin provide ready implementations to customise.
  • To decouple code: a contract can depend on an interface, so different implementations can be used without changing the caller.
Interface Restrictions

Interfaces are a more restricted form of abstract contract. They:

  • cannot declare state variables;
  • cannot declare a constructor;
  • cannot declare modifiers;
  • cannot implement any function – functions have no body;
  • must declare all functions as external;
  • cannot inherit from contracts, but can inherit from other interfaces.

Interfaces may declare events, custom errors, structs and enums. All interface functions are implicitly virtual, so implementing functions do not need to repeat it.

Interface vs Abstract Contract
FeatureInterfaceAbstract contract
Implemented functionsNot allowedAllowed (some may be unimplemented)
State variablesNot allowedAllowed
Constructor / modifiersNot allowedAllowed
Function visibilityexternal onlyAny
Can be deployed?NoNo
Example : Declare, Implement and Use an Interface
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface ICounter {
    event Incremented(uint newValue);
    function increment() external;
    function count() external view returns (uint);
}

// implementing the interface
contract Counter is ICounter {
    uint private value;

    function increment() external override {
        value += 1;
        emit Incremented(value);
    }

    function count() external view override returns (uint) {
        return value;
    }
}

// using ANY contract that follows ICounter, knowing only its address
contract CounterUser {
    function bump(address counterAddress) external returns (uint) {
        ICounter c = ICounter(counterAddress);   // wrap the address in the interface
        c.increment();
        return c.count();
    }

    function counterInterfaceId() external pure returns (bytes4) {
        return type(ICounter).interfaceId;       // used by ERC-165 interface detection
    }
}
Key Takeaways
  • An interface lists external function declarations only – no state, constructor, modifiers or bodies.
  • Wrap an address in an interface (ICounter(addr)) to call another contract.
  • Token standards (ERC-20, ERC-721) are defined as interfaces.
Download | Print      E-Notes

The PDF E-Notes are the earlier printable version of this chapter. The notes on this page are the latest, revised version.

Video : Interfaces in Solidity
Resource File
Question / Answer (15 questions)

Answer : An interface is a contract-like declaration, written with the interface keyword, that lists function signatures without implementations. Contracts that implement it must provide those functions.

Answer : Interfaces let contracts interact with other deployed contracts using only their function signatures and address, define common standards such as ERC-20, reduce code duplication and allow different implementations to be swapped without changing the caller.

Answer : No state variables, no constructor, no modifiers, no function implementations, and all functions must be external. They also cannot inherit from contracts (only from other interfaces).

Answer : Events, custom errors, structs and enums.

Answer : By inheriting from it with is and providing every declared function, e.g. contract Counter is ICounter { function increment() external override { ... } }.

Answer : Convert its address to the interface type and call the function: ICounter(addr).increment();.

Answer : Yes, interfaces can inherit from other interfaces, but not from contracts.

Answer : An abstract contract may contain state variables, a constructor, modifiers and implemented functions, with at least one function possibly left unimplemented. An interface contains only external function declarations and no implementation or state.

Answer : Interfaces describe how a contract is called from outside; internal details are not part of an interface, so only external functions are allowed.

Answer : Yes. All functions declared in an interface are implicitly virtual, so implementing contracts can override them.

Answer : It returns a bytes4 identifier of the interface (the XOR of its function selectors). It is used with ERC-165 so a contract can report which interfaces it supports.

Answer : The application can call balanceOf, transfer and other standard functions on any ERC-20 token through IERC20, without knowing each token’s source code.

Answer : No. An interface has no implementation, so it cannot be deployed; only contracts that implement it can be deployed.

Answer : Interface names usually begin with a capital I, such as IERC20 or ICounter.

Answer : The contract is incomplete; the compiler requires it to be marked abstract, and it cannot be deployed.
MCQ Test : Check Your Understanding (5 questions)

Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.

Q1. Which of these CAN be declared inside an interface?

Show Answer

Correct Answer : C. An event
Interfaces may declare events, errors, structs and enums.

Q2. All functions in an interface must be:

Show Answer

Correct Answer : A. external
Interface functions are external.

Q3. ICounter(addr).increment() does what?

Show Answer

Correct Answer : B. Calls increment on the contract at addr
The address is treated as an ICounter and called.

Q4. Which is TRUE about interfaces and abstract contracts?

Show Answer

Correct Answer : D. Neither can be deployed
Neither is deployable on its own.

Q5. An interface can inherit from:

Show Answer

Correct Answer : D. Only other interfaces
Interfaces can inherit only from interfaces.

Bibliography/References

The notes, questions and MCQs on this page are original explanations written for this course. The works listed below were consulted and are cited for attribution and further reading. Product names, logos and trademarks belong to their respective owners. Short quotations, where used, are marked and attributed.

  1. Solidity Team. (n.d.). Contracts (creating contracts, visibility and getters, function modifiers, constant and immutable, functions, events, custom errors, inheritance, abstract contracts, interfaces, libraries). Solidity Documentation. https://docs.soliditylang.org/en/latest/contracts.html
  2. Vogelsteller, F., & Buterin, V. (2015). ERC-20: Token Standard. Ethereum Improvement Proposals, no. 20. https://eips.ethereum.org/EIPS/eip-20
  3. Ethereum Improvement Proposals. (2018). ERC-165: Standard Interface Detection. https://eips.ethereum.org/EIPS/eip-165
  4. OpenZeppelin. (n.d.). OpenZeppelin Contracts Documentation. https://docs.openzeppelin.com/contracts/
  5. Modi, R. (2018). Solidity Programming Essentials: A beginner’s guide to build smart contracts for Ethereum and blockchain. Packt Publishing. ISBN 978-1-78883-138-3.