Destroy Smart Contracts using selfdestruct
¶
We can not erase information from the Blockchain, but we can update the current state so that you can't interact with an address anymore going forward. Everyone can always go back in time and check what was the value on day X, but, once selfdestruct
is called, you can't interact with a Smart Contract anymore.
Let's try this!
Potential Removal of SELFDESTRUCT
There might be an Ethereum Protocol update coming ahead which removes the SELFDESTRUCT functionality all-together. As writing this, it's not out there (yet), but might be soon, so take the following lab with this in mind.
Update our Smart Contract¶
Let's update our Smart Contract and add a selfdestruct
function. This function takes one argument, an address. When selfdestruct is called, all remaining funds on the address of the Smart Contract are transferred to that address.
contract StartStopUpdateExample {
address public owner;
bool public paused;
constructor() {
owner = msg.sender;
}
function sendMoney() public payable {
}
function setPaused(bool _paused) public {
require(msg.sender == owner, "You are not the owner");
paused = _paused;
}
function withdrawAllMoney(address payable _to) public {
require(owner == msg.sender, "You cannot withdraw.");
require(paused == false, "Contract Paused");
_to.transfer(address(this).balance);
}
function destroySmartContract(address payable _to) public {
require(msg.sender == owner, "You are not the owner");
selfdestruct(_to);
}
}
On the surface it looks very similar to our withdrawAllMoney
function, with one major difference: Once you call destroySmartContract
, the address of the Smart Contract will contain no more code. You can still send transactions to the address and transfer Ether there, but there won't be any code that could send you the Ether back.
Let's try this!
Try our new Smart Contract¶
- Deploy a new Instance
- Send some Ether there by interacting with
sendMoney
- Try to call
destroySmartContract
and provide your own Account, so Ether are sent back.
A Transaction should go through smoothly!
Interacting with Destroyed Smart Contracts¶
Now comes the part that is puzzling a lot of newcomers to Ethereum.
What happens if you try to send Ether again using the "sendMoney" function? Will there be an error or not?
There won't be an error! Internally you are sending Ether to an address. Nothing more.
Try it! Use the same contract instance, don't redeploy. Just enter 1 Ether and hit the sendMoney
button.
and see the log console:
Works perfectly fine!
But try to get your Ether out again!
Also this transaction goes through smoothly! But wait!
Check your Balance!
It isn't updated...
You locked one Ether at the Smart Contract address for good. There's no more code running on that Address that could send you the Funds back.
So, be careful with the Contract life-cycle!
Re-Deployment of Smart Contracts to the Same Address¶
Once scenario, which is not in the course videos, is in-place upgrades. Since the CREATE2 Op-Code was introduced, you can pre-compute a contract address.
Without CREATE2, a contract gets deployed to an address that is computed based on your address + your nonce. That way it was guaranteed that a Smart Contract cannot be re-deployed to the same address.
With the CREATE2 op-code you can instruct the EVM to place your Smart Contract on a specific address. Then you could call selfdestruct(), thus remove the source code. Then re-deploy a different Smart Contract to the same address.
This comes with several implications: when you see that a Smart Contract includes a selfdestruct()
then simply be careful. Those implications will become more and more apparent as you progress through the course, especially when we talk about the ERC20 Token allowance. At this stage it is too early to discuss them all, but if you want to read on about it, checkout this article.
Alright, that's enough of a detour into advanced topics.