【问题标题】:Deleting mapping from mapping in Solidity从 Solidity 中的映射中删除映射
【发布时间】:2018-07-08 23:55:36
【问题描述】:

我有这样的事情:

mapping (address => mapping(string => uint)) m_Map;

它可以作为 m_Map[strCampaignName][addrRecipient],活动可以有多个收件人...

现在某个时候(ICO 失败),我需要删除所有收件人的活动。我觉得不简单 delete m_Map[strCampaignName] 将起作用。 如果我使用 m_Map[strCampaignName] = null,我认为数据不会被删除。 如果我遍历所有收件人的列表,我会用完gas。

这种情况应该如何处理? Min:我希望 m_Map[strCampaignName] 为空, Max:我不想再浪费内存了。

【问题讨论】:

    标签: ethereum solidity


    【解决方案1】:

    正如您所说,您无法在 Solidity 中删除 mapping。 “清除”数据的唯一方法是遍历键(使用存储键的单独数组)并删除单个元素。但是,您担心成本是正确的...根据映射的大小,您可能会遇到气体消耗问题。

    解决此问题的常用方法是在映射中使用 struct 并进行软删除:

    struct DataStruct {
      mapping(string => uint) _data;
      bool _isDeleted;
    }
    
    mapping(address => DataStruct) m_Map;
    

    现在,删除条目只需要设置标志:m_Map[someAddr]._isDeleted = true;

    【讨论】:

    • 这会起作用吗:m_Map[strCampaignName] = null 吗?或者 m_Map[strCampaignName] = 新映射...
    • 我关心的是这个东西的大小。一个成功的 ICO 可以很容易地管理 10,000 多个地址——我是否“付钱”携带它?有限制吗?
    • Solidity 中没有 null。一切都是使用与数据类型相对应的默认零值创建的(0 表示整数,0x0 表示地址,false 表示布尔等)。删除元素与将值设置为 0 相同。存在存储限制,但您不会达到它(2^256 个插槽,每个插槽 32 个字节)。您需要为更新存储中的数据付费,但映射查找是不变的,因此整体大小不会成为问题。
    • 寻找重置整个映射的选项,例如删除整个实例并分配一个新实例。为什么这么复杂?
    • @AnupamKumar - 因为来自您的合约的数据存储为链(因此是“区块链”),当前状态是通过获取初始值并处理后续交易中的所有更新来确定的。如果您只想清除所有内容,为什么不部署另一个合约?
    【解决方案2】:

    如果你有所有addrRecipient的映射

    delete m_Map[strCampaignName][addrRecipient];
    

    有效。

    【讨论】:

      猜你喜欢
      • 2019-02-26
      • 1970-01-01
      • 2012-04-19
      • 1970-01-01
      • 2016-01-29
      • 2021-12-30
      • 2018-07-31
      • 2019-01-05
      • 2021-04-28
      相关资源
      最近更新 更多