重入攻击:理解和防止这种智能合约漏洞

我花了无数小时调试合约漏洞,让我告诉你——重入攻击是智能合约的隐形杀手。它们看似简单却极具破坏性。让我们深入了解它们是什么,以及如何在它们耗尽你的资金之前阻止它们。

当我第一次遇到重入漏洞时,我花了数小时试图理解有人如何能够利用这样一段看似无辜的代码。这个概念令人沮丧地简单:一个合约可以在第一个执行完成之前回调另一个合约。

想象一下:ContractA 有 10 ETH,而 ContractB 已经存入了 1 ETH。当 ContractB 提取其资金时,ContractA 在将 B 的余额更新为零之前发送了 ETH。这个微小的顺序错误造成了巨大的安全漏洞。

发生了什么?恶意合约的回退函数立即再次调用withdraw(),由于余额尚未更新,它再次通过余额检查!这个循环会一直重复,直到ContractA被完全耗尽。真聪明,不是吗?

攻击者如何在代码中利用这一点:

// 攻击合约调用 withdraw() 合约 A 发送 ETH 以 ETH 触发 fallback() // fallback() 在余额更新之前再次调用 withdraw() // 清洗并重复,直到所有资金被盗

我见过项目因为没有理解这个简单的攻击向量而损失数百万。这让我感到愤怒的是,仍然有很多开发者犯这样的初学者错误。

保护您的合同的三种技术

  1. 非重入修饰符

    这在执行期间锁定合约,防止任何带有此修饰符的功能被重新进入。简单但有效。

  2. 检查-效果-交互模式

    这是我个人最喜欢的。代替:

    // 脆弱 require(balance > 0); send(ether); 余额 = 0;

    做这个:

安全 require(balance > 0); balance = 0; // 在外部交互之前更新状态 send(以太坊);

在发送ETH或代币之前,请始终更新您的状态!

  1. GlobalReentrancyGuard

对于具有多个相互作用的合约的项目,这通过使用共享锁定机制为您的整个合约生态系统提供保护。

这些技术不仅仅是学术上的——它们已经拯救了无数项目免于完全的财务破产。

太多开发者仍然认为"这不会发生在我身上",因此跳过这些保护措施。不要成为那种人。每一个发送ETH或代币的函数都应该至少实施其中一种保护机制。

记住,在智能合约开发中,偏执是一种特性,而不是错误。一个遗漏的保护措施可能会导致一切付诸东流。

ETH0.63%
查看原文
此页面可能包含第三方内容,仅供参考(非陈述/保证),不应被视为 Gate 认可其观点表述,也不得被视为财务或专业建议。详见声明
  • 赞赏
  • 评论
  • 转发
  • 分享
评论
0/400
暂无评论
交易,随时随地
qrCode
扫码下载 Gate App
社群列表
简体中文
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)