Skip to main content
1 of 2
Nulik
  • 4.1k
  • 1
  • 19
  • 30

It is marked as suicided in the state trie and the code is not cleared, it stays there forever.

FYI:

func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
    balance := evm.StateDB.GetBalance(contract.Address())
    evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance)

    evm.StateDB.Suicide(contract.Address())
    return nil, nil
}

// Suicide marks the given account as suicided.
// This clears the account balance.
//
// The account's state object is still available until the state is committed,
// getStateObject will return a non-nil account after Suicide.
func (self *StateDB) Suicide(addr common.Address) bool {
    stateObject := self.getStateObject(addr)
    if stateObject == nil {
        return false
    }
    self.journal = append(self.journal, suicideChange{
        account:     &addr,
        prev:        stateObject.suicided,
        prevbalance: new(big.Int).Set(stateObject.Balance()),
    })
    stateObject.markSuicided()
    stateObject.data.Balance = new(big.Int)

    return true
}

An account can only be deleted from State Trie if it is empty. Where empty is defined as:

// Empty returns whether the state object is either non-existent
// or empty according to the EIP161 specification (balance = nonce = code = 0)
func (self *StateDB) Empty(addr common.Address) bool {
    so := self.getStateObject(addr)
    return so == nil || so.empty()
}


// empty returns whether the account is considered empty.
func (s *stateObject) empty() bool {
    return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash)
}

In your case, there is some code, so, the object is not empty.

Nulik
  • 4.1k
  • 1
  • 19
  • 30