智能合约是区块链去中心化应用的基石。然而,与所有代码一样,智能合约也存在遭受攻击的漏洞风险。其中,重入攻击(Reentrancy Attack) 是最臭名昭著的漏洞类型之一。本文将深入解析重入攻击的原理,提供存在漏洞的代码示例,并阐述如何防范此类风险。
什么是重入攻击?
重入攻击指智能合约在更新自身状态前调用了外部合约,导致外部合约可在原函数执行完毕前,再次(甚至多次)回调原函数,最终引发合约行为异常并被攻击者利用的攻击方式。
存在漏洞的代码示例
以下是一个用 Solidity 编写的存在重入漏洞的智能合约示例:
pragma solidity ^0.8.0;
contract VulnerableBank {
mapping(address => uint) public balances;
function deposit() public payable {
balances[msg.sender] += msg.value;
}
function withdraw(uint _amount) public {
require(balances[msg.sender] >= _amount, "Insufficient balance");
(bool success, ) = msg.sender.call{value: _amount}("");
require(success, "Transfer failed");
balances[msg.sender] -= _amount;
}
}
上述合约中的 withdraw 函数存在重入漏洞,攻击者可按以下步骤利用该漏洞:
- 攻击者先向
VulnerableBank合约存入一定数量的 ETH; - 攻击者部署一个恶意合约,通过该合约调用
VulnerableBank的withdraw函数; - 在
withdraw函数完成余额扣减前,恶意合约会反复回调withdraw函数,持续耗尽目标合约中的资金。
如何防范重入攻击?
要防范重入攻击,需遵循以下最佳实践:
采用“检查-效应-交互”模式
确保所有状态变更操作(检查与效应) 都在与外部合约交互前完成。
以下是采用该模式优化后的 withdraw 函数:
function withdraw(uint _amount) public {
require(balances[msg.sender] >= _amount, "Insufficient balance");
// Update the state first
balances[msg.sender] -= _amount;
// Interact with the external contract last
(bool success, ) = msg.sender.call{value: _amount}("");
require(success, "Transfer failed");
}
使用重入保护机制
Solidity 生态中,OpenZeppelin 提供的 ReentrancyGuard 合约可直接用于阻止重入调用。
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract SecureBank is ReentrancyGuard {
mapping(address => uint) public balances;
function deposit() public payable {
balances[msg.sender] += msg.value;
}
function withdraw(uint _amount) public nonReentrant {
require(balances[msg.sender] >= _amount, "Insufficient balance");
balances[msg.sender] -= _amount;
(bool success, ) = msg.sender.call{value: _amount}("");
require(success, "Transfer failed");
}
}
通过 nonReentrant 修饰符,可确保 withdraw 函数在一次执行周期内无法被重复调用。
总结
重入攻击是智能合约中的高危漏洞,可能导致巨额资产损失。开发者通过遵循“检查-效应-交互”模式、使用重入保护机制等最佳实践,可有效保护智能合约免受此类攻击。
敬请关注我们的“智能合约漏洞解析”系列下一篇文章,我们将继续探讨更多常见的智能合约漏洞及对应的防护方案。
👇 欢迎关注 OpenBuild 公众号,我们将持续为开发者转载更多技术文章和硬核教程!
💪 欢迎加入 OpenBuild 开发者交流群,和更多开发者一起探讨技术、交流进步!
作者:Mustafa Akbulut
原文:https://medium.com/coinmonks/smart-contract-vulnerabilities-unveiled-reentrancy-attack-75e9a1d4311c
本文内容仅代表原作者观点,旨在分享技术知识。由于编者水平有限,不保证翻译的完全精确性、完整性和时效性。内容仅供参考,不构成任何建议。
654

被折叠的 条评论
为什么被折叠?



