Solidity智能合约报错:uint256不存在length成员问题求助
问题定位与解决方法
核心错误定位
报错的直接原因是**userAccounts的类型定义错误**:
你当前定义的userAccounts是mapping(address => uint),这意味着每个地址对应一个单一的uint值,而uint类型并没有length属性,代码中userAccounts[owners[idx]].length >= 3这一行试图访问uint的length,自然触发错误。
同时,你原本的意图是让userAccounts存储每个用户拥有的所有账户ID数组,所以类型应该定义为mapping(address => uint[])(地址到uint数组的映射)。
具体修复步骤
1. 修正userAccounts的类型
将合约中的:
mapping(address => uint) userAccounts; // store the accounts that the users own
修改为:
mapping(address => uint[]) userAccounts; // store the accounts that the users own
2. 修复WithdrawRequest结构体的amount类型错误
结构体中amount被错误定义为address类型,应该改为uint:
struct WithdrawRequest { address user; // who request the withdraw uint amount; // 原先是address,改为uint uint approvals; // check to determine if the withdraw is approved mapping(address => bool) ownerApproved; bool approved; }
3. 修复getApprovals函数的返回值缺失
该函数没有返回语句,补充return:
function getApprovals(uint accountId, uint withdrawId) public view returns (uint) { return accounts[accountId].withdrawRequests[withdrawId].approvals; }
4. 验证createAccount函数的逻辑正确性
修正userAccounts类型后,userAccounts[owners[idx]].push(id)的操作就合法了,因为现在每个地址对应的是数组,可以执行push添加账户ID。
修复后的关键代码片段
// 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 amount, uint timestamp ); event Withdraw(uint indexed withdrawId, uint timestamp); event AccountCreated(address[] owners, uint indexed id, uint timestamp); struct WithdrawRequest { address user; uint amount; // 修正类型 uint approvals; mapping(address => bool) ownerApproved; bool approved; } struct Account { address[] owners; uint balance; mapping(uint => WithdrawRequest) withdrawRequests; } mapping(uint => Account) accounts; mapping(address => uint[]) userAccounts; // 修正为数组映射 uint nextAccountId; uint nextWithdrawId; // 其余modifier和函数保持不变,仅上述三处修改 function getApprovals(uint accountId, uint withdrawId) public view returns (uint) { return accounts[accountId].withdrawRequests[withdrawId].approvals; // 补充返回 } }
内容的提问来源于stack exchange,提问作者Mohamed
相关产品推荐
相关产品推荐

