广场
最新
热门
资讯
我的主页
发布
HalfBuddhaMoney
2026-05-14 15:11:42
关注
我想分享一件相当重要但你可能还不太清楚的事情——那就是智能合约中的重入漏洞。如果你正在开发去中心化应用(dapp)或与区块链打交道,这个知识点是必须掌握的。
重入漏洞的基本问题是什么?它发生在一个智能合约调用另一个合约时,而被调用的合约可能在执行过程中再次调用原始合约。攻击者可以利用这个时间差来窃取资金。
想象一下,ContractA 持有 10 Ether,而 ContractB 已经向它发送了 1 Ether。当 ContractB调用提款函数时,ContractA会检查余额是否大于0,如果是,就会向它返回 Ether。但这里的问题是——ContractA只在发钱后才更新余额。因此,在发钱的过程中,如果ContractB有一个fallback函数,它可以再次调用ContractA的提款函数。由于余额还没有被更新,检查依然通过,它又会多获得1 Ether。这个循环会持续,直到ContractA的余额耗尽。
我将告诉你三种保护合约免受重入攻击的方法。
第一种是使用nonReentrant修饰符。这个思路非常简单——在函数执行时锁住合约。如果有人试图再次调用这个函数,它会被拒绝,因为合约处于锁定状态。你必须等函数执行完毕后才解锁,此时再次调用会失败。
第二种是采用“检查-效果-交互”模式。不是在发钱后再更新余额,而是在检查余额后立即更新,但在发钱之前。这样,即使其他合约再次调用,余额也已经变成0了,检查就会失败。这也是为什么顺序非常重要——先检查,再更新状态,最后与其他合约交互。
第三种是创建一个单独的GlobalReentrancyGuard合约,特别适合多个合约相互调用的场景。不是为每个函数单独保护,而是建立一个共享的守卫合约,用来存储锁定状态。当任何合约试图调用受保护的函数时,它会先检查这个守卫合约。如果守卫显示合约已被锁定,交易就会被拒绝。这种方式非常强大,因为它可以防止多个合约之间的重入攻击。
我建议你根据具体情况采用这三种技术中的一种或多种。对于提款或转账操作,始终使用nonReentrant或“检查-效果-交互”模式。如果你的项目涉及复杂的合约系统,也可以考虑引入GlobalReentrancyGuard作为额外的保护层。
这是最常见的导致重大资金损失的漏洞之一,理解重入漏洞非常重要,只有这样你才能写出安全的智能合约。
XCH
0.13%
TRA
0.68%
XEM
-1.30%
查看原文
此页面可能包含第三方内容,仅供参考(非陈述/保证),不应被视为 Gate 认可其观点表述,也不得被视为财务或专业建议。详见
声明
。
赞赏
点赞
评论
转发
分享
评论
请输入评论内容
请输入评论内容
评论
暂无评论
热门话题
查看更多
#
预测世界杯挪威VS英格兰
32.2万 热度
#
GateUS合规扩展佛罗里达
431.73万 热度
#
美股AI概念股普涨
251.99万 热度
#
美伊战争阴云再起
399.69万 热度
#
GUSD年化升至3.8%
86.32万 热度
置顶
网站地图
我想分享一件相当重要但你可能还不太清楚的事情——那就是智能合约中的重入漏洞。如果你正在开发去中心化应用(dapp)或与区块链打交道,这个知识点是必须掌握的。
重入漏洞的基本问题是什么?它发生在一个智能合约调用另一个合约时,而被调用的合约可能在执行过程中再次调用原始合约。攻击者可以利用这个时间差来窃取资金。
想象一下,ContractA 持有 10 Ether,而 ContractB 已经向它发送了 1 Ether。当 ContractB调用提款函数时,ContractA会检查余额是否大于0,如果是,就会向它返回 Ether。但这里的问题是——ContractA只在发钱后才更新余额。因此,在发钱的过程中,如果ContractB有一个fallback函数,它可以再次调用ContractA的提款函数。由于余额还没有被更新,检查依然通过,它又会多获得1 Ether。这个循环会持续,直到ContractA的余额耗尽。
我将告诉你三种保护合约免受重入攻击的方法。
第一种是使用nonReentrant修饰符。这个思路非常简单——在函数执行时锁住合约。如果有人试图再次调用这个函数,它会被拒绝,因为合约处于锁定状态。你必须等函数执行完毕后才解锁,此时再次调用会失败。
第二种是采用“检查-效果-交互”模式。不是在发钱后再更新余额,而是在检查余额后立即更新,但在发钱之前。这样,即使其他合约再次调用,余额也已经变成0了,检查就会失败。这也是为什么顺序非常重要——先检查,再更新状态,最后与其他合约交互。
第三种是创建一个单独的GlobalReentrancyGuard合约,特别适合多个合约相互调用的场景。不是为每个函数单独保护,而是建立一个共享的守卫合约,用来存储锁定状态。当任何合约试图调用受保护的函数时,它会先检查这个守卫合约。如果守卫显示合约已被锁定,交易就会被拒绝。这种方式非常强大,因为它可以防止多个合约之间的重入攻击。
我建议你根据具体情况采用这三种技术中的一种或多种。对于提款或转账操作,始终使用nonReentrant或“检查-效果-交互”模式。如果你的项目涉及复杂的合约系统,也可以考虑引入GlobalReentrancyGuard作为额外的保护层。
这是最常见的导致重大资金损失的漏洞之一,理解重入漏洞非常重要,只有这样你才能写出安全的智能合约。