A sleek solidity cheatsheet
part 1 of a 5 part series on essentials for solidity devs solidity_cheatsheet.sol cryptography_cheatsheet.sol assembly_cheatsheet.sol designPatterns_cheatsheet.sol security_cheatsheet.sol It compiles! Get the full cheatsheet here. Drop a star if you find this useful, it will motivate me to do more of it. table of contents basics license pragma imports contract events constructor receive modifier functions symbols variables control sturctures units block msg tx intermediate OOPs library custom errors fallback variable passing value types reference types type conversion datatype builtins fringe arithmetic advanced function signatures and selectors abi encoding low level calls error handling bit operations bitmasking license copyleft: ensure that the software is free and open-source even in its derivative versions you use this when you do open source software and don't want to let someone else make it proprietary examples: GNU General Public License v3.0 (GPL-3.0) permissive: allows the software to be used in proprietary software you use this when you want maximum adoption with minimal legal overhead examples: MIT, Apache-2.0, BSD-3-Clause implementaion: SPDX-License-Identifier: licence Software Package Data Exchange (SPDX) this licence declaration is directly included in the source code as a commment // SPDX-License-Identifier : GPL-3.0 pragma ^version: means versions above this but below breaking changes version nothing before the version means just that one version pragma solidity ^0.8.20; imports import "filename"; imports everything from that file import {symbol1, symbol2} from "filename"; imports only the mentioned items import {symbol1 as alias1, symbol2 as alias2} from "filename"; import "@openzeppelin/token/ERC20/utils/SafeERC20.sol"; OOPs problem : large codebases are hard to manage solution : structure code into smaller packets. implementation components: class, object, method, variables is: inherits contracts contract A is B,C,D : B is most base, D is most derived C3 linearization right to left(D to B) to resolve conflicts in inheritance constructor: order of execution from most base to most derived (B to D) visibility: public, internal, private, external abstract: when a function is missing definition super: call parent class definition this: the contract itself in which 'this' is invoked(contract type) virtual and override: manage polymorphism properties encapsulation: bundling everything to form a fully working entity abstraction: only expose what is required, rest is kept enclosed inheritance: acquiring properties from parents polymorphism: The ability to take multiple forms (method overloading & method overriding) pros : Code Reusability Modularity Security & Data Hiding Easy Maintenance & Scalability trivia: C3 linearization to resolve inheritance conflicts: inheritance from right to left in the 'is' statement library implementation cannot have state variables functions in library to have the first parameter as the 'datatype' on which to attach the library libraries can be used in two methods using library for type : attaches library functions to the type library.method trivia: cannot inherit, nor be inherited inheritance doesnt bring using for statement from parent to child, need to write using for again in child. cannot recieve ether deployment: libraries are deployed only when it contains external functions and called by delegatecall else its code is embedded into the calling contract at compile time the calling convention is designed like internal call not following the abi standard using SafeERC20 for IERC20; events has normal params and indexed params(for quick searches) indexed topics are capped at max 3 trivia: Event logs are stored on blockchain but not accessible from within contracts not even from the contract that created them indexed are special params included in a seperate place called topics 'indexed' arguments make it easy for searching and filtering through the logs event Log(string message); event newOwner(address indexed owner); custom errors Cheaper gas costs (saves storage compared to string messages) More structured error messages. implementation error certain_edge_case_messing_up(); error certain_edge_case_messing_up_explained_with_args(args); revert certain_edge_case_messing_up(); revert certain_edge_case_messing_up_explained_with_args(args); error amount_smaller_than_100(uint256 amount); function custom_error(uint256 amount) public pure { if (amount< 100) { revert amount_smaller_than_100(amount); } } constructor executes once during deployment can recieve ether during deployment its runtime code, not part of the contract constructor execu

