Inheritance Assignment

contract Destroyable is Ownable{

   function close() public onlyOwner { //onlyOwner is custom modifier
  selfdestruct(msg.sender);  // `owner` is the owners address
}

}

1 Like

I decided to instead add the destroy function to the Owner class as I believe it be best practice to always have the option to destroy the contract for whatever reason, therefore it will not be possible to forget to include it.

event contractDestroyed(address destroyer);

function destroy() public _onlyOwner {
     emit contractDestroyed(msg.sender);
     selfdestruct(msg.sender);
}
1 Like

In HelloWorld.sol contract, just first lines

pragma solidity 0.5.12;
import './Destroyable.sol';


contract HelloWorld1 is  Destroyable {

In Destroyable.sol contract

pragma solidity ^0.5.1;
import "./Ownable.sol";
contract Destroyable is Ownable {
    
    function destroy() public onlyOwner { //onlyOwner is custom modifier
  selfdestruct(owner);  
    }
}

In Ownable.sol contract

pragma solidity ^0.5.1;

contract Ownable{
    address payable public owner;
    
    constructor() public{
        owner = msg.sender;
    }
    
    modifier onlyOwner(){
        require(msg.sender==owner, 'You are not the owner');
        _;
    }
    
}    

Note: in Ownable.sol, payable option is added since selfdestruct(),
sends the remaining balance of the contract to owner.

1 Like

HelloWorld.sol:

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

pragma solidity 0.5.12;

contract HelloWorld is Ownable, Destroyable {

Ownable.sol:

pragma solidity 0.5.12;

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

Destroyable.sol:

import "./Ownable.sol";

pragma solidity 0.5.12;

contract Destroyable is Ownable {
    

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

}
1 Like

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

contract Destroyable is Ownable {

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

}

1 Like
contract Destroy {
    
    
    
    address payable private ownerAddress;
    constructor () public {
        ownerAddress = msg.sender;
    }
    
    
    modifier isOwner() {
        require (msg.sender == ownerAddress);
        _;
    }
    
    function close() public isOwner {
        selfdestruct(ownerAddress);
    }
    
   
}

then import into base contract and call close. Can also derive ‘Owner’ functions from owner contract if applicable.

1 Like

In Helloworld.sol:

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

contract Structobject is Ownable, Tearable{…}

In Tearable.sol:

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

contract Tearable is Ownable{

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

}

1 Like

import “./Ownable.sol”;

pragma solidity 0.5.12;

contract Destroyable is Ownable {

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

}

1 Like

pragma solidity 0.5.12;

contract Destroyable{

address public owner;

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

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

}

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

contract Destroyable is Ownable{
    function destroyContract() public onlyOwner{
        selfdestruct(msg.sender);
    }
}

Also added this to HelloWorld:

import "./Ownable.sol";
import "./Destroyable.sol";
pragma solidity 0.5.12;


contract HelloWorld is Ownable , Destroyable{
....
1 Like

Why do we want to do the payable part?
address payable receiver = msg.sender;

and not just :
selfdestruct(msg.sender);

1 Like

@filip

Sorry forgot to tag you… @filip

1 Like

@elterremoto
Thanks for reaching out!

payable keyword is necessary to enable an address receive ETH.
Hence, once the address can receive or send ETH, we can call selfdestruct(msg.sender) to transfer all ETH from the contract.

A brief info about selfdestruct():
Selfdestructs in Ethereum are an operation (an OPCODE actually) at the EVM level, independent of what language or client you are using.

For example, calling selfdestruct(address) sends all of the contract’s current balance to address .

This is useful when you are finished with a contract, because it costs far less gas than just sending the balance with address.send(this.balance) .

In fact, the SELFDESTRUCT opcode uses negative gas because the operation frees up space on the blockchain by clearing all of the contract’s data.

This negative gas deducts from the total gas cost of the transaction, so if you’re doing some clean-up operations first, SELFDESTRUCT can reduce your gas costs.

1 Like

Here it is, for some reason it isn’t letting me add spaces in the reply.

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

contract Destroyable is Ownable
{
function destroy(address) public onlyOwner
{
selfdestruct(msg.sender);
}
}

1 Like

Hi @elterremoto,

You’ve asked a good question, and I just wanted to add to the reply @Taha has already sent you.

That’s correct, but the selfdestruct function sends the contract’s ETH balance to the owner’s address, and, as Taha says, it must be a payable address to enable that to happen.

However, by default, msg.sender is already a payable address, and so this is why we don’t actually need the additional line of code:

address payable receiver = msg.sender;

and why we can just use:

selfdestruct(msg.sender);

Maybe this is what was confusing you. The reason why Filip includes the additional step in the video is discussed and explained in this post. However, the conclusion is that it isn’t necessary.

I hope this clarifies things further for you :slight_smile:

1 Like

Hi @LTL

This is correct, except that your destroy function doesn’t need an address parameter. By default, msg.sender is always accessible within a function body, and it references the address which invokes the function as a payable address.

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

If you mean spaces within your code, you may solve this by formatting your code before posting it here in the forum. Click on the </> icon in the menu at the top of this forum’s text editor. This will give you 2 sets of 3 back ticks.
```
input your code here
```
If you now input your code between these, you will end up with it nicely formatted. You should always format the code you post, as it is then much clearer and easier to read, and easier for someone else to copy and paste into a text editor for review and execution. It also makes it easier for you to organise your code with the correct spacing and indentation etc. and to spot any errors or copy-and-paste slips. By formatting it in this way, your code should end up looking something like this:

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

contract Destroyable is Ownable {

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

}

Inheriting Destroyable from Ownable --> Only allowing to destroy what you own and balance will be paid to owner.

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

Inheriting from Destroyable, HelloWorld will get Ownable functionality as well as the destroyContract function.

contract HelloWorld is Destroyable{
// no other changes for destroyable functionality
}

@filip
Question on your solution: The msg.sender is the owner, but it is only implied by onlyOwner doing its job flawlessly. It should work and I do not see how to “hack” to steal funds, but just in case would it not be a notch safer to use owner in Ownable as receiver instead? Or does it open up other weakness? (Yes, I still have the Ethereum Security course ahead of me :slight_smile: )

function destroy() public onlyOwner {
    address payable receiver = owner;
    selfdestruct(receiver);
}
1 Like

I created a file called Destroyable.sol which contains this:

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

contract Destroyable is Ownable {

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

}

And the top of HelloWorld.sol now looks like this:

import "./Ownable.sol";
import "./Destroyable.sol";
pragma solidity 0.5.12;

contract HelloWorld is Ownable, Destroyable{
2 Likes

After posting that I realized that this is enough:

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

contract HelloWorld is Destroyable{

as Destroyable already inherits Ownable.

It is anyway good to keep code short, but would it also save gas?

1 Like

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

contract Destroyable is Ownable{

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

}

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

contract HelloWorld is Ownable, Destroyable{

1 Like