Solidity & Vyper Cheat Sheet

A feature by feature reference guide to the two most popular programming languages on Ethereum.


Something missing? Check out the official Solidity reference or Vyper reference.

The content of this cheat sheet is open source and you are welcome to suggest changes at our GitHub repository.


Feature Solidity Vyper
Version
$ solc --version
Version: 0.5.14
$ vyper --version
0.1.0b14 (0.1.0 Beta 14)
General notes on syntax

Solidity loosely borrows its syntax from Javascript and C

Vyper syntax is valid Python 3 syntax (but the opposite is not true)

Block delimiters
{ }
:  # Vyper uses Python's off-side rule
Statement separator
;
'\n' and :
End of line comment
// comment
# comment
Multiple line comment
/* multiple line
comment */
# Multiple line
# comment
Constant
uint constant TOTAL_SUPPLY = 10000000;
TOTAL_SUPPLY: constant(uint256) = 10000000
Assignment
v = 1;
v = 1
Parallel assignment
(x, y) = (0, 1);

Tuple to tuple assignment not supported

Swap
(x, y) = (y, x);

Compound assignment
-=, *=, /=, %=, |=, &=, ^=
-=, *=, /=, %=, |=, &=, ^=
Increment and decrement
i++, ++i, i--, --i
i += 1, i -= 1
Null

null doesn't exist in Solidity but any unitialized variables take a default value represented by 0 in memory

null doesn't exist in Vyper but any unitialized variables take a default value represented by 0 in memory

Set variable to default value
delete v // doesn't work with mappings
clear(v) # doesn't work with mappings
Null test
v == 0
v == 0
Conditional expression
x > 0 ? x : -x

Conditional expression not supported

Operators
Feature Solidity Vyper
True and false
true false
True False
Falsehoods
false
False
Logical operators
&& || !
and or not
Relational operators
== != < > <= =>
== != < > <= =>
Min and max

max(x, y)
Arithmetic operators
+ - * / % ** unary-
+ - * / % ** unary-
Integer division
/
/
Bit operators
<< >> & | ^ ~
<< >> & | ^ ~
Binary & hex literals
uint x = 0x52
string memory s = hex"52"
a: address= 0x14d465376c051Cbcd80Aa2d35Fd5df9910f80543
b: bytes32= b'\x01\x02\x03\x04\x05\x06... (32 bytes)
c: bytes32= 0x010203040506... (32 bytes)
d: bytes[1] = 0b00010001
Data structures
Feature Solidity Vyper
String type
string
string[N]  # N is a fixed number
Bytes type
bytes  // dynamic
bytes1, bytes2, ..., bytes32  // packed
bytes[N]  // N is a fixed number, unpacked
bytes32
bytes[N]  # N is a fixed number
String literal
"don't \"no\""
'don"t \'no\''
"don't \"no\""
'don"t \'no\''
String length
bytes(s).length
len(s)
String literal escapes
\<newline> (escapes an actual newline)
\\ (backslash)
\' (single quote)
\" (double quote)
\b (backspace)
\f (form feed)
\n (newline)
\r (carriage return)
\t (tab)
\v (vertical tab)
\xNN (hex escape)
\uNNNN (unicode escape)
\<newline> (escapes an actual newline)
\\ (backslash)
\' (single quote)
\" (double quote)
\a (bell)
\b (backspace)
\f (form feed)
\n (newline)
\r (carriage return)
\t (tab)
\v (vertical tab)
\ooo (octal escape)
\xNN (hex escape)
\uNNNN (unicode escape)
\uNNNNNNNN (unicode escape)
Are strings mutable?

Yes

Yes

Slice

slice(x, start=_start, len=_len)
String comparison
keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2))
keccak256(s1) == keccak256(s2)
String concatenation
abi.encodePacked(s1, s2)
concat(s1, s2)
Array literal
[1, 2, 3]
[1, 2, 3]
Length
a.length
len(a)
Empty test
a.length == 0

Lookup
a[0]
a[0]
Update
a[0] = 1;
a[0] = 1
Out of bounds access

Failing assertion

Failing assertion

Add new element
a.push(3);  # Dynamic arrays

Remove element
a.pop();  # Dynamic arrays

