Vyper Fixed-size Lists (Usage and Examples)

whiteboard crypto logo
Published by:
Whiteboard Crypto
on

Fixed-size lists in Vyper are data structures with a definite number of elements, enhancing data management in smart contracts. Here are some examples:

holders: address[3]

@external
def set_holders(_holders: address[3]):
   self.holders = _holders

@external
def get_holder(index: uint256) -> address:
   return self.holders[index]



signatories: address[3]

@external
def add_signatory(index: uint256, _signatory: address):
    self.signatories[index] = _signatory

@external
def get_signatory(index: uint256) -> address:
    return self.signatories[index]



bids: uint256[3][5]

@external
def submit_bid_to_round(new_bid: uint256, bid_index: uint256, round_index: uint256) -> bool:
   self.bids[bid_index][round_index] = new_bid
   return True

@external
def get_bid_from_round(bid_index: uint256, round_index: uint256) -> uint256:
   return self.bids[bid_index][round_index]

In Vyper, fixed-size lists are data structures designed to hold a specific number of elements of the same defined type. They’re crucial in creating organized and efficient smart contracts. Unlike dynamic arrays that allow resizing, fixed-size lists have a set number of elements, determined upon declaration. Essentially, these are boxes that contain a particular number of slots, and each slot can hold only a particular type of value.

Overview of Fixed-size Lists

The declaration of such a list is pretty straightforward – You mention the list’s name, the type of value each slot will hold, and most importantly, the number of slots that the list will have. The code outline for doing this looks as follows:

_name: _ValueType[_Integer]

Here, replace _name with the list’s name, _ValueType with the type of value the list’s slots will accommodate, and _Integer with the number of slots that the list should have.

Common Uses of Fixed-Size Lists

  1. Storing Contract Properties: If a contract has a known set of properties, you can use a fixed-size list to store them.
  2. Handling Multi-Dimensional Data: When your application requires multi-dimensional data storage (think matrices), fixed-size lists can make the task easier.
  3. Managing Multiple Instances: In scenarios where you need to handle multiple instances of a particular data type uniformly, fixed-size lists can make your job easier. For example, tracking scores for multiple students in a class or storing price data over a particular time period.

Keep in mind, that the utility of fixed-size lists is most evident when you are dealing with a known quantity of data. Making the best use of fixed-size lists can significantly increase the efficiency of your smart contracts.

Example 1: Storing Token Holders

In this example, a fixed-size list could store the addresses of token holders in a capped token distribution event.

# A fixed-sized list 'holders' to store addresses of 3 token holders
holders: address[3]

@external
def set_holders(_holders: address[3]):
   # Set the addresses of token holders
   self.holders = _holders

@external
def get_holder(index: uint256) -> address:
   # Retrieve the address of a specific token holder
   return self.holders[index]

In this contract, the set_holders function saves the addresses of the token holders to the holders list. The get_holder function then retrieves the address of a specified token holder using its index.

Example 2: Handling Multi-Signatures

Fixed-size lists can be used to hold addresses in a multi-signature wallet, where operations need approval from a majority of signatories.

# A fixed-sized list 'signatories' to store addresses of 3 signatories
signatories: address[3]

@external
def add_signatory(index: uint256, _signatory: address):
    # Add a new address to the signatories list
    self.signatories[index] = _signatory

@external
def get_signatory(index: uint256) -> address:
    # Retrieve the address of a specific signatory
    return self.signatories[index]

In this contract, the list signatories holds addresses for three signatories. The add_signatory function updates an address to the list at a given index, and the get_signatory function retrieves a signatory address from the list using its index.

Example 3: Round-Based Auction Bids

In a more complex auction contract, a multi-dimensional fixed-size list could track the top three bids for several consecutive auction rounds.

# A two-dimensional fixed-sized list 'bids' to store 
# amounts of top 3 bids for each of 5 auction rounds
bids: uint256[3][5]

@external
def submit_bid_to_round(new_bid: uint256, bid_index: uint256, round_index: uint256) -> bool:
   # Submit a new bid amount to a specific slot in a specific round
   self.bids[bid_index][round_index] = new_bid
   return True

@external
def get_bid_from_round(bid_index: uint256, round_index: uint256) -> uint256:
   # Retrieve the amount of a particular bid from a specific round
   return self.bids[bid_index][round_index]

In this contract, the bids list holds arrays of bids for five different auction rounds, with each round ranking up to three top bids. The submit_bid_to_round function allows the submission of a new bid amount to a specific position in a specific round. The get_bid_from_round function retrieves the amount of a specific bid at a particular rank from a specific auction round.

Best Practices and Possible Pitfalls

When working with fixed-size lists in Vyper, keep these practices in mind to avoid any pitfalls:

  • Initialization: Always initialize your fixed-size lists, because Vyper sets uninitialized storage to zeroes.
  • Index Out of Bounds: Accessing an index outside of the list’s size throws an “Index out of range” exception, a common error to avoid.
  • Memory Limitation: Overly large lists can consume excessive memory, leading to higher gas costs. Use just as much size as required.

As we conclude, it’s clear that fixed-size lists play a vital role in structuring data in Vyper and contribute significantly to creating efficient and organized smart contracts. By mastering them and applying the examples and best practices outlined here, you’ll be able to harness the full power of this feature in your journey with Vyper. Happy coding!

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.