Inheritance Assignment

Liked to save so I could check - the video with Filip implementing the code is there - maybe it was updated? or what?:
https://academy.moralis.io/lessons/full-project-code

Hey @GrettaIsBack, hope you are ok.

Could you share your contract so i can help you solve the questions.

selfdestruct sends all remaining Ether stored in the contract to a designated address.

You can set up which ever address you want, as long as the address is payable.

The argument msg.sender refers to the account requesting to trigger a function.

Carlos Z

pragma solidity 0.7.5;

contract Ownable{

    address public owner;

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

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



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

contract Destroyable is Ownable {

       function destroy() public onlyOwner{

           address payable receiver = msg.sender;
    
      selfdestruct(receiver);
    }
}
    
pragma solidity 0.7.5;
import "./ownable.sol";
    contract destroyer is ownable {

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

contract Ownable{

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

    }
}
pragma solidity 0.7.5;
import "./destroyer.sol";
import "./ownable.sol"
contract Bank is ownable, destroyer{
1 Like

Hello there! Here is my answer for the Inherit Assignment.


import "./Ownable.sol";

contract Destroyable is Ownable{

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

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


contract bank is Ownable, Destroyable{
1 Like
pragma solidity >=0.6.0 <0.8.0;
import "./Ownable.sol";
import "./Destroyable.sol";

contract Bank is Destroyable {
  uint public balance;

  function deposit() public payable {
    balance += msg.value;
  }

  function withdraw(uint amount) public onlyOwner {
    require(amount <= balance, "Insufficient balance");
    msg.sender.transfer(amount);
    balance -= amount;
  }
}
1 Like

Hey I have some trouble which I think is due to msg.sender in the recent solidity updates. I keep getting following error in Destroyable.sol:

“TypeError: Invalid type for argument in function call. Invalid implicit conversion from address to address payable requested. --> Destroyable.sol:8:22: | 8 | selfdestruct(msg.sender); | ^^^^^^^^^^”

Until I added payable in function header and wrote selfdestruct(payable(msg.sender)).

Can someone explain.
My three contracts looks as follows:

pragma solidity 0.8.17;


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


contract Bank is Ownable, Destroyable{

   mapping(address => uint) balance;


    event depositDone(uint amount, address indexed depositedTo);



    function deposit() public payable returns (uint){
       balance[msg.sender] += msg.value;
       emit depositDone(msg.value, msg.sender);
       return balance[msg.sender];
   }

    function withdraw(uint amount) public onlyOwner returns (uint){
        require(balance[msg.sender] >= amount, "Not enough balance.");
        balance[msg.sender] -= amount;
        payable(msg.sender).transfer(amount);
        //return balance.[msg.sender];
    } 

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

    function transfer(address recipiant, uint amount) public{
        
        require(balance[msg.sender] >= amount, "Balance too low");
        require(msg.sender != recipiant, "Can only transfer to other people");

        uint previousSenderBalance = balance[msg.sender];
        _transfer(msg.sender, recipiant, amount);
        
        assert(balance[msg.sender] == previousSenderBalance - amount);

    }

    function _transfer(address from, address to, uint amount) private{
        balance[from] -= amount;
        balance[to] += amount;

    }
}

pragma solidity 0.8.17;

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

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

contract Destroyable is Ownable{

    function destoryContract() public payable onlyOwner{
        
        selfdestruct(payable(msg.sender));
    }
}
1 Like

Hi @mariustoft

Using payable addresses with solidity was an update in latest solidity versions >= 0.5.0 due to some vulnerability. I could not find any docs for it but you can read the below issue discussing about it.
https://github.com/ethereum/solidity/issues/7727

//Ownable.sol
pragma solidity 0.7.5;

contract Ownable {
    address payable internal 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 close() public onlyOwner{
        selfdestruct(owner);
    }
}

//Bank.sol
pragma solidity 0.7.5;
import "./Destroyable.sol";
contract Bank is Destroyable{
    function close() public{
        selfdestruct(owner);
    }
}

1 Like

pragma solidity 0.8.17;

contract Ownable {

address public owner;

modifier onlyOwner {

require (msg.sender == owner);

_;

}

constructor () {

owner = msg.sender;

}

}

pragma solidity 0.8.17;

import “./Ownable.sol”;

contract Destroyable is Ownable {

function destroy() public payable onlyOwner {

    selfdestruct (payable(owner));

}

}

pragma solidity 0.8.17;

import “./Destroyable.sol”;

contract Bank is Destroyable {

contract destoyable

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

contract destroyable is Ownable{


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

    }
}
  

HelloWorld Contract

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

contract HelloWorld is Ownable, destroyable{

pragma solidity <= 0.8.19

contract Destroyable{

address public owner;

require(msg.sender == owner);

_; //execution

function close() public onlyOwner{

    selfdestruct(Owner);

}

}

Selfdestruct(owner) can be used to destruct the contract

There it goes:

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

import "./Ownable.sol";

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

And, also, the Ownable contract:

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

contract Ownable {
    address owner;

    modifier onlyOwner() {
        require(msg.sender == owner, "You're not the contract owner!");
        _;
    }

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

Quick question.
Why are we adding “pragma solidity 0.7.5;” in the Destroyable.sol file but not in the Ownable.sol file.
Also, should we put the "import “./xxx.sol” command before or after the line “pragma solidity 0.7.5;”? or this is not important?
Thanks

If the ownable contract is imported into any other contract then compiler version of the parent contract will be used to compile Ownable.sol.

You could also run .sol file without mentioning the compiler version. It this case the default compiler installed in your environment will be used to compile the contract. But It is recommended to use the compiler version in every file for easy version updating.

I tried compiling it now by moving the importing line up, but it seems like it does not matter. I don’t see any errors after doing that.

I tried to resolve the assignment but it always gives me error (as usual)

helloworld.sol

// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

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

contract Bank is Ownable, Destroyable {

    mapping(address => uint) balance;

    event depositDone(uint amount, address indexed depositedTo);

    function deposit() public payable returns (uint)  {
        balance[msg.sender] += msg.value;
        emit depositDone(msg.value, msg.sender);
        return balance[msg.sender];
    }

    function withdraw(uint amount) public onlyOwner returns (uint){
        require(balance[msg.sender] >= 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 money to yourself");

        uint previousSenderBalance = balance[msg.sender];

        _transfer(msg.sender, recipient, amount);

        assert(balance[msg.sender] == previousSenderBalance - amount);
    }

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

}

Ownable.sol

 contract Ownable{
   address internal  owner;

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

Destroyable.sol


import "./Ownable.sol";

contract Destroyable is Ownable {

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

It gives this error

Hi @Ahmad_Abd_Allah

Try replacing this line with. You need to convert the address as payable. This was a change in the latest solidity versions.
address payable receiver = payable (msg.sender);

1 Like

contract Ownable {
address internal owner;

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

constructor(){
    owner = msg.sender;
}

}

Ownable.sol

pragma solidity 0.7.5;

contract Ownable {
 
 address payable public  owner;

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

    constructor() {
        owner = msg.sender;
    }

}

Destoryable.sol

pragma solidity 0.7.5;

import "./Ownable.sol";

contract Destroyable is Ownable {

    function destroyContract() public {
        require(owner == msg.sender, "Only the contract owner can perform this action.");
        selfdestruct(owner);
    }
}

Bank.sol header

pragma solidity 0.7.5;

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

contract Bank is Ownable, Destroyable {