Solidity
selfdestruct() 是如何工作的?
我想知道 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