11

I have something like this:

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

It can be accessed as m_Map[strCampaignName][addrRecipient], campaign can have multiple recipients...

Now at some point (ICO failed), I need to remove that campaign with all recipients. I don't think a simple delete m_Map[strCampaignName] will work. If I use m_Map[strCampaignName] = null, I think data will not be deleted. If I iterate through a list of all recipients, I will run out of gas.

How should this situation be handled? Min: I want m_Map[strCampaignName] to be empty, Max: I want to stop wasting memory on it.

Pang
  • 9,564
  • 146
  • 81
  • 122
Steve Brown
  • 369
  • 1
  • 3
  • 12

2 Answers2

3

As you stated, you can't delete a mapping in Solidity. The only way to "clear" the data is to iterate through the keys (using a separate array that stores the keys) and delete the individual elements. However, you're correct to be concerned about the cost...Depending on the size of the mapping, you could run into gas consumption issues.

A common approach to work around this is to use a struct in your mapping with a soft delete:

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

mapping(address => DataStruct) m_Map;

Now, deleting an entry just requires you to set the flag: m_Map[someAddr]._isDeleted = true;

Adam Kipnis
  • 10,175
  • 10
  • 35
  • 48
  • Will that work: m_Map[strCampaignName] = null ? Or m_Map[strCampaignName] = new mapping... – Steve Brown Jan 30 '18 at 19:39
  • My concern is size of this thing. A successful ICO can easily have 10,000+ addresses to manage -do I "pay" for carrying it all around? Is there a limit? – Steve Brown Jan 30 '18 at 20:19
  • 4
    There is no null in Solidity. Everything is created with a default zero value corresponding to the data type (0 for ints, 0x0 for addresses, false for bool, etc). Deleting an element is the same as setting the value to 0. There is a storage limit, but you won't reach it (2^256 slots with 32 bytes per slot). You pay for updating the data in storage, but mapping lookups are constant, so the overall size won't be an issue. – Adam Kipnis Jan 30 '18 at 22:13
  • Looking for an option to reset the whole mapping, like deleting the whole instance and assigning a fresh instance. Why is it so complicated? – Anupam Dec 30 '20 at 05:34
  • @AnupamKumar - because data from your contract is stored as a chain (hence "blockchain") and the current state is determined by taking the initial values and processing all of the updates in subsequent transactions. If you just want to wipe everything out, why not just deploy another contract? – Adam Kipnis Apr 08 '21 at 22:09
0

If you have all the addrRecipient of the mapping

delete m_Map[strCampaignName][addrRecipient];

works.

Melih
  • 453
  • 5
  • 9