【从0学习Solidity】26. 删除合约
- 博主简介:不写代码没饭吃,一名全栈领域的创作者,专注于研究互联网产品的解决方案和技术。熟悉云原生、微服务架构,分享一些项目实战经验以及前沿技术的见解。
- 关注我们的主页,探索全栈开发,期待与您一起在移动开发的世界中,不断进步和创造!
- 本文收录于 不写代码没饭吃 的学习汇报系列,大家有兴趣的可以看一看。
- 欢迎访问我们的微信公众号:不写代码没饭吃,获取更多精彩内容、实用技巧、行业资讯等。您关注的是我们前进的动力!
selfdestruct
selfdestruct
命令可以用来删除智能合约,并将该合约剩余ETH
转到指定地址。selfdestruct
是为了应对合约出错的极端情况而设计的。它最早被命名为suicide
(自杀),但是这个词太敏感。为了保护抑郁的程序员,改名为selfdestruct
;在 v0.8.18 版本中,selfdestruct
关键字被标记为「不再建议使用」,在一些情况下它会导致预期之外的合约语义,但由于目前还没有代替方案,目前只是对开发者做了编译阶段的警告,相关内容可以查看 EIP-6049。
如何使用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
来停止黑客的攻击吧。
如果这份博客对大家有帮助,希望各位给作者一个免费的点赞👍作为鼓励,并评论收藏一下⭐,谢谢大家!!!
制作不易,如果大家有什么疑问或给作者的意见,欢迎评论区留言。