Inheritance Assignment

Hi @jon_m,
I probably didn’t manage to make myself clear but generally we are in agreement and your code deliberations are spot on. I merely had a problem with Destroyable extending Ownable. It’s not as straight forward as, let’s say a Car is a Vehicle.

I guess it all depends on who will be left in charge of governance. If we do deploy this for a customer it may be even appropriate to set the owner in Ownable to a customer controlled address.

1 Like

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

contract Destroyable is Ownable{

function close() public onlyOwner { 
    selfdestruct(msg.sender);  

}

}

Then:

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

contract HelloWorld is Ownable, Destroyable{
}

1 Like

Hi @Li_Sun,

Great question!
(and sorry for the delay in replying)

My understanding is that when selfdestruct is called, the whole smart contract in its current state (which includes all its stored data) is deleted from the current state of the Ethereum network, as reflected by the current state of all of the smart contracts currently deployed across all network nodes. This means that the smart contract will no longer run on the EVM, its data no longer needs to be stored by the nodes (hence the gas saving that @Godel alluded to here), and it won’t generate any new transactions — meaning that none of its data will be included in future blocks and stored on the Ethereum blockchain from that point forward.

However, what this doesn’t mean is the loss of any past transaction data associated with that smart contract, which has already been included in blocks mined in the past and included in the blockchain, which by its very nature is, of course, immutable.

Does that answer your question?

1 Like

Hi @Ondrej.S,

Your solution is correct, but not for the reason you have given:

That is correct, but it was already payable, because here the owner’s address is represented by msg.sender (which is a payable address), and not the inherited state variable owner (which is a non-payable address).
msg.sender  can only be the owner, because the function is marked onlyOwner .

In fact, the two lines of code in your solution is a more long-winded (or some would say more clearly broken-down step-by-step) version of the following equally valid solution:

selfdestruct(msg.sender);

Have a look at this post for further details.

It’s only when we explicitly reference the owner’s address by using owner , that we need to convert a non-payable address to a payable one, as follows:

// either
address payable receiver = address(uint160(owner));
selfdestruct(receiver);

// or
selfdestruct(address(uint160(owner)));

// OR by first making owner payable in contract Ownable:
address payable public owner;
// and then using the following code in contract Destroyable:
selfdestruct(owner);

… also, 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.

2 Likes

Good solution @JeffE :ok_hand:

Just remember, that if contract HelloWorld inherits both Ownable and Destroyable, it needs to import both of their files (your code only imports one):

However, also 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.

2 Likes

Good solution @sherlock :ok_hand:

… also, 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.

2 Likes

Thanks for the thorough feedback, I’ll have a look at the post too.

1 Like

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

//SPDX-License-Identifier: UNLICENSED

contract Destroyable is Ownable{

function closeContract() public  onlyOwner {

    selfdestruct(msg.sender);
}

}

1 Like

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

contract Destroyable is Ownable{

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

}

And HelloWorld Contract Part

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

contract HelloWorld is Ownable, Destroyable{

I noticed after watching the solution video that when Fillipe went to execute a function after destroying it he would get an error. However after I do it It all runs as normal but the data has been destroyed. There is no error when trying to call the Owner I just get this.

0: address: 0x0000000000000000000000000000000000000000

Is this correct?

1 Like

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

contract Destroyable is Ownable {

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

}

Then modify HelloWord.sol:

import “./Destroyable.sol”;

contract HelloWorld is Ownable, Destroyable {

2 Likes

import “./ownable.sol”;
pragma solidity 0.5.12;
contract Deployable is Ownable{

function destruct() public onlyOwner {
selfdestruct(msg.sender);
}

1 Like

anybody else notice that after you use the close button (selfdestruct) you can then use createPerson and it will actually take eth from the address. I thought this was strange because if the contract is destroyed how can it take ETH from the address?

@Changfa_Lin
Thanks for reaching out!
Apologies, I didn’t understand your question?

1 Like

@doctormartin67 Thanks a lot for reaching out!
Can you elaborate more on your question? Are you talking about close button in the Remix? if, yes that does not destroy the contract. To Destroy the contract you need to call destroy function :slight_smile:

1 Like
import "Ownable.sol";
pragma solidity 0.5.12;

contract Destroyable is Ownable {
    function close() public onlyOwner { //onlyOwner is custom modifier
        selfdestruct(msg.sender);  
    }
}
2 Likes

Hi @mikekai,

Yes, what you’re getting is correct. That’s exactly what I get too. Without watching the video again, I’m not exactly sure what error you’re seeing Filip getting, but rest assured what you are getting in Remix is correct.

Your solution to the assignment is also correct :+1:

Also, check this post out — it explains how you can make an additional adjustment to the inheritance in HelloWorld. I think you’ll find it interesting :slight_smile:

2 Likes

Hi @leemac,

Just remember that with this inheritance set-up you need…

import "./Ownable.sol";

… as well.

However, also check this post out — it explains how you can make an additional adjustment to the inheritance in HelloWorld. I think you’ll find it interesting :slight_smile:

2 Likes

Hi @john_coraline,

Do you mean contract Destroyable instead of HelloWorld ?! :wink:

2 Likes

never mind, I might have replied to wrong question chain.

best regards.

1 Like
  • Inheritance.sol

     import "./Ownable.sol";
     import "./Destroyable.sol";
    
     pragma solidity 0.5.12;
    
     contract HelloWorld is Ownable, Destroyable{ ... }
    
  • Destroyable.sol

    import "./Ownable.sol";
    pragma solidity 0.5.12;
    
    contract Destroyable in Ownable{   
    
        function terminateContract(address payable owner) public onlyOwner  {
              selfdestruct(owner);
        }
    

    }

1 Like