Inheritance Assignment

  1. ownable.sol
    //PARENT CONTRACT
    contract ownable {
    address owner;
    modifier onlyOwner {
    require(msg.sender==owner);
    _;
    }
    constructor(){
    owner=msg.sender;
    }
    }
  2. destroyable.sol
    import “./ownable.sol”;
    contract Destroyable is ownable {
    function Destroy() public onlyOwner {
    selfdestruct(msg.sender);
    }
    }
  3. helloworld.sol
    pragma solidity 0.7.5;
    import “./ownable.sol”;
    import"./destroyable.sol";
    contract Bank is ownable, Destroyable {,… THE REST IS THE SAME AS BEFORE
1 Like

hi Filip, why do we have to put the word payable after the address? isn’t every address payable? forgive me if this is a stupid question. I avoided having to do this by doing this directly selfdestruct(msg.sender); Please let me know if i am missing anything.

1 Like
pragma solidity 0.7.5;

contract Ownable {

    // has to be payable because the selfdestruct function from destroyable.sol 
    // (which inherits from ownable.sol) sends the remaining balance of the contract
    // back to the owner's address!
    address payable public owner;

    modifier onlyOwner {
        require(msg.sender == owner, "Only owners may perform this action!");
        _;
    }

    constructor() {
        owner = msg.sender;  // the deployer of the contract this way becomes the contract owner
    }
}

pragma solidity 0.7.5;

import "./ownable.sol";
contract Destroyable is Ownable {

    constructor() {
        owner = msg.sender;
    }

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

    function getOwner() public view returns(address) {
        return owner;
    }
}

pragma solidity 0.7.5;
import "hardhat/console.sol";
import "./destroyable.sol";

contract Bank is Destroyable {
1 Like
pragma solidity 0.7.5;

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

import "./Ownable.sol";

contract selfDestruct is Ownable{
    function destroy() public onlyOwner {

        selfdestruct(msg.sender);
  }

}
import "./ownable.sol";

pragma solidity 0.7.5;

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

contract Ownable {

address public owner;

modifier onlyOwner {

require(msg.sender == owner);

_;

}

constructor(){

owner = message.sender;

}

}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import “./Ownable.sol”;

contract Destroyable is Ownable {

function selfDestruct() public onlyOwner {
selfdestruct(payable(owner));
}
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

contract Ownable {
address payable owner;

modifier onlyOwner() {
    require(owner == payable(msg.sender), "ONLY OWNER");
    _;
}

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

}

1 Like

Code for Ownable.sol

pragma solidity 0.7.5;

contract Ownable{

    address internal owner;

    modifier onlyOwner(){
        require(msg.sender==owner,"NOT AUTHORISED");
        _;
    }
    
    constructor(){
        owner=msg.sender;
    }
}

Code for Destroyabe.sol

pragma solidity 0.7.5;

import "./Ownable.sol";

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

Code for Bank.sol

pragma solidity 0.7.5;
import "./Destroyable.sol";
contract Bank is Destroyable{

 mapping(address=>uint256) balance;
 

 event deposited(uint256 amount,address indexed depositedTo);
 event withdrawn(uint256 amount,address indexed withdrawnTo);

 function deposit() public payable returns (uint256)  {
    balance[msg.sender]+=msg.value;
    emit deposited(msg.value,msg.sender);
    return msg.value;
 }
 
  function withdraw(uint amount) public returns (uint,address){
    require(balance[msg.sender]>=amount,"INSUFFICIENT BALANCE!");
    msg.sender.transfer(amount);
    balance[msg.sender]-=amount;
    emit withdrawn(amount,msg.sender);
    return (amount,msg.sender);
  }

 function getBalance() public view returns (uint){
        return balance[msg.sender];   
    }
}
1 Like

Ownable.sol (i made the state variable owner payable from here instead of making a line of code in destroyable)

pragma solidity 0.7.5;

contract Ownable {

    address payable owner;

    constructor(){
        owner = msg.sender;
    }

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

Destroyable.sol

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

contract Destroyable is Ownable {

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

Bank.sol (i only changed the import and added is Destroyable in this file)

pragma solidity 0.7.5;

import "./Destroyable.sol";

contract Helo is Destroyable {
1 Like
Bank Contract

pragma solidity 0.7.5;

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

contract Bank is Ownable, Destroyable {

mapping(address => uint) balance;
```Ownable contract

contract Ownable {

address public owner;

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

}

Destroyable contract

pragma solidity 0.7.5;

import “./Ownable.sol”;

contract Destroyable is Ownable{

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

}

1 Like

You might need to convert msg.sender into payable to be able to send the funds.

Carlos Z

got it, Thx for the help, I wasn’t sure.

Ownable

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Ownable {
    address owner;

    constructor() {
        owner = msg.sender;
    }

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

Destructable

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import "./Ownable.sol";

contract Destructable is Ownable {
    function selfDestroy() public onlyOwner {
        selfdestruct(payable(owner));
    }
}

Bank

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import "./Destructable.sol";
import "./Ownable.sol";

contract Bank is Ownable, Destructable {
  // ...
}
1 Like
contract Destroy is Ownable {
    function close() public onlyOwner {
      selfdestruct(owner);
    }
}
1 Like

Am I dreaming or is the entire “Destroyable” solution video and code gone? The next lesson goes to inheritance and the contract code used by Filip does not include Destroyable?

The solution is still available on Filip’s GitHub.

2 Likes
pragma solidity 0.7.5;

import "./Ownable.sol";

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

Ownable.sol

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

Destroyable.sol

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

contract Destroyable is Ownable {

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

Bank.sol

pragma solidity 0.7.5;

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

contract Bank is Ownable, Destroyable {
...
}
    
1 Like
pragma solidity 0.8.7;

import "./Ownable.sol";

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

ownable contract
image

selfdestruct contract
image

bank contract
image

1 Like

I’m puzzled and needing some answers, if someone could bring me some light on all or part of these:

  1. About the destroy() function:
    the argument msg.sender refers to the owner executing the funciont, but shouldn’t the target of destroy() be the actual SC address?
    And in which part we set the address that will receive the funds before destroying the contract?

  2. The assignment was just to make the Bank contract destroyable, or to actually destroy it?
    Because I got untill the is Destroyable on the Bank contract header just fine, but for it to actually self-destruct, didn’t we need to call the destroy() function somewhere internally on the Bank code?

  3. msg.sender is payable by default nowadays, or not? Searching for it I found comments that it USED to be untill a solidity version, but then was deprecated?

And finally, just to make sure: if I set Destroyable is Ownable {importing the file and in destroy function onlyOwnder… you get it} , I could keep the Bank contract only ‘is Destroyable’, since it will indirectly inherit the Ownable from the other, right?
Or is better to define both Destroyable, Ownable to Bank for some reason?

It was one of my doubts (together with others I posted here): msg.sender used to be payable by default, and since some more recent versions, it is not?
So all msg.sender implementation directed to payable functions need to specify this address as payable somehow?