part 1 of a 5 part series on essentials for solidity devs
- solidity_cheatsheet.sol
- cryptography_cheatsheet.sol
- assembly_cheatsheet.sol
- designPatterns_cheatsheet.sol
- security_cheatsheet.sol
It compiles! Get the full cheatsheet here. Drop a star if you find this useful, it will motivate me to do more of it.
table of contents
- basics
- license
- pragma
- imports
- contract
- events
- constructor
- receive
- modifier
- functions
- symbols
- variables
- control sturctures
- units
- block
- msg
- tx
- intermediate
- OOPs
- library
- custom errors
- fallback
- variable passing
- value types
- reference types
- type conversion
- datatype builtins
- fringe arithmetic
- advanced
- function signatures and selectors
- abi encoding
- low level calls
- error handling
- bit operations
- bitmasking
license
- copyleft:
- ensure that the software is free and open-source even in its derivative versions
- you use this when you do open source software and don't want to let someone else make it proprietary
- examples: GNU General Public License v3.0 (GPL-3.0)
- permissive:
- allows the software to be used in proprietary software
- you use this when you want maximum adoption with minimal legal overhead
- examples: MIT, Apache-2.0, BSD-3-Clause
- implementaion: SPDX-License-Identifier: licence
- Software Package Data Exchange (SPDX)
- this licence declaration is directly included in the source code as a commment
// SPDX-License-Identifier : GPL-3.0
pragma
- ^version: means versions above this but below breaking changes version
- nothing before the version means just that one version
pragma solidity ^0.8.20;
imports
- import "filename";
- imports everything from that file
- import {symbol1, symbol2} from "filename";
- imports only the mentioned items
- import {symbol1 as alias1, symbol2 as alias2} from "filename";
import "@openzeppelin/token/ERC20/utils/SafeERC20.sol";
OOPs
- problem : large codebases are hard to manage
- solution : structure code into smaller packets.
- implementation
- components: class, object, method, variables
- is: inherits contracts
- contract A is B,C,D : B is most base, D is most derived
- C3 linearization right to left(D to B) to resolve conflicts in inheritance
- constructor: order of execution from most base to most derived (B to D)
- visibility: public, internal, private, external
- abstract: when a function is missing definition
- super: call parent class definition
- this: the contract itself in which 'this' is invoked(contract type)
- virtual and override: manage polymorphism
- properties
- encapsulation: bundling everything to form a fully working entity
- abstraction: only expose what is required, rest is kept enclosed
- inheritance: acquiring properties from parents
- polymorphism: The ability to take multiple forms (method overloading & method overriding)
- pros :
- Code Reusability
- Modularity
- Security & Data Hiding
- Easy Maintenance & Scalability
- trivia:
- C3 linearization to resolve inheritance conflicts: inheritance from right to left in the 'is' statement
library
- implementation
- cannot have state variables
- functions in library to have the first parameter as the 'datatype' on which to attach the library
- libraries can be used in two methods
- using library for type : attaches library functions to the type
- library.method
- trivia:
- cannot inherit, nor be inherited
- inheritance doesnt bring using for statement from parent to child, need to write using for again in child.
- cannot recieve ether
- deployment:
- libraries are deployed only when it contains external functions and called by delegatecall
- else its code is embedded into the calling contract at compile time
- the calling convention is designed like internal call not following the abi standard
using SafeERC20 for IERC20;
events
- has normal params and indexed params(for quick searches)
- indexed topics are capped at max 3
- trivia:
- Event logs are stored on blockchain but not accessible from within contracts not even from the contract that created them
- indexed are special params included in a seperate place called topics
- 'indexed' arguments make it easy for searching and filtering through the logs
event Log(string message);
event newOwner(address indexed owner);
custom errors
- Cheaper gas costs (saves storage compared to string messages)
- More structured error messages.
- implementation
- error certain_edge_case_messing_up();
- error certain_edge_case_messing_up_explained_with_args(args);
- revert certain_edge_case_messing_up();
- revert certain_edge_case_messing_up_explained_with_args(args);
error amount_smaller_than_100(uint256 amount);
function custom_error(uint256 amount) public pure {
if (amount< 100) {
revert amount_smaller_than_100(amount);
}
}
constructor
- executes once during deployment
- can recieve ether during deployment
- its runtime code, not part of the contract
- constructor execution order: B -> C -> solidity_cheatsheet
- most base to most derived
constructor(/* args1, args2 */) /* B(args1) C(args2) */ payable {
wingman = new Wingman();
owner = msg.sender;
emit newOwner(owner);
}
fallback
- called when the contract is invoked with calldata, but function definition is absent
- this function has builtin definition and its very strict, only two variations allowed
- fallback() external [payable] {}
- fallback(bytes calldata input) external [payable] returns(bytes memory) {}
- trivia:
- does not have a function signature
fallback(bytes calldata _shipment) external payable returns(bytes memory){
string memory payload = abi.decode(_shipment,(string));
return bytes(string.concat(payload, "_done"));
}
receive
- this function is called when the contract is invoked without calldata
- main purpose is to receive ETH
- this function has builtin definition, only one variation allowed
- receive() external payable {}
- its mostly kept empty
- trivia:
- does not have a function signature
receive() external payable {}
modifier
- a piece of code that generally contains some checks and is placed on top of a function
- modifiers can accept arguments
- function body represented by _ it can be included multiple times.
- Modifiers wrap around the function body using the special placeholder _ When multiple modifiers are applied, they execute in a nested manner:
- The first modifier runs until it reaches _.
- Control moves to the next modifier in the order they are listed.
- This continues until the function itself executes.
- Once the function completes, execution unwinds back up through the modifiers.
modifier onlyOwner() {
require(msg.sender == owner, "only owner can call this function");
_;
}
modifier single_digit_value(uint256 _value) {
require(_value < 10, "value should be less than 10");
_;
}
function onlyOwnerFunction(uint256 value) view public onlyOwner single_digit_value(value) returns(string memory) {
return "greetings to the owner";
}
functions
- return variables can be used as any other local variable.
- members: .selector
- return: concludes the function execution generally returns some value.
symbols
- () --> functions, mapping, typecasting
- {} --> function blocks, struct blocks, conditional blocks, loop blocks
- [] --> arrays
- ; --> end of statement
- : --> key value pair, array slicing, ternary operator
- , --> seperator
- . --> access
- - --> subtraction
- + --> addition
- * --> multiplication
- / --> division
- % --> modulo
- ** --> power
- || --> or
- && --> and
- | --> bitwise or
- & --> bitwise and
- ! --> not
- ~ --> bitwise not
- ^ --> bitwise xor
- << --> left shift
- >> --> right shift
- == --> equal
- != --> not equal
- < --> less than
- > --> greater than
- <= --> less than or equal
- >= --> greater than or equal
- = --> assignment
- += --> addition assignment
- _ --> integer filler
- "" --> string
- '' --> string
- \ --> escape character
- // --> single line comment
- /// --> natspec comment
- /* */ --> multi line comment
- /** */ --> multi line natspec comment
variables
- life cycle of a variable
- definition
- declaration
- assignment
- access
- attributes
- interpretation
- size
- type
- data location
- slot position
- behaviour
- visibility
- name
- value
variable passing
pass by value: value copy pasted to new location, new variable (copy paste)
-
pass by reference:
- pass in same data location: nothing is copy pasted, instead a new name is given to the same location value pair (renaming)
- pass in different data location: pass by value
| value |
|-----------|
| location |
name1
data location
bit level architecture, data location, inline assembly and gas costs covered in assembly cheatsheet.
--- memory ---
- structure : byte addressable array that reads and writes on 32 byte words
- trivia
- locally available, function scoped
- temporary existence, only for duration of tx
- cheap
--- storage ---
- structure
- mapping of 32-byte keys(storage-slots) to a 32-byte values
- storage slots start at slot 0
- trivia
- globally avilable
- permanent existance
- expensive
--- calldata ---
samae as memory, but its read only