将 nonReentrant 修饰符与应付函数一起使用会导致错误吗?
Posted
技术标签:
【中文标题】将 nonReentrant 修饰符与应付函数一起使用会导致错误吗?【英文标题】:Is using nonReentrant modifier with a payable function causes errors? 【发布时间】:2021-12-15 09:29:03 【问题描述】:我创建了一个 ERC-721 合约,该合约具有可支付的铸币功能。我使用了一个 nonReentrant 修饰符,它可以在 Renterancy 下的 Openzeppelin 合同中找到。这会导致错误吗?
payable 是否调用 nonreenterant 修饰符?
【问题讨论】:
请编辑问题以将其限制为具有足够详细信息的特定问题,以确定适当的答案。 【参考方案1】:我是 Solidity 的一名 n00b,但长期从事 C++ 多线程应用程序的程序员。
这种“重入”解决方案可以防止顺序重入,但不能防止多个调用者调用同一函数。两个调用者可能会在其中一个设置 ENTERED 之前通过 ENTERED 检查,所以繁荣,你有一个黑客在那里。
此外,这也太过分了,因为它也可能使有效的交易失败!如果两个不同的用户同时调用一个函数,其中一个会无缘无故地获得失败的交易。
如果我错了,请纠正我,但那里有数十亿美元的钱包。如果这种东西被用来保护他们,哇。
Solidity 需要一种叫做“测试和设置”的东西,它允许不可中断的“检查一个值,如果它没有设置就设置它”。这将允许创建无法被黑客入侵的真正互斥函数。
我所知道的情况并不完全相同。
【讨论】:
【参考方案2】:OpenZeppelin nonReentrant
修饰符 (link) 可防止重入攻击 (link)。
但不影响函数状态的可变性(如payable
)。
【讨论】:
我问的原因是因为我已经部署了一个带有 mint 功能的合同,该功能是可支付的,并在其上添加了 reenterant 修饰符。该功能正常工作,然后停止,当用户尝试使用该功能时会产生巨大的气体!这是合同:etherscan.io/address/… 链接的实现似乎没问题。你能指定发件人传递的tokenId
和msg.value
是什么,当时tokenPrice
的值是多少?我的猜测是任何require()
条件(在mintBinaries()
函数或其依赖项内)都失败了,这将导致交易恢复......计算恢复交易的气体需求很棘手(钱包没有'不知道它是因为某种情况还是因为没有提供足够的gas而恢复)所以一些钱包正试图将gas推荐一直提高到可用限制。
TokenID 是 523 例如(但它实际上是任何令牌 ID,因为只有 ID 8500、2345、8、88、888、1 和 5585 被铸造)并且 msg.value 是 0.01。 tokenPrice 是 10000000000000000 wei (0.01 ETH),自合约创建以来没有改变。我不明白为什么之前一些用户成功铸造时会出现这个问题!此外,我还有另一个名为 ownerClaim 的函数,它允许我在不付费的情况下进行铸币,它适用于上述相同的 tokenID (523)。所以问题出在额外的 require 语句(以前不是问题)或修饰符上。以上是关于将 nonReentrant 修饰符与应付函数一起使用会导致错误吗?的主要内容,如果未能解决你的问题,请参考以下文章
Java 访问修饰符与非访问修饰符 | Java核心知识点整理
Java 访问修饰符与非访问修饰符 | Java核心知识点整理