Solidity

selfdestruct() 是如何工作的?

  • November 14, 2018

我想知道 selfdestruct() 的實際工作原理。它真的會從儲存中刪除合約程式碼嗎?或者只是從 state trie 中刪除合約地址?如果只是從 state trie 中刪除合約地址,其他新的合約程式碼會覆蓋它嗎?

它被標記為suicided狀態 trie 並且程式碼沒有被清除,它永遠保持在那裡。

供參考:

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
}

只有在 State Trie 為空時,才能從 State Trie 中刪除帳戶。其中空定義為:

// 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)
}

在您的情況下,有一些程式碼,因此該對像不為空。

附加說明:

函式中的這一行statedb.Suicide()

stateObject.data.Balance = new(big.Int)

清除餘額,因此,如果您在合約上呼叫 SELFDESTRUCT,並且地址錯誤,例如將資金發送到合約本身,而不是所有者,則合約的餘額為零。我最近發現這是此交易中的一個案例https://etherscan.io/tx/0x52676b10cf1d1240355e8fcd1154a99327626bd3094cb7ff685a928bdec5b137

引用自:https://ethereum.stackexchange.com/questions/54660