Inheritance Assignment

Ownable.sol

pragma solidity 0.7.5;

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

Destroyable.sol

pragma solidity 0.7.5;

import "./Ownable.sol";

contract Destroyable is Ownable {

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

HelloWorld.sol

pragma solidity 0.7.5;

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

contract Bank is Ownable, Destroyable{
1 Like

import “./Ownable.sol”;
contract Destroyable is Ownable {

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

}

1 Like

I’ve used a multi-level inheritance in order to join the three files.

1. Ownable Contract:

pragma solidity 0.7.5;
contract Ownable{

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

2. Destroyable Contract:

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

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

3. sendMoney Contract:

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

contract sendMoney is Destroyable{
    
    mapping (address => uint) balance;
    
    event depositDone(address from, uint amount);
    
    function sendToSC() public payable returns(uint){
        balance[msg.sender] += msg.value;
        emit depositDone(msg.sender, msg.value);
        return balance[msg.sender];
    }
}
1 Like

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

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

base contract-

pragma solidity 0.7.5;

import “./ownable.sol”;
import “./destroy.sol”;

contract etherbank is Ownable, selfDestruct{

1 Like

Using the Ownable.sol contract from the lesson:

pragma solidity 0.7.5;

import './Ownable.sol';

contract Selfdestructable is Ownable{
  function destructContract() public onlyOwner { 
    selfdestruct(owner);  
  }
}
1 Like
  1. we create a new file (destroyable.sol) with a new contract with the below content:

pragma solidity 0.7.5;

import “./ownable.sol”;

contract destroyable is ownable{
function destroy () public onlyOwner {
selfdestruct(msg.sender);
}

}

  1. We modify the top of bank.sol as below (new additions made bold) :

pragma solidity 0.7.5;

import “./ownable.sol”;
import “./destroyable.sol”;

contract Bank is ownable , destroyable {

1 Like

I chose to pass the owner variable to selfdestruct, instead of passing msg.sender. As such, it required owner be payable. Since the onlyOwner modifier was also applied, there may be no good argument for this approach, but I personally prefer it, as a quick glance indicates to the reader that it is, in fact, the owner address.

pragma solidity 0.7.5;

contract Destroyable {

address payable public owner;

constructor() {
    owner = msg.sender;
}

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

function selfDestructContract() internal onlyOwner {
    selfdestruct(owner);
}

}

1 Like

Hi Jon,

Thank you for the explanation. So, as contracts cannot be changed, this should always be included before we deploy the contract.
But this path as it is, does it mean the onlyOwner modifier is accessible only for the call of Destoyable? What if we want to use the onlyOwner in one of our functions in the Bank contract? I mean do we write in this case at he beginning:

pragma solidity 0.7.5;

import “./Ownable”;
import “./Destroyable”;

contract Bank is Ownable, Destroyable {…

like explained in the reading assignment article with Multiple inheritance?

Or when will this be the case?

2 Likes

pragma solidity 0.7.5;

contract Destroyable {
address payable public owner;

modifier onlyOwner {
    require(msg.sender == owner);
    _; //run the function
}
 constructor(){
    owner = msg.sender;
}

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

}

Hello, this is the solution I came up with. At first I tried exactly like this, but without keyword “Payable” in the 3rd row. It showed me error, so I added this and now it works. I did not understand why it is needed and why this was not working without it.

1 Like
pragma solidity 0.7.5;

import "../Ownable.sol"

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

Ownable - Parent Contract

pragma solidity 0.7.5;

contract Ownable {

address payable public owner;  // payable required for selfdestruct function to compile and deploy //

modifier onlyOwner {
    require(msg.sender == owner,  "Only Owner can perform this function");
    _; // run the function //
    }

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

Destroyable - child contract with Ownable Inherited for owner variable and onlyOwner modifier. Payable required in owner variable to allow selfdestruct function to compile and deploy.

pragma solidity 0.7.5;

import "./ownable.sol";

contract destroyable is Ownable {

function close() public onlyOwner { //onlyOwner is custom modifier
     selfdestruct(owner);  // `owner` is the owners address
     }
}
1 Like

Hey @makinitnow, hope you are good.

Modifiers can be use to design a condition that you could use multiple times on different functions, like the onlyOwner modifier which will limit the access or execution of some functions to only the contract owner, but you can use it on any function that you whish to limit to a condition.

If you have any more questions, please let us know so we can help you! :slight_smile:

Carlos Z.

1 Like

pragma solidity 0.7.5;

address public owner;

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

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

1 Like
pragma solidity 0.7.5;

contract Ownable {
    address payable public owner;

    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }
    
    constructor(){
        owner = msg.sender;
    }
}
pragma solidity 0.7.5;

import "./Ownable.sol";

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

Parent contract

pragma solidity 0.7.5;

contract Destroyable {
    
    address public owner;
    
    modifier onlyOwner {
        require(msg.sender == owner);
        _; //run the function
    }
    
     constructor () {
        owner = msg.sender;
    }
    
}

Child contract

pragma solidity 0.7.5;

import "./Destroyable.sol";

contract IshoboyBank is Destroyable {
    
    mapping(address => uint) balance;
    
    address recipient;
    
    event depositDone(uint amount, address indexed depositedTo);
    
    event balanceTransfer(uint amount, address depositedFrom, address recipient);
    
    event withdrawDone(uint amount, address withdrawnTo);
    
    function close() public onlyOwner { 
        selfdestruct(msg.sender);
    }
    
    function deposit() public payable returns (uint) {
        balance[msg.sender] += msg.value; //you can even remove this line of code
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public onlyOwner returns (uint) {
        require(balance[msg.sender] >= amount); 
        balance[msg.sender] -= amount; 
        msg.sender.transfer(amount); 
        emit withdrawDone(amount, msg.sender); 
        return balance[msg.sender];
    }
    
    function getBalance() public view returns (uint) {
        return balance[msg.sender];
    }
    
    function transfer(address _recipient, uint amount) public {
        require(balance[msg.sender] >= amount, "Balance not sufficient");
        require(msg.sender != recipient, "Don't transfer money to your self");
        
        uint previousSenderBalance = balance[msg.sender];
        
        _transfer(msg.sender, recipient, amount);
        
        emit balanceTransfer(amount, msg.sender, _recipient);
        
        assert(balance[msg.sender]== previousSenderBalance - amount);

    }
    
    function _transfer(address from, address to, uint amount) private {
        balance[from] -= amount;
        balance[to] += amount;
    }
}
1 Like
pragma solidity 0.7.5;

contract Ownable {
   
    address owner;
    modifier onlyOwner {
    require(msg.sender == owner);
    _;
    }
    constructor () {
        owner = msg.sender;
    }
    
}
pragma solidity 0.7.5;

import "ownable.sol";

contract Destructable{

function close() public onlyOwner {
  selfdestruct(owner);  
}
}
1 Like
pragma solidity 0.7.5;

import "./Ownable.sol";

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

Alright, so I added payable to:

address payable public owner;

Then wrote the destroy code:

pragma solidity 0.7.5;

import "./Ownable.sol";

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

Then I changed the inheritance from Ownable to Destroyable inside Bank to clean up the code a bit:

import "./Destro.sol";

contract Bank is Destroyable

It looks like it is working too :blush:

1 Like

Help please @filip :pray: so i’ve modified my code using your GitHub answers and i’m getting a error message, firstly here in the screen shot below:

…and secondly here…

my code is all below:

pragma solidity 0.7.5;

import "./ownable.sol";
import "./destructable.sol";


contract Bank is ownable {
 
    mapping(address => uint) balance;
    
    event depositdDone (uint amount, address depositedTo);
    event balanceTransfered (uint amount, address toAddress, address fromAddress);
    
    function deposit() public payable returns (uint){
        
        balance[msg.sender] += msg.value;
        emit depositdDone(msg.value, msg.sender);
        return balance[msg.sender];
    }
    
    function withdraw(uint amount) public onlyOwner returns (uint){
        
        
        require (balance[msg.sender] >= amount, "Balance not sufficient");
        balance[msg.sender] -= amount;
        msg.sender.transfer(amount);
        return balance[msg.sender];
    }
    
    
    function getBalance() public view returns (uint){
        return balance[msg.sender];
    }
    
    function transfer(address recipient, uint amount) public {
        
        require (balance[msg.sender] >= amount, "Balance not sufficient");
        require (msg.sender != recipient, "Don't transfer to yourself");
        
       uint previousSenderBalance = balance[msg.sender];
       
       _transfer (msg.sender, recipient, amount);
       
       assert(balance[msg.sender] == previousSenderBalance - amount);
       
            emit balanceTransfered(amount, recipient, msg.sender);
    }
    
    function _transfer (address from, address to, uint amount) private{
        balance [from] -= amount;
        balance [to] += amount;
    }
    
}
pragma solidity 0.7.5;

contract ownable{
    address internal owner;
    
    modifier onlyOwner {
    require(msg.sender == owner);
    _;
    }
    
    constructor () {
    owner = msg.sender;
    }
    
}
pragma solidity 0.7.5;

import "ownable.sol";

contract destructable is ownable {

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

You are missing the ./ at the start of the import the ownable contract.

If you have any more questions, please let us know so we can help you! :slight_smile:

Carlos Z.