在 uint256 中进行依赖于参数的查找后,未找到或不可见成员“长度”

问题描述 投票:0回答:1

这是我的智能合约:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;

contract BankAccount {
    event Deposit(
        address indexed user,
        uint indexed accountId,
        uint value,
        uint timestamp
    );
    event WithdrawRequested(
        address indexed user,
        uint indexed accountId,
        uint indexed withdrawId,
        uint amout,
        uint timestamp
    );
    event Withdraw(uint indexed withdrawId, uint timestamp);
    event AccountCreated(address[] owners, uint indexed id, uint timestamp);

    struct WithdrawRequest {
        address user; // who request the withdraw
        address amount;
        uint approvals; // check to determine if the the withdraw is approved
        mapping(address => bool) ownerApproved;
        bool approved;
    }

    struct Account {
        address[] owners;
        uint balance;
        mapping(uint => WithdrawRequest) withdrawRequests; // uint is going to be the id of the withdraw request
    }

    
    mapping(uint => Account) accounts;
    mapping(address => uint) userAccounts; // store the accounts that the users own

    uint nextAccountId; // every time we create an account we increment the id
    uint nextWithdrawId; // every time we request a withdraw we increment the id

    modifier accountOwnership(uint accountId) {

        bool isOwner;
        for (uint idx; idx < accounts[accountId].owners.length; idx++) {
            if (accounts[accountId].owners[idx] == msg.sender) {
            isOwner = true;
            break;
            }
        }
        require(isOwner, "You are not the Owner");
        _;
    }

    function deposit(uint accountId) external payable accountOwnership(accountId) {

        accounts[accountId].balance += msg.value;
    }
    

    modifier validOwner(address[] calldata owners) {
        require(owners.length <= 4, "Max is 4 owners per account");

        for (uint i ; i < owners.length ; i++) {
            for (uint j = i + 1 ; j < owners.length; j++) {
                if (owners[i] == owners[j]) {
                    revert("No Duplicate Owners");
                }
            }
        }
        
        _;
    }
    
    function createAccount(address[] calldata otherOwners) external  validOwner(otherOwners){
        address[] memory owners = new address[](otherOwners.length + 1);
        owners[otherOwners.length] = msg.sender;

        uint id = nextAccountId;

        // this for loop just check if each user had max 3 account 
        // if not the are allowed to create one, if yes we will revert the operation
        for (uint idx ; idx < owners.length; idx++) {
            if (idx < owners.length - 1) {
                owners[idx] = otherOwners[idx];
            }

            if (userAccounts[owners[idx]].length >= 3) {
                revert("Each User has 3 account max");
            }
            userAccounts[owners[idx]].push(id);
        }
        accounts[id].owners = owners;
        nextAccountId++;
        emit AccountCreated(owners, id, block.timestamp);
    }

    modifier sufficientBalance(uint accountId, uint amount) {
        require(accounts[accountId].balance >= amount, "Not enough Balance");
        _;
    }

    function requestWithdraw(uint accountId, uint amount) external accountOwnership(accountId) sufficientBalance(accountId, amount){
        uint id = nextWithdrawId;
        WithdrawRequest storage request = accounts[accountId].withdrawRequests[id];
        request.user = msg.sender;
        request.amount = amount;
        nextWithdrawId++;
        emit WithdrawRequested(msg.sender, accountId, id, amount, block.timestamp);
    }

    modifier canApprove(uint accountId, uint withdrawId) {
        require(!accounts[accountId].withdrawRequests[withdrawId].approved, "This is already approved");
        require(accounts[accountId].withdrawRequests[withdrawId].user != msg.sender, "You are the user , can't approved");
        require(accounts[accountId].withdrawRequests[withdrawId].user != address(0), "this request doesn't exist");
        require(!accounts[accountId].withdrawRequests[withdrawId].ownerApproved[msg.sender], "you are already aproved");
        _;
    }

    function approveWithdraw(uint accountId, uint withdrawId) external accountOwnership(accountId) canApprove(accountId, withdrawId) {
        WithdrawRequest storage request = accounts[accountId].withdrawRequests[withdrawId];
        request.approvals++;
        request.ownerApproved[msg.sender] = true;

        if (request.approvals == accounts[accountId].owners.length - 1) {
            request.approved = true;
        }
    }


    modifier withdrawOwnership(uint accountId, uint withdrawId) {
        require(accounts[accountId].withdrawRequests[withdrawId].user ==msg.sender, "You are not the owner of the request");
        require(accounts[accountId].withdrawRequests[withdrawId].approved, "This request is not aproved");
        _;
    }


    function withdraw(uint accountId, uint withdrawId) external withdrawOwnership(accountId, withdrawId) {
        uint amount = accounts[accountId].withdrawRequests[withdrawId].amount;
        require(accounts[accountId].balance >= amount, "not enough money");

        accounts[accountId].balance -= amount;
        delete accounts[accountId].withdrawRequests[withdrawId];
        (bool sent, ) = payable(msg.sender).call{value : amount}("");
        require(sent);

        emit Withdraw(withdrawId, block.timestamp);
    }

    function getBalance(uint accountId) public view returns(uint) {
        return accounts[accountId].balance;
    }

    function getOwners(uint accountId) public view returns(address[] memory) {
        return accounts[accountId].owners;
    }

    function getApprovals(uint accountId, uint withdrawId) public view returns (uint) {
        accounts[accountId].withdrawRequests[withdrawId].approvals;
    }


    function getAccounts() public view returns(uint[] memory) {
        return userAccounts[msg.sender];
    }
}

当我测试它时,它向我显示此错误:

在 uint256 中进行参数相关查找后,未找到或不可见成员“长度”。

检查用户是否已有 3 个帐户

blockchain solidity smartcontracts datacontract hardhat
1个回答
0
投票

错误发生在这一行:

if (userAccounts[owners[idx]].length >= 3) {

userAccounts
是一个以
address
作为键并返回
uint256
作为值的映射。所以本质上,
userAccounts[owners[idx]]
是一个
uint256
- 而不是数组。而且你无法计算
uint256
数字的长度。


根据代码的上下文,您可能只想简单地比较映射的值:

if (userAccounts[owners[idx]] >= 3) {
© www.soinside.com 2019 - 2024. All rights reserved.