Personal Blog
Calling selfdestruct(...) in a Solidity smart contract (EVM operation SELFDESTRUCT or SUICIDE, respectively) is probably a good thing:
But it can be risky! And make things more complex.
Disclaimer: This pros/cons list does not claim to be complete. I’ll update it as soon as I have new points. You are welcome to mail me if you find any missing aspects.
selfdestruct(account)).return or revert, and therefore does not allow a function to return a parameter. However, results can be persisted in an event when emitted beforehand.selfdestruct method costs a transaction fee (Gas).Let’s say we have a very basic voting contract which stops counting new votes at a certain date. The following function can only be called in the following 14 days after the smart contract’s deployment. Wouldn’t it be handy to self-destruct the smart contract automatically when somebody tries to vote, but the time is over?
uint256 public end = now + 14 days;
mapping(uint256 => uint256) public votes;
address payable owner = msg.sender;
function vote(uint256 _vote) public {
  if(now < end)
    votes[_vote]++; // TODO: check for overflow
  else
    selfdestruct(owner); // owner is the account which deployed the smart contract
}
The problem here is, that selfdestruct sets all non-0 storage values of the contract to 0. Hence, all values in the votes mapping will also be set to 0. But in the case that the votings results are still relevant, it would be more complex to get back the results. For this, one would need to find out at which block the contract has been destructed, and then query that block’s predecessor state.
The following code, though, persists the voting results as events, which can be monitored by others. But the contract has two major problems: First, it is still complex to query past events of a destructed contract (one has to get an old state and therefore the block number must be known), and second, the last one who calls this function will not get back the function’s return value (because selfdestruct stops the function before it’s finished).
uint256 public end = now + 14 days;
mapping(uint256 => uint256) public votes;
address payable owner = msg.sender;
event VoteCounted(uint256 vote);
function vote(uint256 _vote) public returns (bool _successful) {
  if(now < end) {
    _successful = votes[_vote] + 1 > votes[_vote]; // This is an overflow check
    if(_successful) {
      votes[_vote]++; 
      emit VoteCounted(_vote);
    }
  } else {
    _successful = false;
    selfdestruct(owner); // owner contains the account which deployed the smart contract
  }
	
  return _succsessful; // not necessary, see following note
}
Please note here, that calling
return _succsessful;at the end is not necessary, because the return variable is already specified in the function header. It would also be returned even if thereturnwouldn’t be the last command of the function—except in our special case withselfdestruct.
for example, see eveem.org/#destruct, they look for callable selfdestructs automatically ↩