Struct
struct Pair {
    uint x;
    uint y;
}  // Creating a struct

Pair memory pair = Pair(2, 3);  // Instantiating a struct variable
require(pair.y > pair.x);  // Accessing elements
struct Pair:
    x: uint256
    y: uint256  # Creating a struct

pair: Pair = Pair({x: 2, y: 3})  # Instantiating a struct variable
assert pair.y > pair.x)  # Accessing elements
Mapping size

Impossible to know

Impossible to know

Lookup
m[2]
m[2]
Update
m[2] = 1;
m[2] = 1
Missing key behaviour

A mapping has no concept of set keys, a mapping always refers to a hashed value that is the same for a given mapping and key

A mapping has no concept of set keys, a mapping always refers to a hashed value that is the same for a given mapping and key

Delete key
m[2] = 0;
clear(m[2])
Functions
Feature Solidity Vyper
Define function
function add2(uint x, uint y) public pure returns (uint) {
    return x + y;
}
@public
def add2(x: uint256, y: uint256) -> uint256:
    return x + y
Invoke function
add2(x, y)
add2(x, y)
Control flow
Feature Solidity Vyper
If statement
if (a > 2) {
    ...
else if (a == 0) {
    ...
} else {
    ...
}
if a > 2:
    ...
elif a == 0:
    ...
else:
    ...
For loop
for (uint i = 0; i < 3; i++) {
    ...
}
for i in range(3):
    ...
While loop
while (a > 0) {
    ...
}

Do-While loop
do {
    ...
} while (a > 0);

Return value
return x + y;
return x + y
Break
break;
break
Continue
continue;
continue
Assert
assert(x > y);
assert x > y
Require
require(x > y);

Exceptions
require(false, "revert reason")
raise "revert reason"
Misc
Feature Solidity Vyper
Comments
NatSpec conventions:

/// @author Mary A. Botanist
/// @notice Calculate tree age in years, rounded up, for live trees
/// @dev The Alexandr N. Tetearing algorithm could increase precision
/// @param rings The number of rings from dendrochronological sample
/// @return age in years, rounded up for partial years
def foo():
    """
    @author Mary A. Botanist
    @notice Calculate tree age in years, rounded up, for live trees
    @dev The Alexandr N. Tetearing algorithm could increase precision
    @param rings The number of rings from dendrochronological sample
    @return age in years, rounded up for partial years
    """
    ...
Payment with error on failure
address.transfer()
send(address, value)
Payment with false on failure
address.send()

Payment with gas forwarding (WARNING)
address.call.value().gas()()
raw_call(address, data, outsize, gas, value, is_delegate_call)
Event logging
event Deposit(
    address indexed _from,
    bytes32 indexed _id,
    uint _value
);

emit Deposit(msg.sender, _id, msg.value);
Deposit: event({_from: indexed(address), _id: indexed(bytes32), _value: uint256})

log.Deposit(msg.sender, _id, msg.value)
Units and global constants
1 ether
1 finney
1 szabo
1 wei
1 seconds
1 minutes
1 hours
1 days
1 weeks
1 years  // deprecated)
ZERO_ADDRESS
as_wei_value(1, "finney")
as_wei_value(1, "szabo")
as_wei_value(1, "wei")
as_wei_value(1, "babbage")
as_wei_value(1, "shannon")
EMPTY_BYTES32
MAX_INT128
MIN_INT128
MAX_DECIMAL
MIN_DECIMAL
MAX_UINT256
ZERO_WEI

time: timestamp
time_diff: timedelta

# define custom units
units: {
    cm: "centimeter",
    km: "kilometer"
}
a: int128(cm)
b: uint256(km)
Block and transaction properties
blockhash(blockNumber)
block.coinbase
block.difficulty
block.gaslimit
block.number

block.timestamp
now  // alias for block.timestamp
gasleft()
msg.data
msg.gas
msg.sender
msg.sig
msg.value
tx.gasprice
tx.origin
blockhash(blockNumber)
block.coinbase
block.difficulty

block.number
block.prevhash  # Same as blockhash(block.number - 1)
block.timestamp



msg.gas
msg.sender

msg.value

tx.origin