Cheatsheet: Full solidity docs
=================
Every contract needs to specify a solidity compiler to use. This is because changes in the solidity compiler
version may introduce breaking and dangerous divergent behavior.
pragma solidity ^0.8.0;
=================================
function myFunction() <visibility specifier> returns (bool) {
return true;
}
public: visible externally and internally (creates agetter function<getter-functions>for storage/state variables)external: only visible externally (only for functions) - i.e. can only be message-called (viathis.func)internal: only visible internallyprivate: only visible in the current contract
============
function myFunction() <optional function modifier> <visibility specifier> returns (bool) {
return true;
}
-
purefor functions: Disallows modification or access of state -
viewfor functions: Disallows modification of state -
payablefor functions: Allows them to receive Ether together with a call -
virtualfor functions and modifiers: Allows the function's or modifier's behavior to be changed in derived contracts -
override: States that this function, modifier or public state variable changes the behavior of a function or modifier in a base contract -
constantfor state variables: Disallows assignment (except initialization), does not occupy storage slot -
immutablefor state variables: Allows exactly one assignment at construction time and is constant afterwards
uint256 constant varA;
uint256 immutable varB;
========
bool: Boolean which is eithertrueorfalse- Example:
bool foo = true;
- Example:
int/uint: alias forint256/uint256int8/uint8: 1 byte numberint16/uint16: 2 byte number- ...
int256/uint256: 32 byte number
bytesXbytes1: 1 byte lengthbytes2: 2 byte length- ...
bytes32: 32 byte length
bytes: encoded as a bytes1 array (bytes foo = bytes1[] foo)string: encoded as a bytes1 array (string foo = bytes1[] foo)address: holds a 20 byte value- Has the following functions:
balance: Ether balancecall: Issue a low level call on the address- msg.value can be overriden
someContract.call{value: 1 ether}("");delegatecall: Issue a low level delegatecall on the address
- Has the following functions:
address payable: same asaddressbut also has thetransferandsendfunctionsarray:- Example:
uint256[] arrayOfNumbers; - Example:
arrayOfNumbers.push(10); - Example:
uint256 foo = arrayOfNumbers.pop();
- Example:
mapping: Same idea as a python dictionary. key-value pairing- Example:
mapping(address => bool) allowed; - Example:
allowed[msg.sender] = true
- Example:
NOTE: Min and max values for
int/uinttypes can be done viatype(T).minortype(T).maxExample:type(int8).min == -128andtype(int8).max == 127.
NOTE: To send ether to a contract, the variable must be of type
address payableor must be casted to that type via thepayable(<variable>);syntax.
WARNING: The low-level calls which operate on addresses rather than contract instances (i.e.
.call(),.delegatecall(),.staticcall(),.send()and.transfer()) do not include a check to ensure the address is a smart contract and as such will not revert when attempting to call a function at that address. This means that(bool success, ) = address(0x0000000000000000000000000000000000000000).call("")will always setsuccesstotrue.
=================
assert(bool condition): reverts transaction ifconditionis false- Example:
assert(a + b) <= type(uint256).max
- Example:
require(bool condition): reverts transaction ifconditionis false- Example:
require(success)
- Example:
require(bool condition, string memory message): reverts transaction ifconditionis false and provides the string as an error message which is used to determine why the transaction reverted- Example:
require(success, "Could not send funds to contract!")
- Example:
revert(): reverts a transaction- Example:
revert()
- Example:
revert(string memory message): reverts a transaction and provides the string as an error message which is used to determine why the transaction reverted- Example:
revert("This feature is not implemented yet!")
- Example:
=======================
-
wei: 1 wei == 1
-
gwei: 1 gwei == 1 * 10**9 == 1e9
-
ether: 1 ether == 1 * 10**18 == 1e18
-
seconds: 1 seconds = 1
-
minutes: 1 minutes == 60 seconds
-
hours: 1 hours == 60 minutes
-
days: 1 days == 24 hours
-
weeks: 1 weeks == 7 days
===================
- Left shift: x << y == x * 2**y
- Right shift: x >> y == x / 2**y
===================
-
abi.decode(bytes memory encodedData, (...)) returns (...):ABI <ABI>-decodes the provided data. The types are given in parentheses as second argument- Example:
(uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))
- Example:
-
abi.encodeWithSignature(string memory signature, ...) returns (bytes memory): Equivalent toabi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)- Example:
address(contract).call( abi.encodeWithSignature("someFunc(uint256)", varA) )
- Example:
-
block.number(uint): current block number -
block.timestamp(uint): current block timestamp in seconds since Unix epoch -
msg.data(bytes): complete calldata -
msg.sender(address): sender of the message (current call) -
msg.sig(bytes4): first four bytes of the calldata (i.e. function identifier) -
msg.value(uint): number of wei sent with the message -
tx.origin(address): sender of the transaction (full call chain) -
keccak256(bytes memory) returns (bytes32): compute the Keccak-256 hash of the input -
ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address): recover address associated with the public key from elliptic curve signature, return zero on error -
this(current contract's type): the current contract, explicitly convertible toaddressoraddress payable -
super: the contract one level higher in the inheritance hierarchy -
selfdestruct(address payable recipient): destroy the current contract, sending its funds to the given address
NOTE: The global variables under the
msgprefix can change when one contract calls another contract (within the same transaction). The global variables under thetxprefix cannot change for the duration of the entire transaction.
EoA (0x1111...) ---------------------> Contract A (0xAAAA...) ---------------------> Contract B (0xFFFF...)
msg.sender: 0x1111... msg.sender: 0xAAAA...
tx.origin: 0x1111... tx.origin: 0x1111...
==============
- Contracts can inherit from other contracts
contract Base {
constructor() {}
function addNumbers(uint256 a, uint256 b) public returns (uint256) {
return a + b;
}
}
contract TestContract is Base {
constructor() {}
function foo(uint256 a, uint256 b) public {
addNumbers(a, b);
}
}
- Types can inherit from library contracts
library SafeMath {
function add(uint256 a, uint256 b) public returns (uint256) {
uint256 c = a + b;
require(c >= a, "Operation caused an overflow!");
return c;
}
}
contract TestContract {
using SafeMath for uint256;
constructor() {}
function addNumbers(uint256 a, uint256 b) public returns (uint256) {
uint256 c = a.add(b);
return c;
}
}
==================
===========================================
contract TestContractA {
address bAddr;
address cAddr;
constructor(address _bAddr, address _cAddr) {
bAddr = _bAddr;
cAddr = _cAddr;
}
function sendBalanceToContractB() payable public returns(uint256) {
(bool success, bytes memory returnData) = payable(bAddr).call{value: address(this).balance}("");
require(success);
}
function sendBalanceToContractC() payable public returns(uint256) {
(bool success, bytes memory returnData) = payable(cAddr).call{value: 1 ether}("");
require(success);
}
}
contract TestContractB {
receive() external payable {}
}
contract TestContractC {
fallback() external payable {}
}
=============================
contract TestContract {
constructor() {}
receive() external payable {}
}
==================================================
contract TestContract {
address owner;
constructor() {
owner = msg.sender;
}
receive() external payable {}
modifier onlyOwner() {
require(msg.sender == owner, "Only the owner can call this function!");
_;
}
}
====================
These keywords are reserved in Solidity. They might become part of the syntax in the future:
after, alias, apply, auto, byte, case, copyof, default,
define, final, implements, in, inline, let, macro, match,
mutable, null, of, partial, promise, reference, relocatable,
sealed, sizeof, static, supports, switch, typedef, typeof,
var.