Vyper Dynamic Arrays (Usage and Examples)

whiteboard crypto logo
Published by:
Whiteboard Crypto
on

Dynamic arrays in Vyper give you the power to manage data collections dynamically within a declared size limit. Let’s look at a few examples:

contributors: DynArray[address, 1000]

@external
def add_contributor(contributor: address):
    if len(contributors) < 1000:
        contributors.append(contributor)



gameScores: DynArray[int128, 3]

@external
def record_scores(score1: int128, score2: int128, score3: int128):
    gameScores = []
    gameScores.append(score1)
    gameScores.append(score2)
    gameScores.append(score3)



candidates: DynArray[address, 50]

@external
def clear_candidates():
    while len(candidates) > 0:
        candidates.pop()

Dynamic Arrays in Vyper present a flexible and secured way of dealing with collections of data in your smart contracts. Imagine having a storage container that can adjust its size as you keep on adding or removing stuff, but it also has a maximum limit beyond which it just can’t expand. This is precisely the concept behind Vyper’s Dynamic Arrays! Let’s delve deeper into how they work and why they are so useful, showcasing some practical and easy-to-understand examples related to blockchain scenarios.

Overview of Dynamic Arrays

Dynamic Arrays are arrays that can hold elements of a specified type, and can change their size during runtime, but within a certain boundary limit. You can define them using arrayName: DynArray[_type, _maxSize] format, where _type is the data type of the elements stored in the array and _maxSize is the maximum allowed size of the array.

Alongside, Vyper provides handy functions like append() to add new elements, pop() to remove elements, and indexes to access individual elements. However, be careful! If you attempt to add an item to a full array, extract an item from an empty array, or access an index beyond the current array length, you will face a runtime error.

Let’s understand better with some real-world examples.

Example 1: Keeping a Track of Crowdfunding Contributors

Assume you are developing a crowdfunding contract where people can contribute to a project. You can maintain a dynamic array of the addresses of contributors. However, to manage crowdfunds effectively, you can limit the maximum number of contributors.

# Define a dynamic array to store the addresses of contributors
contributors: DynArray[address, 1000]

@external
def add_contributor(contributor: address):
    # Check if we can add more contributors
    if len(contributors) < 1000:
        # Append the contributor address to the array
        contributors.append(contributor)

In the add_contributor function, a contributor’s address is added to the contributors array as long as the current number of contributors is less than 1000.

Example 2: Storing Different Levels of Game Scores

Consider a gaming contract where you store the top three scores of all completed games in a dynamic array.

# Define a dynamic array to store the top three game scores
gameScores: DynArray[int128, 3]

@external
def record_scores(score1: int128, score2: int128, score3: int128):
    # Clear the dynamic array to store new scores
    gameScores = []
    # Append the new game scores to the array
    gameScores.append(score1)
    gameScores.append(score2)
    gameScores.append(score3)

Here, the record_scores function resets the gameScores array and records the top three scores of a newly completed game.

Example 3: Safely Clearing Participating Addresses After Voting

Let’s continue with the contract for a voting system. After the vote, you might want to clear the list of candidates for the next round. Here is how you can do it:

# Define a dynamic array to store the addresses of the candidates
candidates: DynArray[address, 50]

@external
def clear_candidates():
    # Loop until the array is empty
    while len(candidates) > 0:
        # Pop addresses from the array
        candidates.pop()

In this clear_candidates function, we are safely popping out all the candidates’ addresses using a while loop until our candidates list is completely empty.

Good Habits and Things To Watch Out For

While dynamic arrays offer flexible and powerful storage, keep these guidelines in mind for effective usage:

  • Prevent Overflow: Always ensure your dynamic array has enough room before attempting to append new items.
  • Don’t Pop from Empty Arrays: Attempting to pop an item from an empty array will result in a runtime error. Always check if the array has items before trying to remove.
  • Access the Right Indices: Avoid accessing an index that doesn’t exist in your array. Confirm the index’s existence before referencing to avoid runtime exceptions.
  • Optimal Array Size: Choose the maximum array size wisely keeping in mind your specific application needs to avoid unnecessary memory allocation.

Remember that trying to access an unavailable index, popping an empty array, or appending to a full array will all cause a runtime failure (REVERT). Moreover, passing an array in calldata that is larger than the array bound will also result in a runtime REVERT.

Dynamic arrays, thus, provide you with an optimal solution for managing changing data sizes in your Ethereum smart contracts. Knowing how to accurately deal with them will boost your Vyper expertise and bring flexibility to your smart contracts. Happy coding with Vyper!

whiteboard crypto logo

WhiteboardCrypto is the #1 online resource for crypto education that explains topics of the cryptocurrency world using analogies, stories, and examples so that anyone can easily understand them. Growing to over 870,000 Youtube subscribers, the content has been shared around the world, played in public conferences and universities, and even in Congress.