4

I've been attempting to implement a function to combine two mappings into a single one:

contract Mappulator {
    mapping(address => int256) public BigMap;
    struct mapper { mapping (address => int256) map;}

    function MappingCombiner(mapper map1, mapper map2){ 
        BigMap = map1.map + map2.map;
    }
} 

According to this I must wrap the mappings in structs to be able to pass them to a function. With the above code I get the following error:

Internal type is not allowed for public or external functions.
function MappingCombiner(mapper map1, mapper map2){ 
                         ^---------^

If I add the storage keyword, as suggested here, I get:

Location has to be memory for publicly visible functions (remove the "storage" keyword).    
function MappingCombiner(mapper storage map1, mapper storage map2){ 
                         ^-----------------^

The compiler is not getting as far as BigMap = map1.map + map2.map; for me to assess if that is valid. I'm assuming not because, to combine them, both maps would have to be iterated over, which is not straight-forward. Also, it doesn't look like any operator is defined to do this.

Where am I going wrong here? Would I be better off defining/converting to arrays?

Can any provide/point to a working example of mappings being passed to a funtion and combined?

  • 1
    You can't iterate over maps. The correct way to implement this is just to create a function that checks both maps and returns the non-zero result. Why do you want to combine the mappings anyway? Would some other data structure make more sense here? – Tjaden Hess Dec 4 '16 at 7:34
  • @TjadenHess Thanks, but how would I check for non-zero results without iterating? It would be convenient. I have got around it by creating a struct an array of mappings and an array of all the keys in both.. – atomh33ls Dec 4 '16 at 12:07
  • I really can't help more unless I know some context. I can just tell you that in general, iterating over potentially large data structures in Ethereum is dangerous. It's much better to update state incrementally and only when required – Tjaden Hess Dec 4 '16 at 14:55
  • 1
    You cannot combine mappings, as they can grow to such a large size that the copy operation would exceed the block's gas limit or become a DoS vector. ethereum.stackexchange.com/a/24519/3573 – paulhauner Aug 17 '17 at 3:47
3

the problem is not about storage or memory but about using a struct as a parameter. to avoid the first problem declare your function internal :

 function MappingCombiner(mapper  map1, mapper map2) internal{ 
     }

for the mapping assignation I don't know what do you try to do, your operation is erroneous. the operator + is for LValue (i.e. a variable or something that can be assigned to)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.