Ethereum #
Limitations of Bitcoin #
- UTXO contains
ScriptPK
or hash thereof- Simple script: indicates conditions when UTXO can be spent
- However: difficult to maintain state in multi-stage contracts or to enforce global rules on assets
- e.g. rate limiting: if wallet has 100 UTXOs, and want to enforce transfer of max 2BTC per day out of wallet, this is impossible!
Example: NameCoin #
- DNS on the blockchain
- Need operations:
Name.new(OwnerAddr, DomainName)
: intent to registerName.update(DomainName, newVal, newOwner, OwnerSig)
Name.lookup(DomainName)
- note: also need to ensure no front-running on
Name.new()
- UTXO for new, update:
DUP HASH256 <OwnerAddr> EQVERIFY CHECKSIG VERIFY <NAMECOIN> <DomainName> <IPAddr> <1>
- Limitation: cannot enforce “if I own a domain name, nobody else can register or update to that domain name”
- Required a fork of Bitcoin to achieve
- However: gave rise to Ethereum, which natively supports global state
Cryptocurrencies as state transition systems #
- Bitcoin: each transaction is a function mapping from set of possible world states, set of possible inputs -> set of possible world states
- Limited functionality in these transactions: the mutation only executes over UTXOs transforming one UTXO to another UTXO
- Ethereum: much richer state transaction function
- One transition executes an entire program
Ethereum applications #
- Ethereum DApps include:
- New coins: ERC-20 standard interface
- Decentralized finance: exchanges, lending, stablecoins, derivatives, etc
- Insurance
- Decentralized organizations
- NFTs: managing asset ownership (ERC-721 interface)
- DApps run on:
- Base: consensus layer: beacon chain
- Compute layer: execution chain
- Create DApp w/Program Code, runs on compute layer mapping states to states with transactions as transitions
The Ethereum system #
Consensus layer: proof-of-stake #
- One block every 12 seconds; about 150 Tx per block
- Block proposer receives Tx fees for the block, along with other rewards
- Beacon chain: Eth2 (post-Sep. 2022) consensus layer
- Validators, not miners
- To become a validator: stake (lock up) 32 ETH, or use Lido
- Validators:
- Sign blocks to express correctness
- Occasionally propose blocks (chosen at random)
- Correct behavior: issued new ETH every epoch (32 blocks)
- Incorrect behavior: slashed
- When consensus reached:
notify_new_payload(payload)
(Engine API) called, sends transactions to compute layer
Compute layer: Ethereum Virtual Machine #
- World state: set of accounts identified by 32-byte address
- Types of accounts:
- Owned accounts: controlled by ECDSA signing pair
(pk, sk)
- Contracts: controlled by code (set at account creation time, does not change)
- Owned accounts: controlled by ECDSA signing pair
EVM structure and instructions #
- Stack machine (like Bitcoin) but with JUMP (so loops allowed)
- Max stack depth = 1024
- Program aborts if stack size exceeded; block proposer keeps gas
- Contract can create or call another contract
- Opcodes at evm.codes
- Two types of zero-initialized memory:
- Persistant storage (on blockchain), to use
SLOAD
,SSTORE
(expensive) - Volatile memory (for single Tx):
MLOAD
,MSTORE
(cheap) LOG0(data)
: write data to log
- Persistant storage (on blockchain), to use
- Every instruction costs gas:
SSTORE <addr>, <value>
(32 byte variables each)- zero -> nonzero: 20,000 gas
- nonzero -> nonzero: 5,000 gas (for a cold slot)
- nonzero -> zero: 15,000 gas refund (example)
- Refunds given for reducing size of blockchain state: incentivizes contracts to clean up after themselves
- However: refund has a maximum, cannot make money by just cleaning up the blockchain
CREATE
: 32,000 + 200x code size gasCALL gas, addr, value, args
: call another contractSELFDESTRUCT addr
: kill current contract, 5000 gas
Account data #
- Address (computed):
- Owned,
H(pk)
- Contracts:
H(CreatorAddr, CreatorNonce)
- Owned,
- Code:
- Owned: none
- Contracts:
CodeHash
- Storage root (state):
- Owned: none
- Contracts:
StorageRoot
- Balance (in Wei = 10-18 ETH, note GigaWei often used = 10-9 ETH)
- Both for humans and contracts
- Nonce:
- Both for humans and contracts
- Nonce = number of Tx sent + number of accounts created: anti-replay mechanism
Account state: persistent storage #
- Every contract has associated storage array
S[]
w/capacity 2256-1, where each cell holds 32 bytes, init to 0 - Account storage root: Merkle Patricia Tree, keys are hash of
S[]
- Due to cannot compute full Merkle tree hash: 2256 leaves
State transitions: Tx and messages #
- Transactions: signed data by initiator, fields:
- To: 32-byte address of target (0 means create new account)
- From, [Signature]: initiator address and signature on Tx (if owned)
- Value: # Wei being sent with Tx
- Tx fees (EIP 1559):
gasLimit
,maxFee
,maxPriorityFee
- if To = 0: create new contract
code = (init, body)
- if To != 0:
data = (function, args)
- Nonce: must match current nonce of sender (to prevent Tx replay)
- Transaction types:
- owned -> owned: transfer ETH between users
- owned -> contract: call contract w/ETH and data
- contract -> owned: contract sends funds to user
- contract -> contract: one program calls another (and sends funds)
- Enables composability of contracts
- One transaction from user can lead to many Tx processed
An Ethereum Block #
- Validators collect Txs from users => proposer creates a block of
n
Tx- To produce block, do:
- for i = 1,…,n: execute state change of Txi sequentially (can change state of >n accounts)
- record updated world state in block
- Other validators revalidate all Tx to verify block
- sign block if valid; if enough sigs, finalizes epoch
- To produce block, do:
- Block headers:
- Consensus data: proposer ID, parent hash, votes, etc
- Address of gas beneficiary (Tx fee recipient)
- World state root: updated world state
- Merkle Patricia Tree hash of all accounts in system
- Tx root: Merkle hash of all Tx processed in block
- Tx receipt root: Merkle hash of all log messages generated in block
- Gas used: used to adjust gas price (target 15M gas per block)
- Total blockchain size, ETH world, Oct. 2022: 12TB
Gas calculation #
- Why charge Tx fees (gas)?
- Gas prevents submitting Tx that runs for many steps
- During high load: block proposes Tx from mempool that maximize its income
- Gas prices spike during congestion
- Old EVM (prior to Aug. 2021):
- Every Tx contains a
gasPrice
“bid” (gas -> Wei conversion bid) - Producer chooses Tx w/highest
gasPrice
(max sum(gasPrice * gasLimit))
- Not an efficient auction mechanism
- Changed Aug. 2021 to second-choice auction type design
- Every Tx contains a
- EIP1559 EVM gas calculation:
- Every block has a
baseFee
: minimumgasPrice
for Tx in the block baseFee
computed from total gas in earlier blocks- Earlier blocks at gas limit (30M gas) - lots of congestion: base fees goes up 12.5% to discourage participation
- Earlier blocks empty - no congestion: base fee decreases by 12.5% to encourage participation
- If earlier blocks at “target size” (15M gas): base fee does not change
- Transaction specifies three parameters:
gasLimit
: max total gas allowed for TxmaxFee
: maximum allowed gas pricemaxPriorityFee
: additional “tip” to be paid to block proposer
- Computed
gasPrice
bid in Wei:gasPrice <- min(maxFee, baseFee + maxPrioirityFee)
- Max gas:
gasLimit * gasPrice
- Algorithm:
if gasPrice < baseFee
: abort- if
gasLimit * gasPrice > msg.sender.balance
: abort - deduct
gasLimit * gasPrice
frommsg.sender.balance
- set
Gas <- gasLimit
- execute Tx: deduct gas from
Gas
for each instruction- if at end
Gas < 0
: abort, mark Tx invalid (proposer keepsgasLimit * gasPrice
)
- if at end
- Refund
Gas * gasPrice
tomsg.sender.balance
(leftover change) gasUsed <- gasLimit - Gas
- Burn
gasUsed * baseFee
(destroys ether, deflation) - Send
gasUsed * (gasPrice - baseFee)
to block producer (tip)
- Burn
- Max gas:
- Why burn ETH?
- Goals of EIP1559:
- Incentivize users to bid true utility for posting Tx
- Incentivize block proposer to not create fake Tx
- Disincentivize off-chain agreements
- Without burn (i.e.,
baseFee
given to block producer):- In periods of low Tx, volume proposer would try to increase volume by offering to refund
baseFee
off-chain to users
- In periods of low Tx, volume proposer would try to increase volume by offering to refund
- Goals of EIP1559:
- Every block has a