Inheritance Assignment

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

contract Destroyable is Ownable{
function close() public onlyOwner { //onlyOwner is custom modifier
selfdestruct(owner); // owner is the owners address
}
}

Literally copied from website. Had to make HelloWorld a child of Destroyable and Destroyable a child of Ownable.

I also made Owner address payable on the Ownable contract.

1 Like

OWNABLE

pragma solidity 0.6.10;

contract Ownable{
address public owner;

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

constructor() public{
    owner = msg.sender;
}

}

DESTROYABLE

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

contract Destroyable is Ownable {

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

1 Like

Ownable.sol

pragma solidity 0.6.6;

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

Destroyable.sol

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

contract Destroyable is Ownable{
    function close() public onlyOwner { //onlyOwner is custom modifier
      selfdestruct(owner);  // `owner` is the owners address
    }
}

HelloWorld.sol

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

contract HelloWorld is Ownable, Destroyable{
    struct Person {
        string name;
        uint age;
        uint height;
        bool senior;
    }
    
    event personCreated(string name, bool senior);
    event personDeleted(string name, bool senior, address deletedBy);
   
    uint public balance;
    
    mapping(address => Person) public people;
    address[] private creators;
    

    
    modifier costs(uint cost) {
        require(msg.value >= cost);
        _;
    }
    
    function createPerson(string memory name, uint age, uint height) public costs(1 ether) payable {
        require(age <= 130, "Age needs to be real");
        balance+= 1 ;
        
        
        Person memory newPerson;
        newPerson = Person({
            name: name,
            age: age,
            height: height,
            senior: age > 65 ? true : false
        });
        
        insertPerson(newPerson);
        
        creators.push(msg.sender);
        assert(
            keccak256(
                abi.encodePacked(
                    people[msg.sender].name,
                    people[msg.sender].age,
                    people[msg.sender].height,
                    people[msg.sender].senior
                )
            )
            
            ==
            
            keccak256(
                abi.encodePacked(
                    newPerson.name,
                    newPerson.age,
                    newPerson.height,
                    newPerson.senior
                )
            )
        );
        
        emit personCreated(newPerson.name, newPerson.senior);
        
    }
    
    function insertPerson(Person memory newPerson) private {
        address creator = msg.sender;
        people[creator] = newPerson;
    }
    
    function getPerson() public view returns(string memory name, uint age, uint height, bool senior) {
        return (
            people[msg.sender].name,
            people[msg.sender].age,
            people[msg.sender].height,
            people[msg.sender].senior
        );
    }
    
    function deletePerson(address creator) public onlyOwner {
        string memory name = people[creator].name;
        bool senior = people[creator].senior;
        
        delete people[creator];
        
        assert(people[creator].age == 0);
        
        emit personDeleted(name, senior, msg.sender);
    }
    
    function getCreator(uint index) public view onlyOwner returns(address)  {
        return creators[index];
    }
}

2 Likes

haha yes of course :smiley: have edited it now

1 Like

I made HelloWorld.sol inherit from Destroyable by changing the following lines:

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

contract HelloWorld is Ownable, Destroyable{

And here is my Destroyable.sol

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

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

1 Like

New file Destroyable.sol :

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

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

Add to my HelloWorld (renamed to HelloPersons…), removing Ownable since it is already inherited in Destroyable:

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

contract HelloPersons is Destroyable{ ... }
1 Like

I’ve created destructible.sol within I import ./owner.sol

contract Destructible is Owner {
address payable owner // in owner.sol, my address is private

function destroy() public isOwner {
selfdestruct(owner)
}

destructible.sol is imported in test.sol (my Hello World)

1 Like

Ok, I’m completely lost. I thought I had it but no.

pragma solidity 0.5.12;

contract Ownable {
    
    
    
    modifier onlyOwner(){
        address public owner;
        
        require (msg.owner == owner)
        _; //continue execution
        
    }
}

I get an error that I don’t understand.

Destroyable.sol

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

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

HelloWorld.sol

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

contract HelloWorld is Destroyable {...}
1 Like

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

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

1 Like

@dbeelow0323
What error are you getting can you please paste it here? :slight_smile:

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

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

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

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

In the solution video why do you create
“address payable receiver = msg.sender”
when you do not get the compile error about a non payable address if you just have
“selfDestruct(msg.sender);”

?? I’d like to understand if the address payable statement is required or if not, is it beneficial and if so, why?

thanks in advance!

1 Like

@CodyM
Thanks for reaching out!
payable keyword allows the address variable to send and receive function, and also for contracts and function too.
So those address/function/contract does not need payable keyword if they are not going to receive ETH

Hope this answers the question :slight_smile:

Can you elaborate more on this question?

Welcome

I decided to make the ‘Destroyable’ Contract a child of the ‘Ownable’ Contract - this ensures the self destruct operation can only be performed by the owner and also I am not repeating code unnecessarily.

import "./Ownable.sol";

pragma solidity 0.5.12;

contract Destroyable is Ownable{

    function Destroy() public onlyOwner {        //onlyOwner is custom modifier from 'Ownable' contract
        selfdestruct(msg.sender);              // sends all funds to contract owners address
    }
    
}

In the contract that is inheriting all of this (‘HelloWorld’ - or in my case 'FirstContractExample) I put this:

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

contract FirstContractExample is Ownable, Destroyable { 
//'FirstContractExample' is derived from both 'Ownable' and 'Destroyable' contracts

//----rest of contract here....

I wasn’t entirely sure of the best way to do this part as I could’ve just said -

import "./Destroyable.sol";
contract 'FirstContractExample' is 'Destroyable' { ....

…as ‘Destroyable’ inherits from ‘Ownable’ and therefore ‘FirstContractExample’ also inherits from ‘Ownable’ but I think it is more clear exactly what is being derived this way and would be easy to follow the code directly without having to go through ‘Destroyable’. I guess this also means that ‘Ownable’ is simultaneously a parent and grandparent to ‘FirstContractExample’
…which is somewhere between mulitple and mulit-layer inheritance??
Anyway, it all seems to work when I deploy. Only the owner address could destroy the contract, also once destroyed, other addresses could still create a Person and deposit Ether, but then that Ether was lost forever as the article said it would be. I could not withdraw or destroy a second time and recoup funds…interesting stuff, really enjoying this course!!

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

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

… And I have made owner address payable:

pragma solidity 0.5.12;

contract Ownable {

address payable public owner;

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

I created a new file called Destroyable.sol and let it inherit from the Ownable contract. And the main contract (HelloWorld) now inherits from both these contracts.

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


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

@cryptocrom
Thanks a lot for reaching out!
A contract can be inherited to multiple contracts.
I suggest we limit the inheritance concept to PARENT and CHILD only
In your case
Ownable is PARENT of both Destroyable and FirstContractExample

Segregating contracts and using inheritance is a very efficient way of writing re-usable code. A JOB WELL DONE! :+1: