这是我的智能合约:
// 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 个帐户
错误发生在这一行:
if (userAccounts[owners[idx]].length >= 3) {
userAccounts
是一个以 address
作为键并返回 uint256
作为值的映射。所以本质上, userAccounts[owners[idx]]
是一个 uint256
- 而不是数组。而且你无法计算 uint256
数字的长度。
根据代码的上下文,您可能只想简单地比较映射的值:
if (userAccounts[owners[idx]] >= 3) {