Inheritance Assignment

Hi @filip ,
Is it better that it be written like you did
import “./Ownable.sol”;
pragma solidity 0.5.12;

contract Destroyable is Ownable{

function close() public onlyOwner{
    address payable receiver = msg.sender;
    selfdestruct(receiver);
}

}

rather than how i did originally?

Destroyable.sol

import "./Ownable.sol";

contract Destroyable is Ownable {

    function close() public onlyOwner {
        selfdestruct(owner);
    }

}

HelloWorld.sol

import "./Destroyable.sol";

contract HelloWorld is Destroyable {
[...]

I made Destroyable inherit from Ownable, because to be Destroyable, a contract needs some safety so that only the owner can destroy it. So in the end if you want a contract that is Destroyable, you also get the “Ownable” properties and functions.

I also had to fix some error because “owner” had to be a payable address so:

Ownable.sol

contract Ownable {

    address payable public owner;

    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    constructor() public {
        owner = msg.sender;
    }
    
    function setNewOwner(address payable _address) public onlyOwner returns (address) {
        require(_address != address(0));
        owner = _address;
        return owner;
    }
}
1 Like

Hi @filip (hello to anybody else too, who wants to answer :wink: )

I’ve seen in your solution:

import "./Ownable.sol";
import "./Destroyable.sol";

contract HelloWorld is Ownable, Destroyable {

in my solution I did simply:

import "./Destroyable.sol";

contract HelloWorld is Destroyable {

In HelloWorld I didn’t import Ownable, because that is imported already in Destroyable. Also I didn’t specify is Ownable, because Destroyable is already ownable.

Why did you do that redundancy? Do you agree that it’s not necessary? I tested my solution and of course it works, so I assume it’s ok :wink:

1 Like

Destroyable contract which inherets fromOwnable

import “./Ownable.sol”;
pragma solidity 0.5.12;

contract Destroyable is Ownable{
function destroyContract() public onlyOwner {
selfdestruct(owner);
}
}

And the HelloWorld contract inherets from the Destroyable contract

contract HelloWorld is Ownable, Destroyable{
}

1 Like

Hi @Yves_T!

Nice solution :ok_hand:

By the way, what amendments did you make to contract HelloWorld in terms of its inheritance?

1 Like

Hi @mjwatson10!
You may find this answers your question:

2 Likes

Hi @mjwatson10

Check this post out — it explains how you can make an additional adjustment in terms of the inheritance.

2 Likes

Nice detailed analysis and summary, @firepol!

And I like the idea of the additional setNewOwner Function :+1:

You should remove returns(address) and return owner because this function is a setter not a getter, and these additional pieces of code don’t actually do anything anyway. Contract Ownable automatically generates a getter for owner which is a state variable and has public visibility, and so is inherited by Hello World, and so this enables us to get the owner’s address from there.

Have a go at making these changes and you’ll see what I mean.

1 Like

Hi @firepol!

You are exactly right in your observation. There is actually some discussion about this a bit further up in this thread…

I think maybe in the solution code, contract HelloWorld was left inheriting Ownable (as well as Destroyable) from the previous lecture. It isn’t an error, but your inheritance composition is the more efficient, and everyone agrees with that. :smiley:

1 Like

Hi @iceman007!

Your solution is correct, but it involves making an additional change to contract Ownable. Do you know what it is and why?

In addition, have look at @firepol’s post just above, and my reply, and you will see that we can also make our inheritance code in HelloWorld more concise as well.

1 Like

Hi Jon

Yes I needed to make my owner as a payable address.

2 Likes

First I added this to Hello World:

import “./Ownable.sol”;
import “./Destroyable.sol”;
pragma solidity 0.5.12;

contract HelloWorld is Ownable, Destroyable{

I wondered if you could add multiple imports into one import command, but it did not seem to take, so I did it separately.

Then I created Destroyable.sol:
import “./Ownable.sol”;
pragma solidity 0.5.12;

contract Destroyable is Ownable{

function destroy() public onlyOwner{
address payable reciever = msg.sender;
selfdestruct(reciever);
}
}

I was having some issues with the self destruct at first, but I worked it out. Defining payable was the key in my case.

1 Like

Hi @DeCryptolorian,

Nice analysis of your steps, and thought processes :+1:

Check this post out — it explains how you can make an additional adjustment in terms of the inheritance. I think you’ll find it interesting.

1 Like
import "./Ownable.sol";
pragma solidity 0.6.8;

contract Destructable is Ownable {
    function destruct() public onlyOwner{
        selfdestruct(owner);
    }
}
pragma solidity 0.6.8;

contract Ownable
{
    address payable owner;
    
    constructor() public 
    {
        owner = msg.sender;
    }
    
    modifier onlyOwner()
    {
        require(msg.sender == owner);
        _;
    }
}
1 Like

Hi @matren,

Nice solution :ok_hand:

By the way, what amendments did you make to contract HelloWorld in terms of its inheritance?

I also noticed that in contract Ownable you didn’t state the visibility of

I’m interested to know if that was a deliberate decision? Your code still runs without it, but it would make the contract clearer for other developers if you stated what you intend the visibility to be.

1 Like

Thanks for asking.
You’re right, visibility should always be used to state the intend.

For now i don’t know which visibility to use in solidity.
In general i would use the most restricted visibilty possible. In this case it should be then “internal”.

The default visbility in solidity is “public” where other languages normaly use “private” as default.
There must be a reason why “public” was chosen in solidity as the default.

Some statements about this (please correct me if i am wrong):

  1. state variables can only be changed through a function call in the contract itself
    (meaning, it cannot be changed from external contracts or through the API exposure of the contract).

  2. state variables are visible in the blockchain, therefore there’s no way to hide their contents

So my question would be:
Is there any reason i should make the owner “internal” instead of defaulting it to “public” ?

If i see it correctly public state variables have a “public getter” but still an “internal setter”.

1 Like

In the Onwable contract I explicitly converted the owner address to an address payable, like so:

address payable internal owner; // Limit access.

Next, the Destroyable contract reads as such:

import "./ownable.sol";
pragma solidity 0.5.12;

contract Destroyable is Ownable {
    
    function close() public onlyOwner { 
        selfdestruct(owner);
    }      
    
}
1 Like

contract ownable{

address payable public owner;

modifier onlyOwner(){
    require(msg.sender == owner);
    _; //Continue execution
}
constructor() public{
    owner = msg.sender;
}   

}

contract destroyable is ownable{

function destroy() public onlyOwner {
    selfdestruct(owner);
}

}

contract HelloWorld is ownable, destroyable{
…
}

1 Like

I created a new Destroyable contract (which in fact derives from Ownable because only the owner should be able to destroy the contract):

import "./Ownable.sol";

pragma solidity 0.5.12;

contract Destroyable is Ownable {
    function close() public onlyOwner {
        selfdestruct(owner);
    }
}

Then I made our HelloWorld contract Destroyable (I initially inherited from Ownable and Destroyable but then realized that Destroyable was already Ownable :

contract HelloWorld is Destroyable {
    //...
}

Compiled, deployed and executed the close function:

[vm]from:0x147...c160cto:HelloWorld.close() 0x459...d8f30value:0 weidata:0x43d...726d6logs:0hash:0x178...4dce6
Debug
 status 	0x1 Transaction mined and execution succeed
...

I also needed to make the following change in the type of the ower variable of the Ownable contract:

address public owner;

changed to:

address payable public owner;

That’s because when destroying a contract, all it’s funds will be transferred to the owner’s address.

1 Like

pragma solidity 0.5.12;

import “./Ownable.sol”;

contract Destroy is Ownable{

    function  close () public onlyOwner{
        address payable count = address(uint160(owner)); 
        selfdestruct (count);
       }

}

1 Like