If you already have some experience as a developer, many of the terms and concepts you encounter when first diving into Solidity will hopefully be familiar to you, such as Solidity's Array type, which is very similar to arrays found in other programming languages:
string cars ;cars = ['volvo', 'ford', 'tesla', 'honda'];
However, Solidity also has a Mapping type, which may seem similar to an array at first since it is also used to store a group of data. You'll see it take a syntax such as this:
mapping (address => uint) highscores;
However, there are some key differences between
array in Solidity that are important to understand as you progress in your journey as a smart contract developer.
In this article, we'll be taking a look at both types and discussing their differences, and explaining (with examples) when to use one instead of the other.
To begin, let's take a quick look at the
array in Solidity is much like an array in any other programming language. For example, creating an array of fruit in Solidity might look like this:
string fruit;fruit = ["apple", "mango", "watermelon"];
You'll notice that array declarations require a value type, such as
uint, or even a
struct. This is because Solidity is a statically typed language.
Just like arrays in other languages, arrays in Solidity also have some methods available for reading and editing them:
string fruit;fruit = ["apple", "mango", "watermelon"];// let's add another fruit to the array...fruit.push("bacon");// updated array: ["apple", "mango", "watermelon", "bacon"]// wait! bacon isn't a fruit... let's get rid of that last entry real quick:fruit.pop();// updated array: ["apple", "mango", "watermelon"]
Pretty simple stuff right? I bet you're breezing right through 😎
Arrays: Fixed vs. Dynamic length
One final thing to mention about arrays before moving on is that an
array in Solidity can have either a fixed or dynamic length. In the example above, our array assumes a dynamic length
because no fixed length was declared. This means our array can be any of length and thus can be edited freely.
However, if we wanted our array to only ever have 3 fruits inside of it, we would give it a fixed length when we declared it, like so:
string fruit;fruit = ["apple", "mango", "watermelon"];// try to add another fruit to the array...fruit.push("pineapple");// ERROR: array "fruit" is of fixed length 3. You may not add another fruit!
Alright, so I think we've done a good job covering the basics of an
Now let's move on and discuss the
mapping is similar to an
array in that it is a Solidity reference type meant for storing a group of data.
However, its syntax and structure are quite different, in a way that allows it to serve a unique and important purpose.
For example, take this
mapping, which could be used to store the highscores of each player of a game:
mapping (address => uint) highscores;
Simply put, a
mapping is a table of keys and values (each with a pre-defined type).
You can think of the
mapping above as initiating an empty table that lives inside of your smart contract, and is waiting to be filled in with whatever data you want:
Now let's add some data to our highscores
mapping, and see what happens:
mapping (address => uint) highscores;address playerOne = "0xf39Fd6e51aad23F6F4cd6aB9927279cggFb91166";highscores[playerOne] = 750;
Let's check out our table visualization again:
Easy right? Now let's talk about why the
mapping type is so important, and what makes it different from an
Mapping: A Closer Look
mapping is created, it assumes that every possible key exists, and is mapped to some value. In
other words, unlike an
mapping does not have a retrievable length, or any real concept of a key or value being "set".
Don't worry - when we say that "every possible key exists", it doesn't mean that you have no control over your
or that it comes with a bunch of random key-value pairs already built into it. It just means that a
mapping is not
structured in the same way as an
array, and thus cannot be expected to behave like one.
For example, to fetch a value from your mapping, you must have that value's key. If we forgot what
playerOne's highscore was and wanted to fetch it, we would need to first know
address playerOne = "0xf39Fd6e51aad23F6F4cd6aB9927279cggFb91166"uint playerOneHighScore = highscores[playerOne];// playerOneHighScore = 750
If we did not have a player's address, then we would have no way of knowing their highscore, and in theory their highscore would be irretrievable to us forever.
Whereas with an
array, as a last-ditch effort we could at least loop through the array and print all of the highscores and see if any of them looked familiar. But you cannot loop through a mapping.
"So what's the point? Isn't a mapping just a crappy array then?"
No, not at all! Due to the way that a
mapping is structured, fetching a piece of data from a
mapping (if you have the data's key) is far more efficient than fetching the same data from an
array. To fetch data from an
requires iterating over the whole array until you find the element you're looking for, but a
mapping will run and grab that data right away (again, so long as you have the key).
mapping the ideal type for storing basic information about an address, for example, since often there is no need to store the address yourself because it is provided to you by whoever
is interacting with your smart contract (in the form of
And unfortunately in the world of Ethereum, the fact that transactions that edit data on the blockchain require gas fees means that storing/retrieving data from a smart contract as efficiently as possible can save you and your users lots of money in the long run.
Mapping: Default values
You might be wondering what a
mapping will return as a
default value for any key that hasn't had a value explicitly set for it yet.
For example, imagine if we searched for the highscore of
playerTwo, which was never added to the
mapping is storing its values as type
uint, the default value we would get back is
address playerTwo = "0x0Cca37CBaeE672d8429B148DF67cB3513422925c";uint playerTwoHighScore = highscores[playerTwo];// playerTwoHighScore = 0, because we never added a score for them inside the mapping!
This is because all types in Solidity have a default value if no value is assigned to them, and the
default value for
This is true for all types in general, not just for values inside of a
mapping. To quote the Solidity documentation:
If you're wondering, in Solidity the default value for each type is:
- fixed:0.0 (warning: not fully supported)
- enum: the first element of the enum
- array: a dynamically-sized 
- mapping: an empty mapping
- struct: a struct where all members are set to default values
- function: if internal, an empty function. If external, a function that throws an error when called.
Mapping vs. Array: When to use one over the other
If you need to be able to iterate over your group of data (such as with a
for loop), then use an
If you don't need to be able to iterate over your data, and will be able to fetch values based on a known key, then use a
However, sometimes it is optimal to use both. Since iterating over an
array can be an expensive action in Solidity (compared to fetching data from a
mapping), and since
you may want to be able to store both a value and its key within your smart contract, developers sometimes opt to create an
array of keys, which serve as a reference
to even more data that can then be retrieved from its associated value inside of a
Keep in mind that you should never allow an
array in Solidity to grow too large, since in theory iterating over a big enough array could end up costing more in gas fees than the value of the transaction is worth (another reason to consider using
mapping when possible).
To learn more about Solidity and its types, I recommend starting with the Solidity documentation.
If you are brand new to Solidity and are looking for more resources to get started, I couldn't recommend these resources enough:
- the legendary CryptoZombies course
- Nader Dabit's Complete Guide to Full Stack Ethereum Development
- the Hardhat Beginner Tutorial
- the Ethers.js Documentation
- consider joining the awesome Developer DAO community
- and one more time: the Solidity Documentation
If you liked this post, consider following me on twitter and/or subscribing to the blog using the form below.