如何与实体结构的映射映射进行交互?

How to interact with mapping of mappings for structs in solidity?

我创建了带有嵌套映射的结构。考虑以下以 solidity 形式编写在合约中的代码:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.4;

contract TestContract {
  struct Item {
    uint itemId;
    uint itemValue;
  }

  struct OverlayingItemStruct {
    mapping(uint => Item) items;
    uint overlayingId;
    uint itemsCount;
  }
  mapping(uint => OverlayingItemStruct) public overlayingItems;
  uint public overlayCount;

  function addOverlayingItemsStruct(uint _value) external {
    overlayCount ++;
    mapping(uint => Item) memory items;
    items[1] = Item(1, _value);
    overlayingItems[overlayCount] = OverlayingItemStruct(items, 1, 1);
  }

  function addItem(uint _value, uint _overlayId) external {
    OverlayingItemStruct storage overlay = overlayingItems[_overlayId];
    overlay.itemsCount ++;

    overlay.items[overlay.itemsCount] = Item(overlay.itemsCount, _value);
  }
}

编译上述代码时,出现错误:

TypeError: Uninitialized mapping. Mappings cannot be created dynamically, you have to assign them from a state variable.
  --> TestC.sol:21:5:
   |
21 |     mapping(uint => Item) memory items;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

不确定,如何处理这个错误。 其次,需要确认在嵌套映射字典中添加新值的方法是否正确?

不能在函数内部和 memory 状态下声明映射。这种类型只有 storage 状态。 也就是说,要将映射传递到结构中,您可以设置嵌套映射的键并在其中传递相关结构。 我试过这样调整你的智能合约:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

contract TestContract {

  struct Item {
    uint itemId;
    uint itemValue;
  }

  struct OverlayingItemStruct {
    mapping(uint => Item) items;
    uint overlayingId;
    uint itemsCount;
  }

  mapping(uint => OverlayingItemStruct) public overlayingItems;
  
  uint public overlayCount;

  function addOverlayingItemsStruct(uint _value) external {
    overlayCount ++;
    // NOTE: I declared a new Item struct
    Item memory item = Item(1, _value);
    // NOTE: I set into items mapping key value 1, Item struct created in row above this 
    overlayingItems[overlayCount].items[1] = item;
  }

  function addItem(uint _value, uint _overlayId) external {
    OverlayingItemStruct storage overlay = overlayingItems[_overlayId];
    overlay.itemsCount ++;
    overlay.items[overlay.itemsCount] = Item(overlay.itemsCount, _value);
  }
}