Vyper Data Types (Series 2)
Previously, we explored why Vyper is a game changer, as it is one of the fastest-growing languages for smart contract development. We also explored some of the basics, such as Pragma and Constructor. You can read it here. Today, we are delving deep into data types and how they work. What are Data types? Data types help us organize different information in our code, just like how we sort items at home into specific places. These types are set before the program runs. Just like a container designed for liquids won't work well for storing solid objects, each variable in Vyper can only store the kind of data it was designed for. When we write code, we need to specify what data type each variable will hold—whether it's a number for calculations, text for names, or true/false for simple decisions. These types ensure that our program handles information correctly, preventing mix-ups like trying to multiply someone's name or add letters together. Understanding Data Types in Vyper Boolean - The Simple True/False Think of booleans as light switches—they can only be in two states: True or False. We use them in our code to make yes-or-no decisions. is_active: bool = True is_paused: bool = False # You can flip boolean values is_active = not is_active # Now it's False Certain operators can work effectively with Booleans, which include not, or == and !=. This means we can use them to prove Truth to False. Operator Description not x Logical negation x and y Logical conjunction x or y Logical disjunction x == y Equality x != y Inequality Think of these operators as ways to make decisions in your code: not x - This flips a true/false value to its opposite is_door_locked = True is_door_unlocked = not is_door_locked # Result: False It's like saying "the opposite of" - if the door is locked, then not locked means unlocked. x and y - Both conditions must be true has_ticket = True has_id = True can_board_plane = has_ticket and has_id # Result: True Just like you need both a ticket and ID to board a plane, both values must be true for the result to be true. x or y - At least one condition must be true. has_cash = False has_credit_card = True can_pay = has_cash or has_credit_card # Result: True For example, when paying for something, you can use cash OR a card; you need one to be true. x == y - Checks if two values are the same password = "secret123" entry = "secret123" is_correct = password == entry # Result: True It's like checking if two keys are identical. x != y - Checks if two values are different expected_price = 100 actual_price = 90 price_changed = expected_price != actual_price # Result: True It's like checking if something is different, like noticing the price has changed from what you expected. These operators help you make logical boolean decisions. Numbers - Integers and Their Varieties When working with numbers in smart contracts, Vyper provides two fundamental ways to handle whole numbers: signed and unsigned integers. Each serves a specific purpose, and understanding their differences is crucial for writing efficient and secure code. Signed Integers Signed integers are perhaps the most versatile number type in Vyper, capable of expressing both positive and negative values. Imagine a bank account - you can have both deposits (positive) and withdrawals (negative). This is where signed integers shine. When you declare a variable like age: int8 = -5, you're telling Vyper to reserve 8 bits of space that can hold any number from -128 to 127. #signed integers (can be positive or negative) age: int8 = -5 # Stores from -128 to 127 balance: int256 = 1000 # Larger range for bigger numbers For larger values, Vyper offers increased storage capacity. The int256 type, commonly used for substantial numerical operations, can handle much more significant numbers. Consider tracking a company's profit and loss: balance: int256 = 1000. This could represent significant financial movements in either direction. Unsigned Integers Some values in the real world can never be negative. You can't have -3 apples or -5 users. This is where unsigned integers come into play. A declaration like quantity: uint8 = 255 is perfect for inventory systems or user counts. The uint8 type efficiently uses 8 bits to store values from 0 to 255, making it ideal for small positive numbers. # Unsigned integers (only positive) quantity: uint8 = 255 # Stores from 0 to 255 price: uint256 = 1000 # Popular for storing large positive numbers The most commonly used unsigned integer in Vyper is uint256. When you write price: uint256 = 1000, you create a variable that can hold massive positive numbers, perfect for token amounts or wei values in Ethereum transactions. Decimal Numbers When you need precise calculations with decimal points price: decimal = 19.99 # Good for financial calculations tax_rate: decimal = 0.15 A
Previously, we explored why Vyper is a game changer, as it is one of the fastest-growing languages for smart contract development.
We also explored some of the basics, such as Pragma and Constructor. You can read it here.
Today, we are delving deep into data types and how they work.
What are Data types?
Data types help us organize different information in our code, just like how we sort items at home into specific places.
These types are set before the program runs. Just like a container designed for liquids won't work well for storing solid objects, each variable in Vyper can only store the kind of data it was designed for.
When we write code, we need to specify what data type each variable will hold—whether it's a number for calculations, text for names, or true/false for simple decisions. These types ensure that our program handles information correctly, preventing mix-ups like trying to multiply someone's name or add letters together.
Understanding Data Types in Vyper
- Boolean - The Simple True/False
Think of booleans as light switches—they can only be in two states: True or False. We use them in our code to make yes-or-no decisions.
is_active: bool = True
is_paused: bool = False
# You can flip boolean values
is_active = not is_active # Now it's False
Certain operators can work effectively with Booleans, which include not
, or
==
and !=. This
means we can use them to prove Truth to False.
Operator | Description |
---|---|
not x | Logical negation |
x and y | Logical conjunction |
x or y | Logical disjunction |
x == y | Equality |
x != y | Inequality |
Think of these operators as ways to make decisions in your code:
-
not x
- This flips a true/false value to its oppositeis_door_locked = True
is_door_unlocked = not is_door_locked # Result: False
It's like saying "the opposite of" - if the door is locked, then not locked means unlocked.
-
x and y
- Both conditions must be truehas_ticket = True
has_id = True
can_board_plane = has_ticket and has_id # Result: True
Just like you need both a ticket and ID to board a plane, both values must be true for the result to be true.
-
x or y
- At least one condition must be true.has_cash = False
has_credit_card = True
can_pay = has_cash or has_credit_card # Result: True
For example, when paying for something, you can use cash OR a card; you need one to be true.
-
x == y
- Checks if two values are the samepassword = "secret123"
entry = "secret123"
is_correct = password == entry # Result: True
It's like checking if two keys are identical.
-
x != y
- Checks if two values are differentexpected_price = 100
actual_price = 90
price_changed = expected_price != actual_price # Result: True
It's like checking if something is different, like noticing the price has changed from what you expected. These operators help you make logical boolean decisions.
Numbers - Integers and Their Varieties
When working with numbers in smart contracts, Vyper provides two fundamental ways to handle whole numbers: signed and unsigned integers. Each serves a specific purpose, and understanding their differences is crucial for writing efficient and secure code.
- Signed Integers
Signed integers are perhaps the most versatile number type in Vyper, capable of expressing both positive and negative values. Imagine a bank account - you can have both deposits (positive) and withdrawals (negative). This is where signed integers shine. When you declare a variable like age: int8 = -5
, you're telling Vyper to reserve 8 bits of space that can hold any number from -128 to 127.
#signed integers (can be positive or negative)
age: int8 = -5 # Stores from -128 to 127
balance: int256 = 1000 # Larger range for bigger numbers
For larger values, Vyper offers increased storage capacity. The int256
type, commonly used for substantial numerical operations, can handle much more significant numbers. Consider tracking a company's profit and loss: balance: int256 = 1000
. This could represent significant financial movements in either direction.
- Unsigned Integers
Some values in the real world can never be negative. You can't have -3 apples or -5 users. This is where unsigned integers come into play. A declaration like quantity: uint8 = 255
is perfect for inventory systems or user counts.
The uint8 type efficiently uses 8 bits to store values from 0 to 255, making it ideal for small positive numbers.
# Unsigned integers (only positive)
quantity: uint8 = 255 # Stores from 0 to 255
price: uint256 = 1000 # Popular for storing large positive numbers
The most commonly used unsigned integer in Vyper is uint256. When you write price: uint256 = 1000
, you create a variable that can hold massive positive numbers, perfect for token amounts or wei values in Ethereum transactions.
- Decimal Numbers
When you need precise calculations with decimal points
price: decimal = 19.99 # Good for financial calculations
tax_rate: decimal = 0.15
- Address - For Ethereum Accounts
We use addresses daily to identify places - your home, a store, or a friend's house. In the Ethereum world, addresses work similarly, but instead of pointing to physical locations, they point to digital wallets and smart contracts. Let's explore what makes these addresses unique and how they work in Vyper.
What is an Ethereum Address?
owner: address = 0x123... # Stores wallet addresses
contract: address = 0xABC...
Think of an Ethereum address as a unique digital mailbox. Just like your home address ensures mail reaches you and only you, an Ethereum address ensures that cryptocurrency and digital assets reach their intended destination. In Vyper, we handle these addresses using a special type called address
.
When you write something like:
owner: address = 0x71C7656EC7ab88b098defB751B7401B5f6d8976F
You're creating a variable that can only store valid Ethereum addresses. These addresses always start with "0x" and are followed by 40 characters made up of numbers (0-9) and letters (a-f).
Real World Examples
Let's say you're building a simple digital wallet contract. You might store addresses like this:
# The wallet's owner
owner: address = 0x71C7656EC7ab88b098defB751B7401B5f6d8976F
# A trusted backup address
backup_wallet: address = 0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199
Working with Addresses
Addresses in Vyper come with special properties. You can check things like:
- How much Ether does an address hold
- Whether an address belongs to a smart contract
- The code is stored at a contract address
For example, checking an address's balance is as simple as:
wallet_balance: uint256 = owner.balance
Addresses help us navigate the blockchain, ensuring our digital assets and interactions reach their intended destinations safely and securely.
- Byte Arrays - For Raw Data
In Vyper, byte arrays are used to handle raw binary data. Think of them as containers for storing information that computers can directly process. Byte arrays are especially useful when working with files, cryptographic hashes, or binary operations.
# Fixed size (exactly 32 bytes)
file_hash: bytes32 = 0x1234...
Static Byte Arrays
A static byte array has a fixed size that cannot be changed. This makes it straightforward and efficient.
Example: Storing a Fixed-Size Hash
Imagine you have a unique code, like a fingerprint that is always 32 bytes long. Here’s how you can store it in Vyper.
fixed_code: bytes32
what this means is that bytes32
will always be 32 bytes.
Dynamic Byte Arrays
Dynamic byte arrays can hold data of different lengths if they don't exceed a maximum size. It helps store things like short messages.
Example: Saving a Short Message
Let’s say you want to save a message, like "Hello, World!", which can be up to 100 bytes long:
data: DynArray[100] = "Hello World"
Okay, that's enough learning for one day. Our next article will examine more data types and see how they function.
To read more on the above, check out Vyper documentation and Vyper by example.