Arrays

“如果您發送價值並且您發送的價值應該小於您目前的餘額,則應該支付呼叫的函式。”非傳遞函式的錯誤

  • April 26, 2022

這是我在這個堆棧交換網站上的第一篇文章,它是在我的頭撞到這個錯誤的牆上幾個小時之後發布的。

簡而言之,我目前正在學習穩固性課程,我正在從事的項目之一是具有不同角色的“共享錢包”概念(在我下面的範例中,管理員、家庭、批准的支出者)、津貼/角色和概念每個分配了至少 1 個角色(即成員)的地址的“剩餘餘額”。

我面臨的並且我無法理解的問題是為什麼我會收到此錯誤*“注意:如果您發送價值並且您發送的價值應該小於您目前的餘額,則應該支付被呼叫的函式。”* 執行*“SetAllowance”*功能時? 我無法理解的是,為什麼在執行不包含任何類似方法(即傳輸、呼叫、發送)的函式時返回的錯誤中呼叫了“應付”的概念?!

我的程式碼如下:

//Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721)
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/AccessControl.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol";


contract SharedWallet is Ownable, AccessControl {
using SafeMath for uint256;

event BalanceReceived (address indexed _from, uint256 _amount);
event AmountSpent (address indexed _by, address indexed _to, uint256 _amount);

bytes32 public constant FAMILY_ROLE = keccak256("FAMILY");
bytes32 public constant ApprovedSpender_ROLE = keccak256("ApprovedSpender");

mapping(bytes32 => uint256) public allowance;
mapping(address => uint256) public remainingBalance;

address payable[] internal AllFamilyAcc;
address payable[] internal AllAppSpendersAcc;

constructor () public {
   _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
   allowance[FAMILY_ROLE] = 1 ether;
   allowance[ApprovedSpender_ROLE] = 2 ether;
}

modifier onlyAdmin() {
   require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender));
   _;
}
modifier OnlyMembers() {
   require(hasRole(ApprovedSpender_ROLE, msg.sender) || hasRole(FAMILY_ROLE, msg.sender) || hasRole(DEFAULT_ADMIN_ROLE, msg.sender));
   _;
}

function SetAllowance(uint256 _FamilyAmount, uint256 _AppSpenderAmount)
   public payable
   {
   for (uint i=0; i<=AllFamilyAcc.length; i++) {        
         remainingBalance[AllFamilyAcc[i]] += _FamilyAmount;
     }

   
   for (uint i=0; i<=AllAppSpendersAcc.length; i++) { 
         remainingBalance[AllAppSpendersAcc[i]] += _AppSpenderAmount;
     }
   }

function addFamilyMember(address payable _account)
   public virtual
   {
       require(!hasRole(FAMILY_ROLE, _account),"Already a family member!");
       grantRole(FAMILY_ROLE, _account);
       remainingBalance[_account] = allowance[FAMILY_ROLE];
       AllFamilyAcc.push(payable(_account));
   }

function addApprovedSpender(address payable _account)
   public virtual
   {
       require(!hasRole(ApprovedSpender_ROLE, _account),"Already an approved spender!");
       grantRole(ApprovedSpender_ROLE, _account);
       remainingBalance[_account]=allowance[ApprovedSpender_ROLE];
       AllAppSpendersAcc.push(payable(_account));
   }
}

提前致謝!

我認為它必須是支付的,因為它AllAppSpendersAcc[i]是類型address payable,並且由於您使用的是 payble 地址,因此編譯器假定此函式將轉移 Ether。您可以將應付地址儲存為address,當您需要支付它們時,您可以像這樣轉換它們:

   address adr = 0x.........;
   payable(adr).transfer(...);

您必須在函式中更改這些for條件SetAllowance()

for (uint i=0; i <= AllFamilyAcc.length; i++){
 ...
}

for (uint i=0; i <= AllAppSpendersAcc.length; i++) {
 ...
}

這樣:

function SetAllowance(uint256 _FamilyAmount, uint256 _AppSpenderAmount) public payable {
       for (uint i=0; i < AllFamilyAcc.length; i++) {
           remainingBalance[AllFamilyAcc[i]] += _FamilyAmount;
       }

       for (uint i=0; i < AllAppSpendersAcc.length; i++) {
           remainingBalance[AllAppSpendersAcc[i]] += _AppSpenderAmount;
       }
   }

這是因為,如果 AllFamilyAcc 長度為 3 項(地址 0、地址 1、地址 2),在這種情況下i <= AllFamilyAcc.length,您將迭代直到 i=3,但在您的數組中不存在索引 3 處的元素,然後編譯器會給您此錯誤。當您在 中更改此條件時i < AllFamilyAcc.length,最後一次迭代將是 2 並且(在此範例中)索引 = 2 處的最後一個值是地址 2。AllAppSpendersAcc 循環也是如此。

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