0

I have a vyper contract:

favoriteNumber: uint256 # Stored at slot 0
someBool: bool # Stored at slot 1
myArray: uint256[1000] # Length stored at slot 2

The length of myArray would be stored at storage slot 2, but how do I calculate where the first element is stored?

3 Answers 3

0

The first element would be at storage slot 3.

Since vyper has static memory and storage allocation, it can deterministically allocate storage without dealing with collisions.

To get the storage layout, you can run:

vyper -f layout YouContract.vy 

To get the storage layout in json format.

If you had 2 arrays for example:

myArray: uint256[1000] # Length stored at slot 2
myArrayTwo: uint256[1000] # Length stored at slot 2 + 1000

The length of the second array would be stored at the slot 1000 after the previous array, since the previous array allocates all the storage right after itself for itself.

0

Bounds and overflow checking https://buildmedia.readthedocs.org/media/pdf/vyper/v0.1.0-beta.8/vyper.pdf

  myArray_slot = 2
 element_slot = keccak256(concat(myArray_slot,index + 1))
 sstore(element_slot, 42)

  my_array: bool[3][2] = [
  [True, False],
  [False, True],
  [True, True]

  element_value = my_contract.functions.get_array_element(0).call()
0

In this example, myArray is a Static array. This means that its length is not in the storage and that the first element of myArray is at storage slot 2.

Note that as all elements of the array are stored consecutively, myArray[i] is stored at slot 2 + i.


In the case of a Dynamic Array, things are different:

favoriteNumber: uint256
someBool: bool
myDynArray: DynArray[uint256, 2]
myStaticArray: uint256[3]

A Dynamic Array in Vyper represents a bounded array whose length can be modified at runtime, up to a bound b specified in the type (here b=2).

The bound, similarly to static arrays, is not stored in storage as it is known at compile time. The length, however, as it can be modified at runtime must be stored. It always occupies the first slot of the storage used by the array and is followed by b slots reserved for all the elements of the array.

In this second example, we would hence have the elements of myDynArray stored in slot 3 and 4.

Finally, here is a table of the storage slots of the above contract, such layout can be obtained using vyper -f layout foo.vy :

Slot Content
0 favoriteNumber
1 someBool
2 myDynArray's length
3 myDynArray[0]
4 myDynArray[1]
5 myStaticArray[0]
6 myStaticArray[1]
7 myStaticArray[2]

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.