(Part 10) Ethereum Solidity - Multiple inheritance, Diaomond Problem And Function Polymorphism(PT 10)
Repository
https://github.com/igormuba/EthereumSolidityClasses/tree/master/class10
What Will I Learn?
- Multiple inheritance
- Diamond problem and how to avoid it
- Polymorphism in functions
Requirements
- Internet connection
- Code editor
- Browser
Difficulty
- Intermediate
Tutorial Contents
Solidity allows you to achieve polymorphism, but you need to be careful with some issues this may cause and you need to be mindful of your contract design choices
Multiple inheritance
For this we will use three contracts, the first one is the parent that will have a variable and a function to retrieve it's variable.
The second contract is the "child", it will inherit from the parent but will override the parent's function and will implement its own version of that function calling its own variable.
Then the last contract will inherit from both the parent and the child and will call the function, that has the same name on both the parent and the child
Parent contract
This is the base contract that will be inherited by the next two, it has it's own variable and a function that calls this variable
contract parent{
uint parentNumber=1; //unique variable to identify we called this contract
function getNumber() public view returns (uint){
return parentNumber; //returns its unique variable
}
}
Child contract
This one inherits from the parent and implements its own function and variable so we can identify whether we called the child or the parent, the function from the parent gets overwritten by the new declaration on the child, so the child is parent but has its own implementation of the getNumber()
function
contract kid is parent{
uint kidNumber=2; //variable different from the parent to identify
function getNumber() public view returns (uint){
return kidNumber; //returns the kids variable
}
}
The contract to test
You need to inherit first from the parent, then from the child, both because else you will get an error because of the diamond inheritance problem (more on that later) and because it will help me show you one thing
contract test is parent, kid{ //inherits both
function callNumber() public view returns (uint){
return getNumber(); //calls the function that has the same name on both
}
}
Now, as you can see, the contract test
inherits from both the parent and the kid, and it calls the function that has the same name on both, so what do number will show on the result? 1, representing it called the parents variable or 2 for the child?
It has returned the kids number, even though we have said it to inherit from the parent first!
This is because solidity prioritizes the child that is "the last on the family tree".
We can still call the function from the parent, but first I need to explain why
The diamond problem
Some programming languages do not allow you to inherit from multiple parents to avoid the diamond problem, Solidity, though, do allow you to inherit from multiple objects.
Inheriting from multiple contracts, in this case, allows you to have some cool features, but you need to be mindful of the functions naming. In case the compiler finds the same method on multiple contracts it will not be able to choose which one are you actually calling.
By saying contract test is parent, kid
we are solving the indecision from the compiler by making it explicit that we want the kid function to override the parent one.
If you said, however, contract test is kid, parent
it wouldn't make sense because you would tell the compiler that the functions from the parent are overriding the functions from the kid that are overriding the functions from the parent (because kid is parent).
The diamond problem by itself would be worth a whole post, but here are some useful resources on this topic
Higher level explanation of the problem:
http://www.lambdafaq.org/what-about-the-diamond-problem/
In-depth explanation with examples in c++:
https://medium.freecodecamp.org/multiple-inheritance-in-c-and-the-diamond-problem-7c12a9ddbbec
A very good example explaining how Solidity deals with the problem
https://delegatecall.com/questions/multiple-inheritance-question-9dcaa9e4-af20-4518-9a5d-033b11a0d97e
Calling the parent function
In case you want to make a call to the function and get the number from the parent, you need to change the kid and implement this with the keyword super
, what super
does is it "ignores" that the function was overwritten and goes right into the parent one.
Let me show with an example, on the code below the only thing that changes is the kid
contract
pragma solidity ^0.5.0;
contract parent{
uint parentNumber=1;
function getNumber() public view returns (uint){
return parentNumber;
}
}
contract kid is parent{
uint kidNumber=2;
function getNumber() public view returns (uint){
return super.getNumber(); //searches for this function on the parent
}
}
contract test is parent, kid{
function callNumber() public view returns (uint){
return getNumber();
}
}
As you can see, this time the parent number was called because we told the kid to search for the function on the parent contract.
One function with many forms
Polymorphism means many forms, the same way that contracts can have many forms, functions also can have many forms. One beautiful thing on polymorphism is that you can have multiple functions with the same name if the signature from the functions is different. That means if they have different inputs. In practice, this is as if there is only one function, but this one function has many forms, hence, the word polymorphism
See the example below
pragma solidity ^0.5.0;
contract polymorphism {
function manyforms(uint numberOne) public pure returns (uint){ //fist form of function manyforms
return numberOne;
}
function manyforms(uint numberOne, uint numberTwo) public pure returns(uint){ //second form of function manyforms
return numberOne+numberTwo;
}
}
On the example above we have successfully implemented two functions with the exact same name, but we have had no errors raised from the Solidity compiler because their signature is different from each other, in this case, the Solidity code will choose which one to call based on the signature of the caller, if you pass to the function manyforms()
only one number, the first one will be executed, if you pass two, there will be no ambiguity because it is obvious to the computer that you mean to call the second one that deals with two arguments
Calling a polymorphed function
With a third function, we can test the polymorphed function manyforms
, check the newly added function below
pragma solidity ^0.5.0;
contract polymorphism {
function manyforms(uint numberOne) public pure returns (uint){
return numberOne;
}
function manyforms(uint numberOne, uint numberTwo) public pure returns(uint){
return numberOne+numberTwo;
}
function callOneForm() public pure returns (uint){
//some code here
}
}
Inside the callOneForm
we can choose whether we want to send one or two arguments. For this we call the function manyforms()
and we can either pass one or two numbers, like in
function callOneForm() public pure returns (uint){
manyforms(1);
}
or in
function callOneForm() public pure returns (uint){
manyforms(1,3);
}
Doing the first form first, the one that receives only one number and calling the callOneForm()
And now on the second form with 1 and 3 as arguments (notice that you have to compile and deploy the contract again)
You can keep on adding more forms, maybe you would like to add another manyforms
function that sums multiple numbers, this allows you to design more concise contracts, with the same functionality but prepared to receive different sets of arguments.
Curriculum
- (Part 9) Ethereum Solidity Assembly - Return, Memory, Hexadecimal, Pointers, And Memory Addressing(PT 9)
- (Part 8) Ethereum Solidity - Assembly, Reducing Costs And Creation Your Low-Level Expression(PT 8)
- (Part 7) Ethereum Solidity - Fallback, Ethereum Fractions, And Collateral Backed Contract(PT 7)
- (Part 6) Ethereum Solidity - Custom Variable Functionalities, Libraries, Using Libraries For Security(PT 6)
- (Part 5) Ethereum Solidity - Custom Access Modifiers, Security Breach Alerts, Assert And Require(PT 5)
- (Part 4) Ethereum Solidity Development - Inheritance, Working With Multiple Contracts And Simple Mutability(PT 4)
- (Part 3) Ethereum Solidity Development - Contract Mutability, DelegateCall And Calling Functions By Address(PT 3)
- (Part 2) Ethereum Solidity Development - Deploying, Security And ERC20 Compliance(PT 2)
- (Part 1) Ethereum Solidity Development - Getting Started + Lower Level Explanation (PT 1)
Beneficiaries
This post has as beneficiaries
@utopian.pay with 5%
using the SteemPeak beneficiary tool
Thank you for your contribution.
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Chat with us on Discord.
[utopian-moderator]
Hi, thank you very much foe the insightful review and for giving me many points where I can improve, I sincerely appreciate
By the way, what Java UI are you referring to? The IDE I am using is Remix from Ethereum, I will soon start tutorials about truffle but for now it is Remix only
Posted using Partiko Android
You're welcome!
I used to code a lot in JAVA many years back. This purple display looks a lot like JAVA runtime UI with its color and layout.
oh, I see
It is from a browser Ethereum IDE to code and deploy contracts from the browser
https://remix.ethereum.org
Posted using Partiko Android
Thank you for your review, @mcfarhat! Keep up the good work!
Hi, @igormuba!
You just got a 0.28% upvote from SteemPlus!
To get higher upvotes, earn more SteemPlus Points (SPP). On your Steemit wallet, check your SPP balance and click on "How to earn SPP?" to find out all the ways to earn.
If you're not using SteemPlus yet, please check our last posts in here to see the many ways in which SteemPlus can improve your Steem experience on Steemit and Busy.
Hi @igormuba!
Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server
Hey, @igormuba!
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!