Inheritance vs. interfaces in Solidity contracts

Key takeaways:

  • Inheritance in Solidity allows contracts to inherit properties and functionalities from parent contracts, enabling code reuse, modularity, and supporting multiple inheritance.

  • Interfaces define function signatures without implementation, ensuring contracts implement specific methods while providing flexibility for different implementations.

  • Choosing between inheritance and interfaces depends on the need: inheritance for sharing common functionality and interfaces for defining contract structures without enforcing implementation details.

Solidity, a programming language for developing smart contracts on blockchain platforms like Ethereum, provides developers with multiple code organization and reuse tools. Two key concepts for achieving this are inheritance and interfaces. This discussion will delve into the differences between inheritance and interfaces in Solidity contracts.

Inheritance in Solidity contracts

Inheritance is a fundamental object-oriented programming concept that allows a contract to inherit properties and functionalities from another contract. The derived contract is called the child or subclass, while the base contract is called the parent or superclass.

Syntax

contract BaseContract {
// Base contract code
}
contract DerivedContract is BaseContract {
// Derived contract inherits from BaseContract
// Derived contract code
}
Syntax for inheritance in Solidity

Features

  • Child contracts can access functions, state variables, and modifiers from the parent contract.

  • It enables code reuse and modular development.

  • Supports multiple inheritance, allowing a contract to inherit from multiple parents.

Example

Note: The provided Solidity code doesn’t produce any output by default when compiled and deployed. The output or behavior depends on how you interact with the deployed contract in a blockchain environment.

pragma solidity ^0.5.0;
contract Animal {
uint256 public age;
event AgeSet(uint256 indexed _age);
function setAge(uint256 _age) public {
age = _age;
emit AgeSet(_age);
}
}
contract Dog is Animal {
string public breed;
event BreedSet(string _breed);
function setBreed(string memory _breed) public {
breed = _breed;
emit BreedSet(_breed);
}
}

Explanation

  • Line 4: Declares a public state variable age to store the age of the animal.

  • Line 6: Declares an event AgeSet to signal that the animal’s age has been set.

  • Lines 8–11: Declares a public function setAge to set the animal’s age.

    • Line 9: Assigns the value of _age to the age state variable.

    • Line 10: Emits the AgeSet event with the new age _age as an argument.

  • Line 15: Declares a public state variable breed to store the breed of the dog.

  • Line 17: Declares an event BreedSet to signal that the breed of the dog has been set.

  • Lines 19–22: Declares a public function setBreed to set the breed of the dog.

    • Line 20: Assigns the value of _breed to the breed state variable.

    • Line 21: Emits the BreedSet event with the new breed _breed as an argument.

Interfaces in Solidity contracts

Interfaces in Solidity are similar to abstract contracts. They define the signatures of functions without implementing the logic. Contracts can adapt interfaces to ensure they implement specific methods.

Syntax

interface MyInterface {
// Function declarations
function myFunction(uint256 arg1, address arg2) external returns (uint256);
function anotherFunction(string calldata arg1) external view returns (bool);
// Additional function declarations
}

Features

  • It defines a blueprint for contracts to adhere to without providing functionality.

  • Contracts implementing an interface must provide implementations for all functions declared in the interface.

  • A single contract can adopt multiple interfaces.

Example

Note: The provided Solidity code doesn’t produce any output by default when compiled and deployed. The output or behavior depends on how you interact with the deployed contract in a blockchain environment.

pragma solidity ^0.5.0;
interface IAnimal {
function setAge(uint256 _age) external;
function getAge() external view returns (uint256);
}
contract Animal is IAnimal {
uint256 private age;
event AgeSet(uint256 newAge);
function setAge(uint256 _age) external {
age = _age;
emit AgeSet(_age);
}
function getAge() external view returns (uint256) {
return age;
}
}
  • Lines 3–6: Defines an interface named IAnimal.

    • Line 4: Declares a function signature setAge with one parameter _age of type uint256. This function does not have any implementation details and is marked as external.

    • Line 5: Declares a function signature getAge with no parameters. It specifies that this function is external and view, meaning it does not modify the contract’s state and returns a value of type uint256.

  • Lines 8–21: Declares a contract named Animal that implements the IAnimal interface.

    • Line 9: Declares a private state variable age of type uint256 to store the age of the animal.

    • Line 11: Declares an event named AgeSet with one parameter newAge of type uint256. This event will be emitted whenever the age of the animal is set.

    • Lines 13–16: Defines a function setAge that takes one parameter _age of type uint256. This function is marked as external, indicating it can be called from outside the contract.

      • Line 14: Assigns the value of _age to the age state variable.

      • Line 15: Emits the AgeSet event with the parameter _age, indicating that the animal’s age has been set.

  • Lines 18–20: Defines a function getAge with no parameters. It is marked as external and view, indicating that it does not modify the contract’s state and can be called from outside the contract.

  • Line 19: Returns the value of the age state variable.

Choosing between inheritance and interfaces

Inheritance and interfaces both provide ways to structure contracts in Solidity but serve different purposes based on the design needs of our application. Choosing the right one can enhance modularity, code reuse, and adherence to specific standards within your smart contract architecture.

Inheritance

  • Suitable for sharing common functionality among contracts.

  • Enables the reuse of code and the extension of existing contracts.

Interfaces

  • Used when a contract needs to adhere to a specific structure without providing the implementation details.

  • Useful for defining standards that multiple contracts can follow.

Conclusion

In Solidity, inheritance, and interfaces are valuable tools for achieving code organization and reuse. The choice between them depends on the smart contract’s specific requirements and the desired level of abstraction. Developers often combine both to create modular, interoperable, and maintainable code.

Frequently asked questions

Haven’t found what you were looking for? Contact Us


Does Solidity support inheritance?

Yes, Solidity supports inheritance, allowing contracts to inherit properties and functions from other contracts. Solidity’s inheritance model is similar to object-oriented programming languages and supports multiple inheritance, enabling more complex and modular code structures.


Is Solidity better than Python?

Solidity is specifically designed for smart contracts on the Ethereum blockchain, while Python is a general-purpose language suited to many applications, such as web development, data science, and automation. For blockchain development, Solidity is preferable due to its integration with Ethereum’s ecosystem. For broader applications, Python offers more versatility and a larger developer community.


Is Solidity well paid?

Yes, Solidity development is generally well paid due to the high demand for blockchain expertise and the specialized skills required. Solidity developers can command competitive salaries, especially with experience in decentralized applications (dApps) and smart contract development, reflecting the high value of blockchain and Web3 expertise.


Free Resources

Copyright ©2025 Educative, Inc. All rights reserved