5

I'm trying to understand how mappings work. I've never seen anything like it before, but I'm sure many languages use something similar. Anyway, here's my code:

enter image description here

What am I doing wrong here?

Thank you!

5

The reason for you error is because in solidity you can only have declarations outside functions.

In you code, you declare the mapping and then in another operation you do an assignment which is only possible in a function.

For the other data types its possible also to do the assignment during initialization so it works.

Mappings can be thought of as Hash tables but it is different. In solidity a mapping is from start initialized with all possible keys and the associated value of the key is the default for the specified type. So in solidity you can only add new values to keys and you cannot add new keys since they are already there.

Also to mention that by default you cannot iterate over a mapping in Solidity. Again that is related to what I wrote earlier. Also you cannot retrieve only the keys for which you set up some values because you have all the keys set up by default with values.

  • So there is no way to sum over a mapping? If I want to know the sum I have to store it in an extra variable or use an array in the first place? – Andi Giga Oct 20 '16 at 14:32
  • Your first sentence is irrelevant. – Jossie Calderon Jun 12 '17 at 23:07
  • @AndiGiga @AndiGiga That is correct. Mappings just transform the key into a struct of type ValueType. – Jossie Calderon Jun 12 '17 at 23:15
  • @JossieCalderon why is my first sentence irrelevant? – dragosb Jun 13 '17 at 7:49
  • @dragosb The answer is because assignment is not allowed for declared variables outside of functions. Not because you can only have declarations outside of functions, although that's also true. – Jossie Calderon Jun 13 '17 at 7:52
5

Mappings are only marginally like hash tables, and are implemented totally unlike any other programming language. Typically a hash table would have an internal array that is 25-75% full of keys/values you have stored. And you can do things like iterate over them, as you're only skipping at most 75% empty cells in a non-trivial table. Ways Solidity mappings are different:

  • Instead of a small internal table (usually starting at size 16) to store key/value pairs, Solidity's mapping uses the entire 256-bit addressable memory space. So iterating is computationally infeasible.
  • Instead of pointing to a linked list of key/value pairs, Solidity mappings don't store the key at all, don't do any sort of collision detection, and don't store pointers to the values, instead stores the value directly. (This is why you can't get the key back out, and why you can't detect if the key has been set or not.)
  • Rather than using a fast/insecure mersenne prime based hash function, it uses SHA3, and doesn't map the sig back to a smaller set. (This is why it doesn't have to worry about collisions.)
  • They're true O(1) operations (from the script's POV), not O(1+e) like most other hash tables. There are no long-tail growth costs, as the table never expands, nor any O(n) collision chain walks.

So I'd recommend NOT thinking of them like hash tables. Instead think of them only as one-way functions that returns a pointer to a pseudo-random memory address.

  • 3
    I'd assumed they just used a perfect hash function. Is that not the case? – Richard Horrocks Jun 7 '17 at 16:06
  • 1
    @RichardHorrocks no. it uses SHA3, which is not a perfect hash function. collisions are possible in SHA3 (even if none have ever been demonstrated), whereas in a perfect hash function they are not. also, no hash function that shrinks the possible world space can be a perfect hash function. (which SHA3 does, shrinks it from infinity to 2^256.) – keredson Jun 7 '17 at 16:11
  • 2
    Aha - thanks for clearing up my misunderstanding :-) – Richard Horrocks Jun 7 '17 at 16:16
  • 1
    np. from a real-world perspective tho, you're functionally right. as no known collision in SHA3 exists, it's pretty darn close to a perfect hash function. thinking of it as such is not a bad heuristic. :) – keredson Jun 7 '17 at 16:25
4

To understand mappings, you can see them as Hash tables.

About your code, probably someone else can give you a complete explanation, but I think it's because you have to assign the value to the mapping inside a function, for example:

contract Complex{
    uint a = 1;
    uint b = 3;
    mapping(uint => uint) myMap;

    function Complex(){
        myMap[a] = b;
    }
}

This piece of code is doing the same thing but putting the myMap[a] = b; inside the constructor.

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.