Solidity极简入门: 26. 删除合约
我最近在重新学solidity,巩固一下细节,也写一个“Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。
欢迎关注我的推特:@0xAA_Science
欢迎加入WTF科学家社区,内有加微信群方法:链接
所有代码和教程开源在github: github.com/AmazingAng/WTFSolidity
selfdestruct
selfdestruct
命令可以用来删除智能合约,并将该合约剩余ETH
转到指定地址。selfdestruct
是为了应对合约出错的极端情况而设计的。它最早被命名为suicide
(自杀),但是这个词太敏感。为了保护抑郁的程序员,改名为selfdestruct
。
如何使用selfdestruct
selfdestruct
使用起来非常简单:
selfdestruct(_addr);
其中_addr
是接收合约中剩余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
合约中,我们写了一个public
状态变量value
,两个函数:getBalance()
用于获取合约ETH
余额,deleteContract()
用于自毁合约,并把ETH
转入给发起人。
部署好合约后,我们向DeleteContract
合约转入1 ETH
。这时,getBalance()
会返回1 ETH
,value
变量是10。
当我们调用deleteContract()
函数,合约将自毁,所有变量都清空,此时value
变为默认值0
,getBalance()
也返回空值。
注意事项
对外提供合约销毁接口时,最好设置为只有合约所有者可以调用,可以使用函数修饰符
onlyOwner
进行函数声明。当合约被销毁后与智能合约的交互也能成功,并且返回0。
当合约中有
selfdestruct
功能时常常会带来安全问题和信任问题,合约中的Selfdestruct功能会为攻击者打开攻击向量(例如使用selfdestruct
向一个合约频繁转入token进行攻击,这将大大节省了GAS的费用,虽然很少人这么做),此外,此功能还会降低用户对合约的信心。
在remix上验证
- 部署合约并且转入1ETH,查看合约状态
- 销毁合约,查看合约状态
从测试中观察合约状态可以发现合约销毁后的ETH返回给了指定的地址,并且在合约销毁后依然可以请求交互,所以我们不能根据这个来判断合约是否已经销毁。
总结
selfdestruct
是智能合约的紧急按钮,销毁合约并将剩余ETH
转移到指定账户。当著名的The DAO
攻击发生时,以太坊的创始人们一定后悔过没有在合约里加入selfdestruct
来停止黑客的攻击吧。