Build on Scroll
Inheritance in Solidity can help you write less code, make it cleaner, and manage it better. Sounds good right? 😀 Let’s dive into the details with some easy explanations and examples.
What is inheritance in Solidity?
Inheritance in Solidity is similar to what you might know from other programming languages—it's a way to pass qualities and behaviors from one contract to another. Think of it like a family tree where a child contract inherits traits from a parent contract.
Why Use Inheritance?
1. Reusability: Write code once in a parent contract and reuse it in multiple child contracts.
2. Simplicity: Manage and update one set of code instead of many.
3. Organization: Clearly structured code that helps understand relationships and hierarchies within your project.
Key Concepts in Solidity Inheritance
1. Single Inheritance
Let’s start with the basics. Here's how you can create a child contract that inherits from one parent contract.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Parent {
uint public money = 100;
function getMoney() public view returns(uint) {
return money;
}
}
contract Child is Parent {
uint public spendingAmount = 10;
function spendMoney() public {
money -= spendingAmount; // Directly use money inherited from Parent
}
}
In this example, Child
inherits from Parent
. It can access the money
and getMoney()
from Parent
.
2. Multiple Inheritance
Solidity also supports multiple inheritance, where a contract can inherit from multiple parent contracts.
contract A {
function foo() public pure returns (string memory) {
return "A";
}
}
contract B {
function bar() public pure returns (string memory) {
return "B";
}
}
contract C is A, B {
function fooBar() public pure returns (string memory) {
return string(abi.encodePacked(foo(), bar()));
}
}
Here, contract C
inherits from both A
and B
, and can use functions foo()
from A
and bar()
from B
.
3. Constructor Inheritance
If a parent contract has a constructor, it needs to be properly handled in the child contract.
contract Parent {
uint public num;
constructor(uint \_num) {
num = \_num;
}
}
contract Child is Parent {
constructor(uint *num) Parent*(num) {} // Passing arguments to the Parent's constructor
}
4. Overriding Functions
Child contracts can override functions of their parent contracts using the override
keyword.
contract Parent {
function greet() public pure virtual returns (string memory) {
return "Hello from Parent!";
}
}
contract Child is Parent {
function greet() public pure override returns (string memory) {
return "Hello from Child!";
}
}
Let’s finalize this lesson with my favorite part, practical tips.
Practical Tips
- Visibility Matters:
private
functions and state variables are not accessible by the derived contracts, whileinternal
ones are. - Be Gas Efficient: While inheritance can make your contracts neat, remember every added complexity could mean more gas to deploy and interact with your contract. Optimize where possible.
- Testing: Always test inherited contracts thoroughly to ensure expected behaviors, especially when functions override each other.
Remember, the best way to get good at this is by experimenting and building. So, try creating some contracts, inherit some properties and override a few functions.
Comments
You need to enroll in the course to be able to comment!