如何在Solidity映射中保留用户成绩记录避免覆盖?
解决Solidity合约成绩记录被覆盖的问题
原合约中每个地址仅对应单条成绩记录,调用add_marks时会直接覆盖原有数据。要保留所有历史成绩,只需将映射的值类型改为成绩结构体数组,每次添加新成绩时往数组中追加即可。
修改后的合约代码
contract YourContract { struct StudentMarks { uint maths; uint science; // 可选:添加时间戳,便于区分不同批次的成绩 uint submitTime; } // 每个地址对应一组成绩记录数组 mapping(address => StudentMarks[]) public studentRecords; function addMarks(uint _maths, uint _science) public { // 将新成绩追加到对应地址的数组末尾,不会覆盖原有数据 studentRecords[msg.sender].push(StudentMarks({ maths: _maths, science: _science, submitTime: block.timestamp })); } // 可选:获取指定地址的成绩记录总数 function getRecordCount(address _student) public view returns(uint) { return studentRecords[_student].length; } // 可选:根据索引获取指定地址的单条成绩记录 function getRecordByIndex(address _student, uint _index) public view returns(uint, uint, uint) { require(_index < studentRecords[_student].length, "索引无效"); StudentMarks storage targetRecord = studentRecords[_student][_index]; return (targetRecord.maths, targetRecord.science, targetRecord.submitTime); } }
关键改动说明
- 映射类型调整:将
mapping(address => student_marks)改为mapping(address => StudentMarks[]),让每个地址关联一个成绩数组,而非单个成绩对象 - 添加逻辑优化:使用
push方法将新成绩追加到数组末尾,彻底避免覆盖原有数据 - 可选增强:新增时间戳字段和辅助查询函数,方便区分不同时间提交的成绩,同时提供更灵活的历史记录查询方式
使用说明
- 调用
addMarks时,每次提交的成绩都会被独立保存到对应地址的数组中 - 通过自动生成的
studentRecordsgetter(传入地址和索引),或自定义的getRecordByIndex函数,可查询单条历史成绩 - 调用
getRecordCount可查看指定地址的总成绩记录数
内容的提问来源于stack exchange,提问作者Asad Arslan
相关产品推荐
相关产品推荐

