Vyper by example

To get up to speed with this new exciting language, we'll go through a simple smart contract so that you can see the full complexity of Vyper. We'll see all the types of variables and functions in one single smart contract.

Go ahead and create a new example.vy file. As you can see, Vyper smart contracts have the .vy termination. Inside it, type down the following code; we'll later explain what every variable means and how they are used. This is just a quick exercise to get your programming hands familiar with how Vyper is written. This code will be your go-to guide to familiarize yourself with Vyper's syntax:

# Events
LogTransfer: event({from: indexed(address), to: indexed(address), amount: uint256})

# Custom units
units: {
kg: "kilogram"
}

# Numbers
myPositiveInteger: uint256
myDecimalNumber: decimal
myInteger: int256

# Addresses
owner: address

# Strings
myName: bytes32
myLongArticle: bytes[1000]

# Booleans
isThisTrue: bool

# Mappings
todoList: map(uint256, bytes32)

# Structs
struct Client:
name: bytes32
age: uint256

myClients: Client[100]

# Timestamps
myBirthday: timestamp
expirationTime: timedelta

# Wei value
etherToSpend: wei_value

# Custom unit types
myKilo: uint256(kg)

# Public functions
@public
def subNumbers(first: int128, second: int128) -> int128:
return first - second

# Payable functions
@public
@payable
def transferFunds(_from: address, to: address, amount: uint256):
log.LogTransfer(_from, to, amount)

# Functions that update state
@public
def updateBoolean(result: bool):
self.isThisTrue = result

# Constructor
@public
def __init__():
self.owner = msg.sender

# Fallback function
@public
@payable
def __default__():
self.myBirthday = now

These are some clarifications to help you understand what is going on:

  • Events must be declared at the top of the Vyper file, and they have to come inside curly brackets, like these: ({}).
  • Unsigned integers can only be positive, and their maximum value is 2**256. You can't have uint8 or equivalent; all uints must be uint256.
  • Signed integers, normal integers, can be positive or negative with a maximum value of 2**128 from both sides. They can only be int128, so you can't have smaller sizes.
  • Decimals have a precision of 10 decimal places, meaning that you can have up to 10 characters after the dot, for instance, 1.2394837662.
  • Strings can either be bytes32 or byte arrays with a custom size, such as bytes[2000]. Note that you don't have the string type of variable, so your strings will be stored as hexadecimal texts after you upload them. Also, you can't have variable-size bytes, such as bytes[], because they create uncertainty when calculating gas costs.
  • Mappings must be declared with the map() function and they can be accessed with brackets, for instance, todoList[3] = "Start something".
  • Timestamp is a fixed date for events such as your birthday, or a specific time in the future. This is mostly used as date containers. timedelta is more like a counter without a precise date in the calendar. For instance, timedelta could store 2 months, while timestamp could store January 1 2019, all in numerical format.
  • The wei value is the type used for storing Ether in wei.
  • Custom unit types are personalized types that you define at the top of the file and you can then use for your variables. They must be casted as uints, ints, or decimals.
  • Functions can be public or private. Public functions must have the @public decorator on top of them. The return value of functions is specified with the arrow sign, ->.
  • Payable functions must use the @payable decorator and they can access the Ether sent (if any) with msg.value.
  • To update state variables inside functions, you must use the self. keyword in front of them to update them as state variables. In Vyper, you don't need to add the underscore _ in front of parameter names, because you can easily reference the variable with the same name in state, while in Solidity you can't, so you had to use underscores to differentiate them.
  • The constructor is called __init__(), while the fallback function is called __default__().

That's it! The fastest way you can master Vyper in a few pages. Make sure that you keep this guide in a special place for whenever you write Vyper contracts to save you hours of headaches and uncomfortable moments.