selfdestruct

  • selfdestruct 关键字强制将当前合约余额转给传参地址
  • 自毁关键字下的转账行为是不可控,任何合约内部执行 selfdestruct 后都会把余额强制转给传参地址

Dencun upgrade

Dencun 升级后针对 selfdestruct 的问题进行了修正升级:

  • selfdestruct 交易仅仅将合约余额发送到传参地址, 并且不会清除合约状态和代码
  • 销毁后,不用再次通过 CREATE2 部署相同地址合约,因为原地址的状态和代码还保留在链上
  • 销毁后,任何的外部调用 call|delegateCall 也不会失败
  • 也不会存在代币锁仓的隐患,因为之前合约的逻辑和状态并未清空

Solidity Examples

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

contract Sale {
    uint256 public num;

    function buy() external payable {
        num += 1;
        // _end();
    }

    function _end() public {
        // 仍然保留 num 状态变量的参数
        selfdestruct(payable(msg.sender));
    }

    function bal() external view returns (uint256 baln) {
        baln = address(this).balance;
    }
}

contract caller {
    constructor() payable {}

    function buy(Sale sale) external {
        (bool success, ) = address(sale).call{value: 100 wei}(
            abi.encodeWithSelector(sale.buy.selector)
        );
        if (!success) {
            revert();
        }
    }
}