(Part 10) Ethereum Solidity - Multiple inheritance, Diaomond Problem And Function Polymorphism(PT 10)

in #utopian-io5 years ago

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?
image.png

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

image.png

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();
    }
}

image.png

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()
image.png

And now on the second form with 1 and 3 as arguments (notice that you have to compile and deploy the contract again)

image.png

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

Beneficiaries

This post has as beneficiaries
@utopian.pay with 5%
using the SteemPeak beneficiary tool
image.png

Sort:  

Thank you for your contribution.

  • It is interesting to learn further about solidity concepts and coding approaches.
  • The description about diamond problem might have been a bit too short, but providing references was helpful.
  • There were few typos in your content, as well as in the title.
  • More screenshots would have been a bit more helpful to the user.
  • Solidity output looks similar somewhat to Java's UI ?

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!

Coin Marketplace

STEEM 0.28
TRX 0.12
JST 0.033
BTC 61926.98
ETH 3060.91
USDT 1.00
SBD 3.79