What is Smart Contract inheritance?
Previous Section Recap
In the previous section, we covered how we can perform very powerful record-keeping in Solidity using **structs**. They are useful for grouping together related data. Can you think of other good use cases for structs? Here are a few:
- Declare a
Voterstruct to record information on a voter (ie. zip code, name, yes_votes, no_votes, etc) - Declare a
Gamerstruct to record information on a user of your video game smart contract (ie. user level, bosses defeated, etc) - Declare a
Proposalstruct to record information specific to a proposal, possibly as part of a DAO (ie. # of yes/no votes, who voted, etc)
Inheritance Overview
As with many object-oriented languages, Solidity includes inheritance as a feature.
Inheritance means that you can create an object with some values/methods and use it as a base for other objects.
In Solidity, the objects weβre referring to are contracts and interfaces. We can write a contract with state variables and functions. Then we can create contracts that inherit those variables and functions. These derived contracts can then choose to add behavior as necessary.

Smart contracts can inherit other contract by using the is keyword. More specifically, a contract that inherits is the child and the inheritor is the parent. Using the is keyword in Solidity establishes a smart contract parent-to-child chain. So whenever you think of inheritance, just think of the infamous father-son duo: Draco and Lucius Malfoy!
Inheritance in Computer Science

Inheritance allows programmers to create classes that are built upon existing classes, to specify a new implementation while maintaining the same behaviors.
If youβve ever taken a Java 101 course, youβll have seen this concept covered. π»
As in the illustration above, we start with the parent class called Animal, which contains some data and has some βbaseβ or βdefaultβ behaviors such as move() (all or most animals can move!) and eat() (all or most animals eat!).
Then we have the child class called Dog that βinheritsβ (symbolized by the arrow pointing downward) the Animal parent class. A dog is-an animal! A dog has all the base behaviors and data that an animal has (because it is an animal).
Notice the important keyword: is! π
Letβs break down all the labels on the illustration:
- parent class:
Animalis the parent class ofDog(relative parent! If there is noDogto inherit to, it is simply just a class!)
Parent classes are often times also referred to as base classes.
- overridden method:
move()is a method thatDoginherits but overwrites!- If a method is overridden, that means the child class implements it differently. A dog is an animal so it moves, but it moves differently to other animals. π
- inherited method:
eat()is an inherited method from a non-pictured parent class ofAnimal. Every living being eats. So the parent class thatAnimalinherits from could be calledLivingBeing. - child class: also referred to as a subclass, this is simply the class inheriting from a parent. This is the Draco to the Lucius Malfoy. πͺ
- overriding method: as covered three terms up, this is the method that the
Dogchild class inherits but overrides. Dogs move differently from all animals!
Keep these core concepts in mind as we study inheritance in Solidity below. These concepts work the exact same in Solidityβ¦ but instead of classes, just use contracts! π
Inheritance in Solidity
Contracts can inherit other contracts by using the is keyword.

Just as illustrated in the diagram above, the syntax to establish inheritance between smart contracts in Solidity is to simply use the is keyword in the child contract - which creates an explicit pointer to the parent contract:
In this case Contract A is the parent contract, often times referred to as the base contract whereas Contract B is the child contract, often referred to as the derived contract. Letβs break down the different types of smart contract inheritance in Solidity. β¬οΈ
The term βderivesβ is one youβll hear a lot! A contract derives another contract if it inherits from it. Just like a child derives features from a parent! π¨βπ¦
Single Inheritance

Single inheritance helps in inheriting the variables, functions, modifiers, and events of base contracts into the derived contract. This is the exact same diagram as was introduced above.
Multi-Level Inheritance

Multi-level inheritance is very similar to single inheritance; however, instead of just a single parent-child relationship, there are multiple levels of parent-child relationships. This is what is referred to as a smart contract inheritance chain. In this case, Contract A is the base contract as it is the contract all other contracts inherit from.
Hierarchical Inheritance

Hierarchical inheritance is again similar to simple inheritance. Here, however, a single contract acts as a base contract for multiple derived contracts. Contract B and Contract C, in this case, act as siblings but are not interconnected in any way other than that.
Inheritance Use Cases
Now that weβve covered smart contract inheritance at a high level, letβs dive into some code-specific use cases. Smart contract inheritance is very useful because it allows us to bring in existing code, variables, and functions into any contract we write; all we need to do is use the is keyword.
Inheritance is a great way to follow the DRY (Donβt Repeat Yourself) principle of software development! π―
Ownable
Have you heard of OpenZeppelin before? They are a company that produces industry-standard smart contracts. This means they develop and deploy smart contracts that are so used, audited and stress-tested that they become industry standards.
One such standard contract is Ownable.sol. Letβs take a look at some parts of it:
Read the full documentation on OpenZeppelin Ownable if you want to explore further into contract access control. π
The above Ownable contract carries functionality specific to access control of a smart contract. Out of this contract, we get:
- a variable of type
addresscalledowner - a
constructorthat declares theowneris equal to whoever deploys the contract - a
modifierthat can be placed on functions to make sure only whoever is the currentownercan proceed
These are all great and very useful functionality! Ready for the magic, fellow Alchemist? π§ββοΈ
Say you are writing a new kickass smart contract. Letβs call it MyContract and give it some simplistic functionality, like presiding over a uint state variable:
All right easy enough, itβs pretty bare though. And itβs not very secure. The changeNumber() function is marked public, meaning anyone can change our state. We donβt want that. We want to implement access control. But waitβ¦ at this point, you know about smart contract inheritance! Why not just inherit the access control functionality from the OpenZeppelin Ownable contract we looked at above?! π€ Like so:
BOOM. π₯ We successfully inherited from Ownable, meaning we are able to access all the variables (owner of type address, ).
All inheritance does is LITERALLY copy-paste the code of the parent contract into the child contract. Thatβs it!
Thanks to MyContract inheriting Ownable, we now have access to the onlyOwner modifier, without needing to write it from scratch.
Writing from scratch is not bad! But you should know when to rely on battle-tested code and when to write your own. π‘
So you donβt need to worry about writing access control functionality from the ground up! You can use a fully audited industry-standard contract to abstract that away from you. This gives you more time to build the dApp of the future! π
Letβs cover a few more use casesβ¦
Multiple Inheritance
Ok, so your MyContract now has the powers of the OpenZeppelin Ownable. Cool! What if you were trying to create your very own token? πͺ π
Token
Imagine we had a very simple and generic Token contract:
β¬οΈ This Token contract is simple: it just keeps track of the balance of users by an address.
Letβs now use that Token to create our own token:
Boom! π₯ Token created! What if we want to add access control checks to MyToken? We can do so using also inherit from the same Ownable contract we used above!
By using multiple inheritance, we can power our MyToken with both the generic Token AND Ownable (and any other contract you want to inherit from!).
Now our MyToken inherits the onlyOwner modifier from Ownable - awesome! π₯
This is what our current contract architecture looks like, thanks to multiple inheritance:

Solidity Inheritance - Function Syntax
virtual Keyword
A function that is going to be overriden by a child contract must be declared as virtual:
override Keyword
A function that is going to override a parent function must use the keyword override:
NFT Use Case
Hereβs a clear example of an NFT base contract that gets extended via inheritance. In order to override functions of a base contract in Solidity, you must use two keywords: virtual and override, like so:
βοΈ Notice the use of virtual on the base function and override for the new functionality.
Suggested Reading
Conclusion
The big takeaways for inheritance in Solidity is:
- following the DRY (Donβt Repeat Yourself!) principle of software development
- you can always use a base functionality of a contract and then customize it with your own features using the
virtual-overridepattern seen above
Feel like youβve internalized all these concepts? Letβs apply them in the following coding tutorial! π§
Learn More About Ethereum Development
Alchemy University offers free web3 development bootcamps that help developers master the fundamentals of web3 technology. Sign up for free, and start building today!