pragma solidity 0.7.5;
contract Destroyable{
address payable owner;
modifier onlyOwner{
require(msg.sender == owner);
_;
}
constructor(){
owner = msg.sender;
}
function close() public onlyOwner {
selfdestruct(owner);
}
}
Hey @AX07, hope you are great.
When you use the close()
function, it calls the internal method selfdestruct()
which contains an address as argument, when this method is executed, it will destroy the contract and sent all the funds to the address that you provide on it. So the funds are not lost because it will be transferred to the address you specify in the method (msg.sender
in your case, that should be approved by the modifier
onlyOwner
You can read more about here:
- https://medium.com/better-programming/solidity-what-happens-with-selfdestruct-f337fcaa58a7
- https://articles.caster.io/blockchain/self-destructing-smart-contracts-in-ethereum/|
- https://docs.soliditylang.org/en/develop/introduction-to-smart-contracts.html#deactivate-and-self-destruct
If you have any more questions, please let us know so we can help you!
Carlos Z.
aaah vale. Gracias por la explicacion!
Un saludo
pragma solidity 0.7.5;
contract Destroyable {
address payable private owner;
uint256 number;
constructor() {
owner = msg.sender;
}
function store(uint256 num) public {
number = num;
}
function retrieve() public view returns (uint256){
return number;
}
function close() public {
selfdestruct(owner);
}
}
I was having some error coming up. It was resolved by not using the modifier and explicitly using require(msg.sender == owner);
Parent Contract:
pragma solidity 0.7.5;
contract Ownable {
address public owner;
function goodbye() public onlyOwner {
require(msg.sender == owner);
selfdestruct(msg.sender);
}
modifier onlyOwner {
require(msg.sender == owner);
_; // run the function
}
constructor(){
owner = msg.sender;
}
}
Inherited into Child Contract:
pragma solidity 0.7.5;
import "./Ownable.sol";
contract Bank is Ownable {
Yes, thank you for adding the āgo-betweenā variable. It is more clear and easy to grasp the language and what is going on behind the scenes.
I had forgotten that addresses were payable and was lost in the solution until reading the forum.
I can see that skipping the variable will be more efficient and better in production.
Thank you for all the help and guidance you are giving. Really appreciate it. This program is amazing.
My self destruct contract:
pragma solidity 0.7.5;
contract SelfDestroy {
address payable owner;
modifier onlyOwner(){
require(msg.sender == owner);
_;
}
function destroyComtract() public onlyOwner {
selfdestruct(owner);
}
}
Create the Destroyable contract to inherit from Ownable
pragma solidity 0.7.5;
import "./Ownable.sol";
contract Destroyable is Ownable {
function largeExplosion() public onlyOwner {
selfdestruct(msg.sender);
}
}
Then make Bank.sol (which is already Ownable) Destroyable as well:
import "./Ownable.sol";
import "./Destroyable.sol";
contract Bank is Ownable, Destroyable{
My solution:
pragma solidity 0.7.5;
import "./Ownable.sol";
import "./DoomsDayDevice.sol";
contract DoomsDayDevice is Ownable, DoomsDayDevice {
}
// Ownable.sol
contract Ownable {
address owner;
modifier onlyOwner {
require(msg.sender == owner);
_; //run calling function
}
constructor() {
owner = msg.sender; // will be the person who deploys the contract
}
}
// DoomsDayDevice.sol
contract DoomsDayDevice is Ownable {
function redButton () public onlyOwner {
selfdestruct(payable(owner));
}
}
contract Destroyable is Ownable{
function close () public onlyOwner {
selfdestruct(msg.sender);
}
}
pragma solidity 0.7.5;
import "./ownable.sol"
contract Destroyable is Ownable {
function close() public onlyOwner { //onlyOwner is custom modifier
selfdestruct(owner); // `owner` is the owners address
}
}
contract Destroyable{
address owner;
modifier onlyOwner{
require(msg.sender == owner);
_;
}
constructor(){
owner = msg.sender;
}
function destroy() public onlyOwner {
selfdestruct(msg.sender);
}
}
pragma solidity 0.7.5;
import ā./destroy.solā;
contract Bank is Destroyable{
ā¦
}
I have a question, selfdistruct function only works with payable functions? Because I couldnāt put selfdestruct(owner) because it is not payable, that was Remix send me like an error.
contract Ownable {
address internal owner;
modifier onlyOwner {
require(msg.sender == owner);
_; //run the function
}
constructor(){
owner = 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);
}
}
pragma solidity 0.7.5;
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);
msg.sender.transfer(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);
govermentInstance.addTransaction(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;
}
}
What is this in the Bank contract in the github respository
govermentInstance.addTransaction(msg.sender, recipient, amount);
Iām getting declaration errors
Nvm, I see where it is used with an external contract in the following video
Yes, I am good, thank you for asking. Hope you are good too.
I am just slower at learning in this course, cause I have decided to redo my JS course, as Iāve only started learning code with it in autumn and I have to redo the basics + repetition with exercises if I want to continue.
Hey @Lane11
To avoid that error, you have to define the address owner
also with payable
, so it will be address payable owner
, the problem is that selfdestruct
function transfer the entire funds of the contract to the address you specify on it (in this case, owner), payable
keyword must be used every time you need to specify that āthis address variable can receive fundsā.
If you have any more questions, please let us know so we can help you!
Carlos Z.
Included deposit and balance functions to test the return process. Fancy!
pragma solidity 0.7.5;
contract Destroyable {
address payable owner;
mapping(address => uint) balance;
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 getBalance()public view returns (uint) {
return balance[msg.sender];
}
function close() public onlyOwner { //onlyOwner is custom modifier
selfdestruct(owner); // `owner` is the owners address
}
}
pragma solidity 0.7.5;
import "./Ownable.sol";
contract Destroyable is Ownable {
function close() public onlyOwner {
selfdestruct(msg.sender);
}
}
Ownable.sol:
contract Ownable {
address owner;
modifier onlyOwner {
require(msg.sender == owner);
_; // run the function
}
}
Destroable.sol:
import "Ownable.sol";
contract Destroyable is Ownable {
function close() public onlyOwner {
selfdestruct(msg.sender);
}
}
Main.sol:
contract Bank is Destroyable {
[...]
}