So I was implementing a trading contract and need to keep a list of products on sale. I was using arrays but later switched to mappings.

So arrays implementation:

uint[] public productsOnSale;
uint public totalProductsOnSale; 
// array of product to its position
mapping(uint => uint) productToIndex;

while sale can be achieved using

uint public totalProductsOnSale;

mapping(uint => uint) indextoProduct;
mapping(uint => uint) productToIndex;

Since in case of arrays we keep track of values at any index, we can achieve that using mapping as well.

Are there any downsides of using mappings instead of an array? In terms of computation time or in terms of cost (gas)?


Array does cost more than mapping, but that's because it's not doing the same thing. An Array in Solidity is basically a struct with this structure

struct Array{
  mapping(uint => someType) items;
  uint length;

And if you want to use mapping, you have to store the length of mapping.

| improve this answer | |
  • So basically mappings implementation is better in terms of cost? – Prashant Prabhakar Singh Sep 25 '18 at 10:15
  • I would use array, because you have uint key and I think, it will be easier then mapping. productsOnSale.length; - you take length of your array. productsOnSale.push(value); - you add new element at the end of the array. In mapping if you will use existing key, you will overwrite it. – Tcс Sep 26 '18 at 18:04

Are there any downsides of using mappings instead of an array?

Yes, here is an aspect which you haven't considered in your question:

There is no way for you to keep track of all the keys that you have set in a mapping (other than scanning the entire blockchain of course).

You could emit an event for every insertion, which will make tracking easier, but that will obviously increase the cost.

You could store everything off-chain (e.g., on your server), but that will make your system vulnerable to off-chain weaknesses (e.g., somebody breaking into your server).

The easiest way to keep track of all keys set in a mapping, is by pushing those keys into an auxiliary array.

Or in your case, as you mentioned, just use an array instead of a mapping to begin with.

| improve this answer | |
  • I can keep track of all the keys of the mapping using indexToProduct mapping. Where each key is stored with respect to an index value. Something like item at an index. So I can iterate till totalProductsOnSale and fetch indexToProduct(i) to get list of all keys. – Prashant Prabhakar Singh Sep 25 '18 at 10:15

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