首页 > 其他分享 >如何防止智能合约中的重入攻击

如何防止智能合约中的重入攻击

时间:2024-12-24 17:55:54浏览次数:4  
标签:重入 sender success require 智能 amount msg balance 合约

以下是更详细的解释如何防止智能合约中的重入攻击,以及每种方法的原理和示例代码:


1. 更改状态变量优先

重入攻击的原理是:在调用外部合约时,攻击者通过回调函数再次调用受害合约的函数,在状态变量未及时更新的情况下,导致合约逻辑被重复执行。

防御措施:

  • 在与外部合约交互之前,先更新合约的状态变量。
  • 这样即使攻击者试图重入,状态变量已经被修改,不会满足条件。

示例代码:

solidity
// 脆弱合约:重入攻击漏洞
function withdraw(uint256 amount) public {
    require(balance[msg.sender] >= amount, "Insufficient balance");

    // 与外部合约交互前未更新余额
    (bool success, ) = msg.sender.call{value: amount}("");
    require(success, "Transfer failed");

    // 更新余额
    balance[msg.sender] -= amount;  // 攻击者可重复调用
}

// 修复后的代码
function withdraw(uint256 amount) public {
    require(balance[msg.sender] >= amount, "Insufficient balance");

    // **先更新状态变量**
    balance[msg.sender] -= amount;

    // 与外部合约交互
    (bool success, ) = msg.sender.call{value: amount}("");
    require(success, "Transfer failed");
}

2. 使用 checks-effects-interactions 模式

这是 Solidity 开发的推荐模式,按以下顺序编写合约代码:

  1. Checks:先检查函数的输入和前置条件是否满足。
  2. Effects:更新合约的状态变量。
  3. Interactions:最后再与外部合约进行交互。

示例代码:

solidity
function withdraw(uint256 amount) public {
    // **Checks**: 验证条件
    require(balance[msg.sender] >= amount, "Insufficient balance");

    // **Effects**: 更新状态变量
    balance[msg.sender] -= amount;

    // **Interactions**: 与外部合约交互
    (bool success, ) = msg.sender.call{value: amount}("");
    require(success, "Transfer failed");
}

这种顺序确保了在交互过程中,攻击者即使试图进行重入攻击,合约的状态变量已经被更新,从而避免了重复执行逻辑。


3. 使用 ReentrancyGuard

ReentrancyGuard 是 OpenZeppelin 提供的一个 Solidity 库,通过一个简单的布尔变量来防止重入攻击。

实现原理:

  • 使用一个修饰符(nonReentrant)防止在一个函数执行时再次调用它。
  • 修饰符通过一个布尔锁实现,如果函数正在执行,锁会启用,从而拒绝重入调用。

示例代码:

solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

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

contract SecureContract is ReentrancyGuard {
    mapping(address => uint256) public balance;

    function withdraw(uint256 amount) public nonReentrant {
        require(balance[msg.sender] >= amount, "Insufficient balance");

        balance[msg.sender] -= amount;

        (bool success, ) = msg.sender.call{value: amount}("");
        require(success, "Transfer failed");
    }
}

在这里,nonReentrant 修饰符确保了 withdraw 函数不能被重复调用。


4. 其他建议和最佳实践

除了上述主要防御方法,还可以采取以下措施:

  • 限制函数调用次数:为敏感操作设置调用次数或频率限制。
  • 使用 pull-over-push 模式:让用户主动提取资金(pull),而不是自动发送(push),减少对外部账户的依赖。
  • 定期审计代码:重入攻击往往隐藏在复杂的逻辑中,定期进行审计是有效的防御方法。

示例代码(pull-over-push 模式):

solidity
function claimReward() public {
    uint256 reward = rewards[msg.sender];
    require(reward > 0, "No reward available");

    // **Effects**: 先重置奖励
    rewards[msg.sender] = 0;

    // **Interactions**: 再发送奖励
    (bool success, ) = msg.sender.call{value: reward}("");
    require(success, "Transfer failed");
}

总结

  • 更改状态变量优先checks-effects-interactions 模式 是预防重入攻击的基本编程习惯。
  • 对复杂项目,建议使用 ReentrancyGuard 提供更全面的防护。
  • 在开发过程中始终关注 代码的逻辑顺序和外部交互时机,并采用可靠的工具和框架进行测试和审计

标签:重入,sender,success,require,智能,amount,msg,balance,合约
From: https://www.cnblogs.com/zhanchenjin/p/18628379

