欢迎光临
我们一直在努力

Solidity重入攻击怎么防?这3种代码方案你必须知道

本文详解Solidity重入攻击的防御策略,包含检查-效果-交互模式、OpenZeppelin安全库应用、以及智能合约审计工具实操指南。通过真实攻击案例拆解,手把手教你编写防重入代码,保护DeFi项目安全。

智能合约为何总被黑客盯上?

最近某知名DeFi平台因重入漏洞损失800万美元的新闻冲上热搜。开发者老张凌晨3点紧急求助:明明测试通过的合约,上线后资金却被莫名转走。这其实是典型的重入攻击——黑客在合约状态更新前反复调用提现函数,就像把自动取款机按键卡住不停吐钞。

Solidity重入攻击怎么防?这3种代码方案你必须知道
重入攻击原理示意图

检查-效果-交互模式(CEI)

问题:转账操作在状态更新前执行是重入攻击的温床。
方案:严格执行”先改数据后打钱”的铁律。就像超市收银必须先扫码录入系统再让顾客拿走商品。
案例:某NFT交易平台升级后采用以下代码结构:

function withdraw() public {
    uint amount = balances[msg.sender];
    balances[msg.sender] = 0; // 先清零
    (bool success, ) = msg.sender.call{value: amount}(""); // 后转账
    require(success);
}

防重入锁(ReentrancyGuard)

问题:复杂合约中多个函数可能共享状态变量。
方案:引入状态锁机制,像卫生间门上的”有人/无人”提示牌。
案例:使用OpenZeppelin官方库改造存提款函数:

import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

contract Vault is ReentrancyGuard {
    function deposit() public payable {
        // 存款逻辑
    }

    function withdraw() public nonReentrant {
        // 提现逻辑
    }
}

Gas限额设置

问题:恶意合约通过消耗超额Gas实施攻击。
方案:使用transfer替代call,自动限制2300Gas。
案例:某DEX平台修复漏洞后的转账代码:

address payable receiver = payable(msg.sender);
receiver.transfer(amount); 
// 替代危险的call方式

实战演练:从漏洞发现到修复

用Slither工具扫描合约时提示”reentrancy-eth”警告,具体修复流程分三步:
1. 安装安全分析工具:npm install -g slither
2. 定位风险函数:slither contracts/Vault.sol
3. 在withdraw函数添加nonReentrant修饰符

FAQ:新手防坑指南

Q:用CEI模式就绝对安全吗?
A:基础防护有效,但组合调用仍需防重入锁。就像防盗门要同时装锁和监控。

Q:如何测试防御效果?
A:使用Foundry模拟攻击:
contract Attack {
function startAttack() public {
target.withdraw();
}
receive() external payable {
if(target.balance >= 1 ether) {
target.withdraw();
}
}
}

赞(0)
未经允许不得转载:USDTBI 深度 » Solidity重入攻击怎么防?这3种代码方案你必须知道

评论 抢沙发

USDTBI 导航

精准直达币圈核心资源|交易所·工具·数据·资讯

USDTBI 导航USDTBI 深度

登录

找回密码

注册