1

In this question I asked why so much Tezos was burned when updating 380 cells in a grid.

It's surprising to see how many bytes it actually took though. If you look at the transaction, there were 380 grid cell updates, totaling 25460 bytes, meaning 67 bytes per individual grid cell. 67 bytes per cell is a TON given the size of a pair in this case is (max bound of 10 bytes) and the size of a bool (4 bytes) is a total of 14 bytes.

Where are the other 53 bytes coming from?

2
  • 1
    The number of bytes a pair uses depends on the values that it contains. Apr 16 at 19:40
  • For this particular case, the pair shouldn't exceed 10 bytes since that's the number of bytes for the Pair(99,99) and the pairs in this transactions are between (60,61) and (79,79) which are around 8 bytes each.
    – Jaime
    Apr 16 at 19:56
2

big_map is extremely expensive. It allows you to put as much data as you want in the contract, but you end up paying more in counterpart.

Check this example:

It produces 2 identical contacts, one uses a map and the other uses a big map.

import smartpy as sp

class MyContract(sp.Contract):
   def __init__(self, **kargs):
      self.init(**kargs)

   @sp.entry_point
   def entry_point_1(self, params):
      self.data.m[params.key] = params.value

@sp.add_test(name = "COST")
def test():
   scenario = sp.test_scenario()
   c1 = MyContract(m=sp.big_map({0: 1}))
   c2 = MyContract(m=sp.map({0: 1}))
   scenario += c1
   scenario += c2

Let's originate them: Each contract will have a row at origination key(0) => value(1).

  • Contract using (map)

       "consumed_gas": "1820",
       "consumed_milligas": "1819984",
       "storage_size": "91",
       "paid_storage_size_diff": "91"
    
  • Contract using (big_map)

       "consumed_gas": "2052",
       "consumed_milligas": "2051837",
       "storage_size": "184",
       "paid_storage_size_diff": "184",
    

Compare the difference. Having a big_map more than doubled the storage size.

Now let's call each contract and add a new row key(1) => value(2):

  • Calling the contract that uses a map

       "consumed_gas": "2717",
       "consumed_milligas": "2716487",
       "storage_size": "97",
       "paid_storage_size_diff": "6"
    
  • Calling the contract that uses a big_map

       "consumed_gas": "3000",
       "consumed_milligas": "2999452",
       "storage_size": "251",
       "paid_storage_size_diff": "67",
    

Look at the difference now, we paid 61 bytes extra for using the big_map. This value changes depending on the values being stored. The reason for the extra cost is because big_maps are stored differently from other types and produce big_map_diff when updated. All of this requires more storage space.

1
1

The main benefit of big_maps with respect to maps is that the gas costs of big_map operations don't depend on the number of elements stored in the big_map.

Regarding storage size, when you store a key-value mapping in a big_map, you store the value but not the key; instead you store the hash of the key. This hash always takes exactly 32 bytes.

The rest of the big_map storage difference comes from the organisztion of paths in the storage, I won't go into details because it is likely to change soon. What matters is that this overhead in constant.

So in term of storage, big_maps become more efficient than maps when the keys are large.

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.