-
bitcoin $78074.098354 USD
1.89% -
ethereum $2299.014391 USD
2.17% -
tether $0.998449 USD
0.01% -
bnb $700.460149 USD
1.26% -
xrp $1.273048 USD
1.81% -
usd-coin $0.999762 USD
0.01% -
solana $92.929882 USD
1.25% -
tron $0.321666 USD
0.30% -
zcash $1272.523101 USD
12.65% -
hyperliquid $84.856242 USD
1.58% -
monero $637.212844 USD
3.50% -
dogecoin $0.074680 USD
1.23% -
unus-sed-leo $9.292529 USD
-0.02% -
chainlink $11.063098 USD
-0.05% -
cardano $0.190385 USD
1.97%
如何防止固体重新进入?
Reentrancy in Solidity occurs when an external call allows a malicious contract to recursively execute the same function, potentially draining funds or corrupting state.
2025/07/20 08:49
了解坚固的重新注入
重新输入是固体智能合约中的关键安全漏洞,当功能在完成内部状态变更之前对不受信任的合同进行外部呼叫时,就会发生。这使外部合同可以递归地回到原始功能,可能耗尽资金或破坏合同的逻辑。
2016年臭名昭著的DAO黑客是如何利用重新进入的一个典型例子。攻击者使用恶意的后备功能在合同更新其余额之前反复触发撤离,从而导致数百万的以太币损失。
为了防止此类漏洞,开发人员必须实施最佳实践和设计模式,以确保外部呼叫并确保在任何外部互动之前发生状态变化。
使用检查效应互动模式
防止重新进入的最有效方法之一是遵循检查效应互动模式。此模式可确保在执行任何外部呼叫之前进行所有内部状态更改。
- 检查:验证输入和条件。
- 效果:更新合同的状态变量。
- 互动:致电外部合同或发送以太。
通过遵守此订单,您可以确保即使发生重新输入尝试,内部状态也已被更新,以防止双人支出或未经授权的余额访问。
例如,考虑一个简单的提款功能:
function withdraw(uint amount) public {require(balances[msg.sender] >= amount); balances[msg.sender] -= amount; (bool success, ) = msg.sender.call{value: amount}(''); require(success);
}
在这种情况下,余额将在外部呼叫之前进行更新,从而使其免受重新输入。
实现Mutex锁
防止重新进入的另一种有效方法是使用MUTEX锁定,这是一种防止执行过程中重新进入的状态变量。
一个简单的示例涉及使用布尔标志来阻止重新进入:
bool private locked;函数提取(UINT金额)public {require(!locked); locked = true; require(balances[msg.sender] >= amount); balances[msg.sender] -= amount; (bool success, ) = msg.sender.call{value: amount}(''); require(success); locked = false;}
这样可以确保该函数在仍在执行时无法重新输入,从而有效地阻止了递归调用。但是,开发人员在使用静音时必须谨慎,以免产生僵局或意外行为。
使用openzeppelin的重新进入守卫
开发人员无需手动实施Mutex逻辑,而是使用OpenZeppelin提供的重新进入守卫合同,该合同提供了安全且经过测试的解决方案。
使用重新输入守卫:
- 导入合同:
import '@openzeppelin/contracts/security/ReentrancyGuard.sol'; - 您的合同中继承它:
contract MyContract is ReentrancyGuard - 将
nonReentrant修饰符应用于容易重新进入的功能。
pragma solidity ^0.8.0;导入'@openzeppelin/contracts/security/recentrancyguard.sol';合同securewithDrawal是重新进入guart {
mapping(address => uint) public balances; function deposit() external payable { balances[msg.sender] += msg.value; } function withdraw(uint amount) external nonReentrant { require(balances[msg.sender] >= amount, 'Insufficient balance'); balances[msg.sender] -= amount; (bool success, ) = msg.sender.call{value: amount}(''); require(success, 'Transfer failed'); }}
这种方法抽象了静音处理的复杂性,并降低了引入错误的风险,使其成为许多开发人员的首选方法。
避免原始呼叫并安全使用转移
在坚固的情况下,使用address.call{value: ...}('')比transfer()或send()更灵活,但它也消除了气体限制,使其容易受到重新进入。
-
transfer()和send()仅向前转发2300天气,这不足以进行任何有意义的执行,从而防止重新进入。 - 但是,
call()转发所有可用的气体,使攻击者可以在后备或接收功能期间执行复杂的恶意逻辑。
为此缓解:
- 对于简单的以太转移,更喜欢
transfer()或send()。 - 如果需要使用
call(),请确保状态变化发生在呼叫之前发生,并将重新进入警卫队进行。
常见问题解答:常见问题
问:什么是固体攻击是什么?答:当外部合同完成执行之前,外部合同回到呼叫功能时,会发生重新进入攻击,通常会导致未经授权的基金提款或州腐败。
问:我可以在不使用Openzeppelin的重新进入守卫的情况下防止重新进入吗?答:是的,通过手动实现检查效应互动模式或使用静音锁定在执行功能期间的重新输入。
问:在现代固体版本中使用address.transfer()安全吗?答:虽然transfer()限制气体并防止重新进入,但如果收件人合同用尽了气体,则可能意外失败。对于简单的传输,它仍然比call()更安全。
问:所有外部呼叫的坚固性是否容易被重新进入?答:不是全部,但是对用户控制合同的任何外部呼叫都可以是潜在的向量。当状态变化遵循外部呼叫而不是呼叫本身时,就会出现漏洞。
免责声明:info@kdj.com
所提供的信息并非交易建议。根据本文提供的信息进行的任何投资,kdj.com不承担任何责任。加密货币具有高波动性,强烈建议您深入研究后,谨慎投资!
如您认为本网站上使用的内容侵犯了您的版权,请立即联系我们(info@kdj.com),我们将及时删除。
- 法国银行加密货币损失:ZachXBT 揭露 Crédit Mutuel Arkéa 涉嫌被盗 1.33 亿美元
- 2026-11-04 16:55:01
- 民主党确保美国众议院控制权,中期选举开启国会新时代
- 2026-11-04 16:45:01
- 美国中期选举、预测市场和加密货币竞赛:对华盛顿未来的高风险赌注
- 2026-11-04 04:30:22
- 数字资产、全球金融和人工智能:在 DavosWeb3 及其他领域探索下一个前沿
- 2026-11-04 04:30:22
- 在更广泛的市场困境中,AVAX 价格下跌;机构兴趣依然浓厚
- 2026-11-03 12:35:02
- 为什么量化价格下跌?深入探讨 QNT 最近在市场动荡中的下滑
- 2026-11-03 12:55:01
相关百科
如何计算持有 BTCUSDT 期货头寸的总成本
2026-10-26 04:06:35
BTCUSDT 期货头寸的总成本构成1. 持有BTCUSDT期货头寸的总成本包括显性费用和隐性费用。显性成本包括开仓和平仓交易费用,而隐性成本主要来自一段时间内的资金费率支付或收入。 2. 开仓费用按照入场时的名义价值与交易所的吃单/挂单费用表的乘积计算——对于主要平台上的吃单来说,开仓费用通常在 ...
如何同时监控 XRPUSDT 资金费率和未平仓合约
2026-10-20 18:39:42
XRPUSDT 永续合约的资金费率机制1. XRPUSDT永续合约的资金费率每八小时计算一次,使用XRP和USDT计价借贷市场之间的溢价指数和利差。 2. Binance、Bybit 和 OKX 等交易所在其衍生品 API 端点中发布实时资金费率数据,从而实现仪表板或警报系统的自动摄取。 3. 正的...
如何设置 SOLUSDT 永续合约盈亏平衡止损
2026-10-23 09:34:18
了解盈亏平衡止损机制1. 盈亏平衡止损是一种动态订单,随着头寸盈利变动而向上调整,执行时锁定零净损失。 2. 它仅在交易达到预定利润阈值后才起作用——通常是初始风险或入场费的 1 至 2 倍。 3. 在币安 SOLUSDT 永续合约上,此逻辑必须手动触发或编写脚本,因为本机交易所 UI 不会自动将止...
如何使用币安期货计算器进行 ETHUSDT 交易
2026-10-21 02:00:11
了解币安期货计算器界面1. 该计算器直接嵌入币安合约交易界面中,可通过订单输入面板下的 ETHUSDT 永续合约页面访问。 2. 随着用户调整输入字段(包括仓位大小、入场价格、杠杆水平以及止盈或止损水平),它会动态更新。 3. 接受多种格式的输入值:合约数量(ETH)、名义价值(USDT)或保证金金...
合约强平前如何查看BTCUSDT标记价格
2026-10-26 12:20:18
了解BTCUSDT期货的标记价格1. 标记价格是交易所为防止市场波动期间出现不公平清算而使用的计算值。 2.反映了来自多个来源的公平、稳定的参考价格,包括指数价格和资金费率。 3. 与最新成交价不同,标记价格包含来自顶级现货交易所的时间加权平均值,以降低操纵风险。 4. 在币安上,BTCUSDT标记...
如何调整 TRUMPUSDT 永续合约的杠杆
2026-10-30 22:19:37
了解 TRUMPUSDT 永续合约机制1. TRUMPUSDT 是在多个一级衍生品交易所上市的主题永续期货合约,旨在跟踪围绕美国政治叙事而非基础资产基本面的价格情绪。 2、根据平台不同,采用标准的反向或线性结算逻辑,以USDT作为报价和保证金资产。 3. 合约使用的标记价格源自现货 BTC/USDT...
如何计算持有 BTCUSDT 期货头寸的总成本
2026-10-26 04:06:35
BTCUSDT 期货头寸的总成本构成1. 持有BTCUSDT期货头寸的总成本包括显性费用和隐性费用。显性成本包括开仓和平仓交易费用,而隐性成本主要来自一段时间内的资金费率支付或收入。 2. 开仓费用按照入场时的名义价值与交易所的吃单/挂单费用表的乘积计算——对于主要平台上的吃单来说,开仓费用通常在 ...
如何同时监控 XRPUSDT 资金费率和未平仓合约
2026-10-20 18:39:42
XRPUSDT 永续合约的资金费率机制1. XRPUSDT永续合约的资金费率每八小时计算一次,使用XRP和USDT计价借贷市场之间的溢价指数和利差。 2. Binance、Bybit 和 OKX 等交易所在其衍生品 API 端点中发布实时资金费率数据,从而实现仪表板或警报系统的自动摄取。 3. 正的...
如何设置 SOLUSDT 永续合约盈亏平衡止损
2026-10-23 09:34:18
了解盈亏平衡止损机制1. 盈亏平衡止损是一种动态订单,随着头寸盈利变动而向上调整,执行时锁定零净损失。 2. 它仅在交易达到预定利润阈值后才起作用——通常是初始风险或入场费的 1 至 2 倍。 3. 在币安 SOLUSDT 永续合约上,此逻辑必须手动触发或编写脚本,因为本机交易所 UI 不会自动将止...
如何使用币安期货计算器进行 ETHUSDT 交易
2026-10-21 02:00:11
了解币安期货计算器界面1. 该计算器直接嵌入币安合约交易界面中,可通过订单输入面板下的 ETHUSDT 永续合约页面访问。 2. 随着用户调整输入字段(包括仓位大小、入场价格、杠杆水平以及止盈或止损水平),它会动态更新。 3. 接受多种格式的输入值:合约数量(ETH)、名义价值(USDT)或保证金金...
合约强平前如何查看BTCUSDT标记价格
2026-10-26 12:20:18
了解BTCUSDT期货的标记价格1. 标记价格是交易所为防止市场波动期间出现不公平清算而使用的计算值。 2.反映了来自多个来源的公平、稳定的参考价格,包括指数价格和资金费率。 3. 与最新成交价不同,标记价格包含来自顶级现货交易所的时间加权平均值,以降低操纵风险。 4. 在币安上,BTCUSDT标记...
如何调整 TRUMPUSDT 永续合约的杠杆
2026-10-30 22:19:37
了解 TRUMPUSDT 永续合约机制1. TRUMPUSDT 是在多个一级衍生品交易所上市的主题永续期货合约,旨在跟踪围绕美国政治叙事而非基础资产基本面的价格情绪。 2、根据平台不同,采用标准的反向或线性结算逻辑,以USDT作为报价和保证金资产。 3. 合约使用的标记价格源自现货 BTC/USDT...
查看所有文章














