Hi @TuomoP,
Apologies for the delay in giving you feedback on your solution to this assignment.
As you have chosen to use Solidity v0.8, the compiler should have highlighted a couple of issues with your code…
The address argument passed to selfdestruct() needs to be a payable address, in order for the contract’s remaining ether balance to be transferred to that address when the contract is destroyed. To receive ether an address must be payable.
Prior to Solidity v.0.8, msg.sender
is payable
by default, and so if you’d used v.0.7, the following line of code would have been correct…
However, from v.0.8, msg.sender
is non-payable by default, and so whenever you are using v.0.8 and need to use msg.sender
as a payable address, this requires an explicit conversion e.g.
selfdestruct(payable(msg.sender));
This is why the compiler throws an error for this line of your code.
Once you’ve correct this, the compiler will now generate an orange/yellow warning for the previous line of code:
This is because you have defined a local variable reciever
, but not used it! So, you should remove this, as it’s not needed. You could declare a local variable with a payable address type, and then pass that to selfdestruct(), but you would need to do that as follows…
address payable receiver = payable(msg.sender);
selfdestruct(receiver);
If you pass msg.sender (converted to a payable address) to selfdestruct(), there is no need to store the contract owner’s address as a payable address in the owner
state variable in Ownable.
You are currently converting msg.sender to a payable address within the constructor. But this has no effect (and can be removed) because this address is being assigned to the owner
state variable which is defined with the default non-payable address type.
An alternative to passing msg.sender to selfdestruct() is to pass owner
instead. To do that it would need to be converted to a payable address. One way to do this is to declare the owner
state variable in Ownable with a payable address type …
address payable owner;
… in which case you would need to convert msg.sender to a payable address within the constructor.
You would then be able to use owner
as the argument in selfdestruct() …
selfdestruct(owner);
However, if you only need the contract owner’s address to be payable for the purposes of executing selfdestruct(), you can leave the owner
state variable as non-payable, and explicitly convert the address to payable locally, within the function where you actually need to use it as payable…
function close() public onlyOwner {
address payable receiver = payable(owner);
selfdestruct(receiver);
}
But you can also do this directly within the selfdestruct() function call itself, which I think is more straightforward and concise …
function close() public onlyOwner {
selfdestruct(payable(owner));
}
Can we also see what modifications you’ve made to the start of your Bank.sol file, and Bank contract header, for the inheritance? After all, Bank is the derived contract that we are actually deploying.
Let me know if anything is unclear, or if you have any questions 