selfdestruct
指令可以用來刪除智能合約,並將合約剩餘的 ETH 轉到指定的地址。selfdestruct
是為了回應合約出錯的極端情況而設計的。它最早被命名為 suicide
(自殺),但這個詞太敏感。為了保護憂鬱的程式設計師(XD),改名為 selfdestruct
,在v0.8.18 版本中,selfdestruct
關鍵字被標記為「不再建議使用」,在某些情況下它會導致預期之外的合約語義,但由於目前還沒有取代方案,目前只是對開發者做了編譯階段的警告,相關內容可以查 看EIP-6049。
selfdestruct(_addr);
其中 _addr
是接收合約中剩餘 ETH 的地址。_addr
地址不需要有 receive()
或fallback()
也能接收 ETH。
contract DeleteContract {
uint public value = 10;
constructor() payable {}
receive() external payable {}
function deleteContract() external {
// 呼叫 selfdestruct 銷毀合約,並把剩餘的 ETH 轉給 msg.sender
selfdestruct(payable(msg.sender));
}
function getBalance() external view returns(uint balance){
balance = address(this).balance;
}
}
部署好合約後,可向 DeleteContract
合約轉入 1 ETH。這時,getBalance()
會回傳 1 ETH,value
變數是 10。
當我們呼叫 deleteContract()
函數,合約將觸發 selfdestruct
操作。在坎昆升級前,合約會被自毀。但升級後,合約依然存在,只是將合約包含的 ETH 轉移到指定地址,而合約依然能夠呼叫。
contract DeployContract {
struct DemoResult {
address addr;
uint balance;
uint value;
}
constructor() payable {}
function getBalance() external view returns(uint balance){
balance = address(this).balance;
}
function demo() public payable returns (DemoResult memory){
DeleteContract del = new DeleteContract{value:msg.value}();
DemoResult memory res = DemoResult({
addr: address(del),
balance: del.getBalance(),
value: del.value()
});
del.deleteContract();
return res;
}
}
ABI (Application Binary Interface,應用二進位介面)是與以太坊智能合約互動的標準。資料基於他們的類型編碼;並且由於編碼後不包含類型訊息,解碼時需要註明它們的類型。
Solidity 中,ABI 編碼有 4 個函數:abi.encode
、abi.encodePacked
、 abi.encodeWithSignature
、abi.encodeWithSelector
。而 ABI 解碼有 1 個函數:abi.decode
,用於解碼 abi.encode
的資料。