相关文章

  • K - 近邻模型知识点全览:构建智能预测的基石
    定义K-近邻(K-NearestNeighbors,KNN)模型是一种基于实例的监督学习算法。它的基本思想是给定一个训练数据集,对于一个新的输入实例,在训练数据集中找到与它最相似(距离最近)的K个实例,然后根据这K个实例的类别(对于分类问题)或数值(对于回归问题)来预测新实例的类别或数值。例如,在一......
  • 智能脂肪秤方案pcba设计研发步骤解析
    一、智能脂肪秤的创新之处1.精准测量技术智能脂肪秤采用先进的生物电阻抗分析(BIA)技术,能够准确测量人体的体脂率、肌肉量、骨量等多项身体指标。同时,通过不断优化测量算法和传感器技术,提高了测量的精度和稳定性。2.蓝牙连接与智能应用智能脂肪秤通过蓝牙技......
  • 免费学习基于SpringBoot的高考志愿智能推荐系统
    免费学习基于SpringBoot的高考志愿智能推荐系统摘要科学技术日新月异,人们的生活都发生了翻天覆地的变化,高考志愿智能推荐系统管理当然也不例外。过去的信息管理都使用传统的方式实行,既花费了时间,又浪费了精力。在信息如此发达的今天,我们可以通过网络这个媒介,快速的查找自己想要......
  • 智能网联汽车功能安全及预期功能安全测试解决方案
    概述    智能化与网联化已经是当前汽车行业主要的发展趋势,伴随着电子电气系统(E/E系统)复杂程度增加并承担更多的主动策略,E/E系统失效、智能驾驶性能边界等引发的安全风险成为汽车行业不可忽视的问题。      经纬恒润安全团队致力于为国内外整车厂和零部件供应商提......
  • 智能监控与实时响应:下一代防火墙运维方案
        防火墙是维护网络安全的关键要素之一。随着网络攻击手段的不断复杂化、智能化以及高速化的发展,防火墙作为网络安全的第一道防线,其重要性愈发凸显。有效的防火墙管理不仅能够确保其运行和性能的稳定性,同时也能显著降低企业面临的外部威胁风险。随着防火墙数量的增加以......
  • AI智能体引领未来:展望2025年
    AI智能体引领未来:展望2025年机器AI学习数据AI挖掘 2024年12月22日19:05 安徽人工智能(AI)代理,借助尖端的生成式人工智能(GenAI)技术,预计到2025年将成为技术领域最具颠覆性的力量。这些能够执行复杂任务且仅需最少人工干预的自主系统,正准备革新行业、重新定义工作流程并提升生......
  • 一般大模型的熵是用什么来计算的,你认为这种生成式AI是能达到通用人工智能的吗?如果不是
    GPT-4oPoe1.大模型的熵是如何计算的?在生成式大模型(如GPT系列、Transformer模型)中,熵的计算通常用于衡量模型在预测过程中的不确定性,主要体现在概率分布上。以下是大模型中熵的具体计算方式:1.1概率分布与熵生成式大模型的输出通常是一个基于软最大化(softmax)的概率分布......
  • 【数据库开发】探索数据库智能运维之数据库关键运行指标
    随着金融业务转型步伐加快、业务连续性要求趋严,对金融业信息系统运行的稳定性要求日益提升。数据库作为信息系统中关键技术基础,如何应用数据库海量运行数据,提升运行指标数据观测性,及时发现数据库运行潜在风险,是G行数据库管理团队一直探索的课题。数据库管理团队负责G行所有生产数......
  • 魔搭Modahub AI 应用(包括智能体)平台架构
    魔搭为AI应用(包括智能体)开发人员提供了一站式全链路的AI应用搭建能力,包括应用开发、测评、监控和丰富的发布渠道。如下图所示,空间是魔搭平台的最顶层的资源组织方式,通过工作空间对开发资源进行隔离。空间:空间是资源组织的基础单元,不同空间内的资源和数据相互隔离。一个......
  • 从手工到智能:如何通过管理软件提升库存管理水平
    一、库存管理的痛点库存管理涉及到原材料采购、产品存储、库存盘点、产品出库等多个环节。虽然在许多行业中库存管理被视为基础性工作,但它的复杂性和动态性常常给企业带来以下痛点:1.库存信息不准确在传统的库存管理方式中,很多企业依赖人工记录和手动更新库存信息。无论是纸质记......