Arrays
“如果您發送價值並且您發送的價值應該小於您目前的餘額,則應該支付呼叫的函式。”非傳遞函式的錯誤
這是我在這個堆棧交換網站上的第一篇文章,它是在我的頭撞到這個錯誤的牆上幾個小時之後發布的。
簡而言之,我目前正在學習穩固性課程,我正在從事的項目之一是具有不同角色的“共享錢包”概念(在我下面的範例中,管理員、家庭、批准的支出者)、津貼/角色和概念每個分配了至少 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 循環也是如此。