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

Solidity同一mapping键覆盖旧值后如何从区块链上检索历史数据?

问题根因

你遇到的现象是Solidity mapping类型的固有特性导致的,和区块链数据不可篡改的特性并不冲突:

  • Solidity中的mapping(uint => eventStruct)是键值对存储结构,同一个键重复赋值会直接覆盖旧值。你两次调用loggingAccess都传入了相同的_nik = 10001,第二次调用会直接把dictConfirmAccess[10001]对应的结构体整体替换为新传入的值,因此你调用checkData查询的是合约当前的最新状态,自然只能拿到第二次写入的结果。

疑问逐一解答

1. 第一次写入的数据有没有被删除?

合约当前状态里的第一次写入数据是被覆盖了,没有保留在dictConfirmAccess这个状态变量里,但不等于数据被彻底删除。

2. 为什么区块链数据永久可查,却读不到第一次的写入结果?

区块链永久存储的是所有历史交易、区块数据以及事件日志,而你调用checkData读的是合约执行完所有历史交易后的最新状态快照,不是历史交易数据。第一次写入的所有信息都保存在你第一次调用loggingAccess的那笔链上交易里,只是没有体现在当前的合约状态中。

3. 怎么检索到第一次写入的数据?

分两种场景实现:

不修改现有合约的检索方式

找到你第一次调用loggingAccess的那笔交易哈希,解码交易的input字段,就能提取到第一次传入的所有参数(时间、事件名、event_id、data_nik),所有链上交易都是永久存证不可篡改的,不会丢失。

优化合约支持直接查询历史记录

如果后续需要长期查询同一个nik的所有写入历史,可以修改合约存储结构,两种常用方案:

  • 方案1:将mapping改为存储结构体数组
    把mapping(uint => eventStruct) public dictConfirmAccess;改成mapping(uint => eventStruct[]) public dictConfirmAccess;,每次调用loggingAccess时,往对应_nik的数组里push新的结构体,而不是直接赋值,后续就可以通过索引读取同一个nik下的所有历史记录。
  • 方案2:新增事件日志(更推荐)
    在合约中定义事件,每次写入数据时触发事件,链上的事件日志支持按索引过滤查询,比查交易更方便:
// 定义事件,nik加indexed支持后续过滤查询
event AccessLogged(uint indexed nik, string event_log_time, string event_name, string event_id, uint data_nik);

function loggingAccess(
    uint _nik, string memory _event_log_time,
    string memory _event_name, string memory _event_id,
    uint _data_nik
) public{
    dictConfirmAccess[_nik] = eventStruct(
      event_log_time : _event_log_time,
      event_name : _event_name,
      event_id : _event_id,
      data_nik : _data_nik
    );
    arrayOfData.push(_nik);
    // 触发事件
    emit AccessLogged(_nik, _event_log_time, _event_name, _event_id, _data_nik);
}

后续你只需要用nik = 10001作为过滤条件查询AccessLogged事件,就能拿到所有这个编号对应的历史写入记录。


补充说明你现有代码中arrayOfData的问题:目前你每次调用loggingAccess都会往这个数组里push一次_nik,所以你的数组现在已经存了两个10001,但这个数组只存了编号,没有对应存储当时写入的结构体数据,因此无法通过这个数组找回第一次的写入内容。

内容的提问来源于stack exchange,提问作者alvin Christianto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:06:03