Solidity

ReentrancyGuard.sol 中的程式碼無法訪問

  • October 31, 2022
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

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

contract SavingsContract is ReentrancyGuard{

address owner;
uint8 interest = 10;

struct Savers{
   address saver;
   uint savedAmount;
   uint dateOfDeposit;
}
Savers[] public savers;

constructor(){
   owner = msg.sender;
}
modifier onlyOwner{
   owner == msg.sender;
   _;
}

function depositMoney() payable public {
   require(msg.value <= (msg.sender).balance,"Insufficient funds");
   require(msg.value >= 10000, "Need to send min 10 000 Wei");
   savers.push(Savers(msg.sender, msg.value, block.timestamp));
}
function interestEarned() view public returns(uint){
   uint storedTime;
   for (uint i=0; i < savers.length; ++i){
       Savers storage savingsAccount = savers[i];
       if (msg.sender == savingsAccount.saver){
           storedTime = block.timestamp - savingsAccount.dateOfDeposit;
           return (savingsAccount.savedAmount);
       }
   }
}
function withdraw() external nonReentrant {
   uint storedTime;
   for (uint i=0; i < savers.length; ++i){
       Savers storage savingsAccount = savers[i];
       if (msg.sender == savingsAccount.saver){
           storedTime = block.timestamp - savingsAccount.dateOfDeposit;
           payable(msg.sender).transfer(savingsAccount.savedAmount);
           savers[i] = savers[savers.length - 1];
           savers.pop();
       }
   }
   revert("User not found!");
}

function viewContractBalance() public view returns(uint){
   return address(this).balance;
}
}

嘿伙計們,我寫了一個簡單的儲蓄智能合約,它會支付你儲存資金的利息,我決定使用 ReentrancyGuard.sol 庫來保護它不被重入。但是由於某種原因,我收到程式碼無法訪問的錯誤。你能幫幫我嗎?

在此處輸入圖像描述

您可以忽略該警告,“無法訪問”程式碼實際上是“修改”函式的初始狀態

1.- 修改的withdraw函式的狀態是_NOT_ENTERED呼叫函式之前的狀態,因為該函式還沒有被呼叫

2.-一旦你呼叫函式withdraw,修改程式碼就會被執行

3.-在修飾符中,_;執行之前的所有內容,因此函式狀態設置為_ENTERED使其無法再次呼叫該函式,直到其執行完成(這就是可重入保護的作用)

//ReentrancyGuard contract by OpenZeppelin

modifier nonReentrant() {
   // On the first call to nonReentrant, _notEntered will be true
   require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

   // Any calls to nonReentrant after this point will fail
   _status = _ENTERED;

   _; // <--- everything before this is executed

   // By storing the original value once again, a refund is triggered (see
   // https://eips.ethereum.org/EIPS/eip-2200)
   _status = _NOT_ENTERED;
}

我通過這個問題和這篇中等文章激發了我的回答

引用自:https://ethereum.stackexchange.com/questions/138466