Inheritance Assignment

@dan-i
After posting my answer, I looked up a bit and saw that you had this great response to someone else that answers my first question! Thank you.

The function selfdestruct() requires one parameter of type address payable that will receive all the remaining Ether in the contract.
Once clarified that you can really use the variable you prefer.

You could use owner for example:

selfdestruct(payable(owner));
1 Like

selfdestruct.sol

pragma solidity 0.7.5;

import "./selfdestruct2.sol";

contract Bank is selfdestruct2 {
    
 mapping(address => uint) balance;
 address owner;
 
 event depositDone(uint amount, address indexed depositedTo);
 
 constructor (){
     owner = msg.sender;
    
 }
 
 modifier onlyOwner {
     require(msg.sender == owner);
     _;
     
 }
 
 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 returns (uint){
     
     msg.sender.transfer(amount);
 }
 
 
 function getbalance() public view returns (uint){
     
     return balance [msg.sender];
 }
 
 function transfer (address recipient, uint amount) public {
    //check sender balance
    
    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); 
    
    //event logs and further checks
    
    assert(balance[msg.sender] == previousSenderBalance-amount);
 }
   
   function _transfer (address from, address to, uint amount) private {
       balance[from] -= amount;
       balance[to] += amount;
   }
   
}
1 Like

selfdestruct2.sol


pragma solidity 0.7.5;


    

contract selfdestruct2{
    address payable private owner;
     constructor() {
  owner = msg.sender;
 }
    
    
    
    function close() public { 
  selfdestruct(owner); 
 }
}
1 Like

You are very welcome :slight_smile:
If you have other questions just let me know.

Happy learning,
Dani

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

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

I donā€™t know how but when I put owner or Ownable i get an error saying that that syntax is wrong but with the msg.sender it works this isnā€™t an issue right?

I updated the bank contract like this:

pragma solidity 0.7.5;  

import "./Destroyable.sol";

contract Bank is Destroyable {
pragma solidity 0.7.5;
contract Destroyable {
    
    constructor() {
        owner = msg.sender;
    }
    
    address private owner;
    
    function close() private {
        address payable payableAddress = payable(owner);
        selfdestruct(payableAddress);
    }
}

I really enjoy this assignments. Great blog post followed by a good challenge. Hereā€™s my answer:

pragma solidity 0.7.5;

import "./Ownable.sol";

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

The only real roadblock I hit was trying to determine how to make owner payable in the Ownable.sol contract. Just a syntax thing, really. Once I got address payable public owner; figured out then BAM got a nice little self destruct contract.

Cheers yā€™all!


Edit: Hereā€™s the Ownable.sol code, 'cause why not.

pragma solidity 0.7.5;

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

@dan-i ā€” quick question about encapsulation:

I noticed that most other folks are making their owner variable private or internal (as Filip did) in the Ownable.sol parent contract. Is there an advantage to keeping the scope smaller, or is public an okay option? I had initially assumed that public was required for the child contract to access it, but clearly thatā€™s not the case.

1 Like

I think this is the same issue I ran into.

Try putting payable sooner in the state variable delcaration, like so:

address payable public owner;

2 Likes

Agree with you @Hudson.
Please @jelle_van_der_meer make sure to post the full error message or a screenshot so that our answers can be as precise as possible.

Cheers,
Dani

1 Like

Hey @Hudson

You should carefully set the right visibility to all your functions and variables.
Set everything as public might be good for beginners but it is definitely a bad habit.
The question in this case is: is the variable owner used by external and internal contracts?

If owner is used by both external and internal contract then should be public;
If owner is used by only external contract then should be external;
If owner is used by only the Ownable.sol contract then should be private;
If owner is used by Ownable.sol and derived contract then should be internal;

In your case I assume you want it internal.

A quick refresh on visibility: https://bitsofco.de/solidity-function-visibility-explained/

Cheers,
Dani

3 Likes

Amazing, thank you for the detailed response. You are certainly a superhero of these forums.

Internal is indeed the visibility I was looking for.

1 Like

Ok I got it, Thank you!

1 Like

Destroyable contract

pragma solidity 0.7.5;

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

Top of bank contract

pragma solidity 0.7.5;

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

contract Bank is Ownable, Destroyable {
mapping (address => uint) balance;

1 Like

Destroyable.sol

pragma solidity 0.7.5;

import "./Ownable.sol";  

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

Bank.sol

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

contract Bank is Ownable, Destroyable{
1 Like

destroyable.sol :

pragma solidity 0.7.5;

import "./ownable.sol";

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

}

smart contract :

import "./destroyable.sol";

contract ETHBank is Destroyable {...}
1 Like
pragma solidity 0.8.1;

//creates  a contract to be used as a base (parent) contract
contract Destroyable
{
    address internal owner;
    
    modifier onlyOwner
    {
        require(msg.sender == owner);
        _;  //means the modifier is done, next execute the function that called the modifier if the require statement is true
    }
    
    constructor()
    {
        owner = msg.sender;   //stores the address of the owner
    }
    
    
    //only allows the owner of the contract to selfdestruct the contract
    function close() public onlyOwner
    {
        //require(msg.sender == owner);     //already done with the modifier function
        selfdestruct(payable(owner));
    }
}
1 Like

That was the error thanks a lot !

2 Likes

That was indeed the issue thanks a lot for helping and iā€™ll send a screenshot of it the next time

2 Likes

pragma solidity 0.7.5;

import ā€œ./Ownable.solā€;

contract contractdestroyer{

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

}

Hereā€™s the parent contract (Destroyable):

pragma solidity 0.7.5;

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

Hereā€™s the child contract with the function to selfdestruct. This function is only available to the contract owner.

pragma solidity 0.7.5;

import "./Destroyable.sol";

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

I donā€™t know yet if this works, the transaction is still pending. It always takes time when i do TXs, but I think the code works? Can someone correct me if Iā€™m wrong. Many Thanks

1 Like