- ownable.sol
//PARENT CONTRACT
contract ownable {
address owner;
modifier onlyOwner {
require(msg.sender==owner);
_;
}
constructor(){
owner=msg.sender;
}
} - destroyable.sol
import “./ownable.sol”;
contract Destroyable is ownable {
function Destroy() public onlyOwner {
selfdestruct(msg.sender);
}
} - 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
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.
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 {
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);
}
}
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];
}
}
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 {
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);
}
}
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 {
// ...
}
contract Destroy is Ownable {
function close() public onlyOwner {
selfdestruct(owner);
}
}
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.
pragma solidity 0.7.5;
import "./Ownable.sol";
contract Destroyable is Ownable{
function destroyContract() public onlyOwner {
selfdestruct(msg.sender);
}
}
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 {
...
}
pragma solidity 0.8.7;
import "./Ownable.sol";
contract Destructible is Ownable {
function kill() public onlyOwner {
selfdestruct(msg.sender);
}
}
ownable contract
selfdestruct contract
bank contract
I’m puzzled and needing some answers, if someone could bring me some light on all or part of these:
-
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? -
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? -
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?