Ok, so I found the solution after some errors, lol.
Selfdestruct contract:
pragma solidity 0.7.5;
import "./Ownable.sol";
contract Selfdestruct is Ownable{
function closeContract() public onlyOwner { //onlyOwner access, public
address payable receiver = msg.sender;
selfdestruct(receiver); //destroys contract
}
}
We need to make sure that the **receiver address is from the owner!** Therefore **onlyOwner modifier is crucial.**
Update in Etherbank contract:
pragma solidity 0.7.5;
import “./Ownable.sol”;
import “./Selfdestruct.sol”;
contract EtherBank is Ownable, Selfdestruct{
mapping (address => uint) balance; //takes in a key, here an adress, and returns a value, here uint
//events can be used to log history of contract use! Very interesting and important :)
event depositDone(uint amount, address depositedTo); //creates event takes in parameters we want in the log
event wasTransfered(address indexed sender, uint amount, address transactionrecipient); //if a parameter is indexed we can search for it on the blockchain! we can use infinite amount of parameters but a max of 3 parameters can be indexed per event!
modifier costs(uint price){ //checks if sent value can cover costs/fees
require(msg.value >= price);
_;
}
modifier notSenderAddress(address recipient){
require(msg.sender != recipient, "Do not send money to yourself!"); //prevents sender to send money to him/herself --> same address
_;
}
modifier enoughBalance(uint amount){
require(balance[msg.sender] >= amount, "Insufficient Funds!"); //if condition is not met function will abort and throw error. Here: if balance of sender is not higher or equal to amount to send
_;
}
function deposit() public payable returns (uint){ //takes in uint for ammount to add to adress, returns a uint with the new balance
//since function is payable, deposits will be stored in the wallet of the contract on the blockchain
//the balance mapping is only to keep track of balances inside the code of the contract, so therefore it can also be deleting since payable modifier will store everything on blockchain now
balance[msg.sender] += msg.value; //accessing mapping balance with address of sender and adds user input value
emit depositDone(msg.value, msg.sender); //emit casts event to log!
return balance[msg.sender]; //returns balance of sender address
}
function withdraw(uint amount) public onlyOwner enoughBalance(amount) {
//store previousSenderBalance
uint previousSenderBalance = balance[msg.sender];
//msg.sender is exactly the same as address payable toSend = PUTADDRESSHERE, so you can define a payable adress like this. msg.sender already is a payable address!!
msg.sender.transfer(amount);
//if transfer fails for some reason contract throws error and reverts the transaction
balance[msg.sender] -= amount;
assert(balance[msg.sender] == previousSenderBalance - amount);
}
function getBalance() public view returns (uint){ //gets balance of address of sender
return balance[msg.sender];
}
function transfer(address recipient, uint amount) public notSenderAddress(recipient) enoughBalance(amount){ //transfers uint amount to address of recipient
//check of balance from sender is in modifer enoughBalance now!
uint previousSenderBalance = balance[msg.sender];
_transfer(msg.sender, recipient, amount); //decreases balance of msg.sender wallet & increases balance of recipient wallet --> see private _transfer function
emit wasTransfered(msg.sender, amount, recipient);
assert(balance[msg.sender] == previousSenderBalance - amount);
//event logs and further checks missing
//assert, check for invariant
}
function _transfer(address sender, address receiver, uint amount) private { //private transfer function! implemented in public transfer function see above
balance[sender] -= amount; //decreases balance of sender address
balance[receiver] += amount; //increases balance of receiver address
}
}