keyword that enables certain compiler feature or checks
compiler version (pragma solidity ^0.8.0;)
ABI Version (pragma abicoder v2;)
experimental versions (pragma experimental smtchecker;)
can be accessed by all functions of the contract and whose values are permanently stored on the blockchain. vs global vars like block timestamp, etc. Visibility:
public - part of contract interface and can be either accessed internally or via messages/calls
internal - accessed internally from within contract or derived contracts
private (still visible to 'humans') - accessed from the contract they are defined in and not even in derived contracts!
also that local variables are ephemeral

*
Immutable & const state vars are lighter on gas when functions call this state variable
const var: the expression assigned to it is copied to all places where it is accessed and re-evaluated each time
immutable vars are evaluated once at construction time and their value is copied to all the places in the code where they are accessed
for these copied values, 32 bytes are reserved even if they would fit in fewer bytes, so const var can be lighter on gas than immut var
walking through a function

function returning with a named param vs just a type
when specifying named of returned param you don't need to explicitly return
Modifiers - use to change behavior of a func. can use to auto check a condition prior to execution (onlyOwner is a common one for example). Great way to reuse assertions
underscore + ; tells solidity compiler to put the body of the modified function here (kind of like a template literal/string lol). so this is always found after the modifier's conditional checks/assertions
a classic```
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
function visibility
public
part of contract interf. can be called internally or via messages
external
part of contract interf. can be called from other contracts and via txs. external func cannot be called internally (f() doesn't work, but this.f() will)
internal
can only be accessed from within current contract or derived contracts
private
can only be accessed from within current contract (no derived)
Pure vs view vs default
func is default if it modifies or reads state vars
view is read only (global or state) does not modify state
pure doesn't read or modify state vars, it only works with local state and/or params
Override vs virtual: A function that allows an inheriting contract to override its behavior will be marked as virtual. The function that overrides that base function should be marked as override.
most basic version of this === OZ ownable contracts/onlyOwner modifier
more adv access control via roles initialized in constructor (RBAC) offered by OZ
DSRole similar but based on lookup tables
DSAUTH auth modifier triggers the internal isAuthorized function to require that the msg.sender is authed
DSGuard maintains an ACL that acts as the authority for dsauth
