You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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时,每次提交的成绩都会被独立保存到对应地址的数组中
  • 通过自动生成的studentRecords getter(传入地址和索引),或自定义的getRecordByIndex函数,可查询单条历史成绩
  • 调用getRecordCount可查看指定地址的总成绩记录数

内容的提问来源于stack exchange,提问作者Asad Arslan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 05:02:34