2

I am trying to understand about how mappings / struct arrays work compared to each other. I don't know currently how exactly the structs work but a little bit more about mappings. I am trying to make a set of user attributes for testing reasons.

struct User {
    uint age;
    string name;
    string email; // This is a platform based mail. Spam will not be possible.
}
User[] public users;

or

mapping(address => uint) Age;
mapping(address => string) Name;
mapping(address => string) Email;

What would be the difference and what is better/cheaper? Thank you for answers! :-)

2 Answers 2

3

It all comes down to the fact that you are using arrays to store these addresses and those arrays grow without bound and because you are always going to iterate through the full length of your arrays, you might end up having to spend a tremendous amount of gas just to look up some given address inside of your array.

In order to solve this issue, stop using arrays altogether inside of your contract and instead use a slightly different data structure.

The data structure that you should use for storing all these addresses, rather than being an array, it will be a mapping.

A mapping is a reference type that is available to us inside of Solidity. A mapping is like a collection of key/value pairs, so its similar to a JavaScript object, but there are some discrete and definite differences between a mapping and JavaScript object.

So, why is a mapping is going to solve your problem?

It all comes down to the search time for each of these data structures. In the Computer Science discipline, whenever we are trying to find some piece of data inside an array, the best case we can get for running that search is Linear Time. When we say that search inside of the array is linear time that means that for every additional record we add to this array, it will take a slightly larger amount of time to execute the search.

If we have 100 elements in the array, it might take 100 seconds. In other words, the size of the array dictates how long the search is going to take.

That is what is going to get you into trouble with gas prices if you go with arrays.

The big difference between an array and mapping is that doing a search inside of a mapping is what is called in Computer Science discipline, Constant Time.

When we say constant time, it means that no matter how many pieces of data we are storing inside this mapping, its always going to take the same amount of time. So if we have one address, it will take one second, but if we have a thousand addresses, it still only takes one second to iterate through these addresses.

Clearly, you definitely want to use mapping here.

0

First, I would question of storage of metadata, at all. Ethereum is not the ideal platform for storage of data that is not directly required for contract logic. Have a look here for a more detailed explanation: https://blog.b9lab.com/the-joy-of-minimalism-in-smart-contract-design-2303010c8b09

It is imperative that you avoid unbounded for loops. Have a look here: https://blog.b9lab.com/getting-loopy-with-solidity-1d51794622ad

mappings provide O(1) lookups given a key. Their main limitation is that the set keys can't be counted or enumerated. There are arguments in favor of completely discoverable data. In addition to a mapping containing instances of a struct, an array of keys can provide the best of both at the cost of additional storage.

mapping(address => UserStruct) public userStructs;
address[] public userAddresses;

There is certainly more than one way to organize storage. Have a look at some simple patterns over here:

Are there well-solved and simple storage patterns for Solidity?

Hope it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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