Tags: #crypto-journey #crypto #web3 #ethereum #blockchain
Reading [How does Ethereum work, anyway](https://preethikasireddy.medium.com/how-does-ethereum-work-anyway-22d1df506369) by Preethi Kasireddy
IMO, it never hurts to explain the blockchain.
- A blockchain is a "cryptographically secure transactional singleton machine with shared-state"
- Cryptographically secure = secured by mathematical algorithms that are prohibitively difficult and expensive to break, making it difficult to cheat
- Transactional singleton machine = there is an instance of the machine with all recorded transactions that is a single global truth
- With shared-state = machine is shared and open to all
The Ethereum blockchain is a transaction-based state machine. It begins in a given state, reads a series of inputs, then based on those inputs in transitions to a new , final state. Any any point in time, the final state is the current state of Ethereum. The original, blank state of Ethereum, before there were any transactions, is called the "genesis state".
The Ethereum blockchain contains millions of transactions that are grouped into blocks. Each block is chained to its previous block. For the Ethereum state to transition to a new state and add a new block of transactions to the blockchain, the block needs to be validated. The validation process is known as mining. Each miner provides mathematical "proof" when submitting a block, making the block valid. For the block to be added, the miner needs to have proved it faster than any other minor. This process is known as "proof of work". Every time a miner proves and adds a new block, they are awarded with Ether tokens.
> Uncertain: it is unclear to me whether each transaction is validated individually or whether each block is validated as a block, or both. From my experience using Etherscan, it seems like each transaction is validated individually.
> Uncertain: I've been focusing on understanding cryptocurrencies from a technical perspective, but my financials lag behind. The financial implications of the blockchain and its use cases are somewhat lost on me at the moment, but plan to learn more.
The current state of Ethereum blockchain is considered the global truth. If there were multiple chains, we wouldn't be able to agree on which transactions. When there are multiple chains, there's a "fork". To determine which chain is most valid, Ethereum utilizes the "GHOST protocol".
GHOST = Greedy Heaviest Observed Subtree
In the event that there are multiple chains, we take the chain that has had the most computation performed on it to be the canonical truth of the current state. One way to do that is to use the block number of the most recent block. The higher the number, the longer the chain, the more computation (and effort), went into it.
Kasireddy dives deeper into the multiple components of the Ethereum blockchain. A lot of it is somewhat technical and would take me multiple reads to absorb, but we'll take a crack at it.
## Accounts
Ethereum is comprised of accounts that interact with each other. Each account has a state and a 20-bit address.
There are two types of accounts:
- Contract accounts, which are controlled by the contract code.
- Externally owned accounts, which are controlled by private keys and have no code associated with them.
Externally owned accounts can initiate transactions, either to other externally owned accounts or contract accounts. A transaction between 2 externally owned accounts is a transfer of value. But a transaction between an externally owned account and a contract account can execute multiple functions depending on the contract's code. The externally owned account can mint tokens, write to storage, even create new contracts, for example.
> Observation: So far I have experimented a bit with executing transactions between my accounts and contract accounts by minting NFTs, but minting new tokens seems to be the equivalent of scraping the iceberg. I'm extremely curious about what I can do when writing to storage or creating new contracts.
Contract accounts cannot initiate transactions, but can only execute a transaction according to the contract code, in response to an externally owned account or another contract account. Transactions between two contract accounts can occur in response to a transaction initiated by an externally owned account.
### Account state
Account state is comprised of 4 components.
- nonce - for an externally owned account, nonce is defined as the number of transactions executed by that account. for an contract account, nonce is defined as the number of contracts created by the account.
- Wei - the number of Wei owned by the account. There are 1e18 Wei per Ether.
- storageRoot - a hash of the root node of the Merkle Patricia tree (to be explained), which encodes the hash of the storage contents of this account. the tree is empty by default.
- codeHash - a hash of the Ethereum Virtual Machine (EVM) code for this account. For contract accounts, the contract code is hashed. For externally owned accounts (which have no code associated with them), the empty string is hashed.
> Question: It is not clear to me what exactly is meant by a contract created by contract account. It is possible that what I'm thinking of as the contract account is actually the contract.
> Question: I might be misunderstanding what "hash" means, but if one hashes an empty string, don't you always get the same output?
### World state
Ethereum's global state is comprised of a mapping between account states and account addresses. This mapping is stored in Merkle Patricia trees.
A Merkle tree (also known as Merkle trie) is a binary tree comprised of the following set of nodes:
- leaf nodes at the bottom of the tree that contain the data
- intermediate nodes in the middle of the tree that are a hash of two child nodes
- root node formed from the hash of two child nodes. this is the top of the tree
The leaf nodes at the bottom of the tree are formed by hashing the data. The data is split into chunks, then split into buckets. The buckets are hashed and become the leaf nodes. The hashing process is repeated until we have the single root node at the top of the tree.
The trie has a key for every value stored in it. The root node will inform you which child node to follow to access the corresponding value stored in the leaf nodes. For Ethereum, the key/value mapping for the state tree is between the address and all associated accounts.
> Question: It's not clear to me what it means that the key/value mapping for the state tree is between an address and its associated accounts. I hadn't realized that an address could be shared by multiple associated accounts.
The trie structure is also used to store transactions and receipts. Each block has a header that stores the hash of the root node for each trie structure:
- Transaction trie -> transactionRoot
- Receipt trie -> receiptRoot
- State trie -> stateRoot
The way information is stored in a Merkle trie structure is useful in Ethereum because it allows for a distinction between the two types of nodes: full nodes and light nodes.
The Ethereum state is distributed over nodes.
Full nodes download a full copy of the entire blockchain, from genesis block down to current block, with each node in each Merkle trie structure, from root node to leaf node. Miners typically carry full nodes because they have to execute and verify every single transaction.
It's not necessary to have a full copy of the entire blockchain unless you need to execute every transaction or look at historical data, so we have light nodes. Light nodes only download the chain of headers, from genesis block to current block. They do not execute any transactions. The headers contain the root node for each trie, so they are still able to verify transactions even though they don't. This works because each root node was formed from hashes of its child nodes. If a bad agent tries to make a change in a leaf nodes, it will reflect in the intermediate node and the root node.
Question: I'd like to find some real examples where someone would use full nodes vs. light nodes and vice versa. Would also like to better understand the pros and cons of using either.
To verify data, any node can use a Merkle proof. Merkle proof consists of:
- chunk of data and its hash
- root hash of the tree
- branch of hashes from root to chunk
Overall, the Merkle trie structure is useful because the root node is cryptographically derived from the data stored in the tree. Therefore, the root node hash can be used to identify the data. Because the block header contains the root hashes for the state, transactions, and receipts tries, any node can verify a small piece of the Ethereum state without having to download and store the entire state.
## Gas and payment
Every computation made as a result of a transaction sent on the Ethereum network incurs fees. These fees are paid in denominations of gas.
When sending a transaction, the sender designates a gas price and a gas limit. Gas price is the amount of Ether the sender is willing to pay for each unit of gas, and is measured in gwei. One gwei is 1,000,000,000 Wei. Wei is the smallest unit of Ether. 1e18 Wei is equal to 1 Ether.
So a sender can set a gas limit of 50,000 and a price of 20 gwei. The amount allotted for gas would then be 50,000 x 20 = 1,000,000 gwei, which would be 1,000,000,000,000,000 Wei, or 1e15 Wei, which would be equal to 0.001 Ether.
> Question: Does it makes a difference if the user sets a gas limit of 20,000 and a price of 50 gwei? Ether amount would be the same, but I'm not sure how the gas units are consumed and what difference the unit price makes if the overall amount allotted for gas is the same.
The gas set by the sender is the maximum amount of gas that can be used. When the transaction is sent, the miners complete the computation needed for the transaction, consuming gas. If the sender has enough ETH in their account and has set a high enough amount of gas to fulfill the processing needs to complete the transaction, the transaction succeeds. The sender will be refunded any unused gas.
If the sender has not allotted enough gas for the transaction, the miner will consume all the gas and the transaction will fail when gas runs out. The sender will not be refunded gas for the failed transaction because the miner already expended effort for computation related to the transaction. Any state changes are reverted back to the original state and the failed transaction is recorded.
Gas is awarded to the beneficiary address (typically the address of the miner that picks up the transaction). The higher the gas the sender is willing to pay, the miners are more incentivized to select that sender's transaction.
In addition to the processing power required for computation, gas fees are also required for using storage. Remember that all transactions are stored on every full node of the Ethereum network. It's in the network's best interests to keep the stored data minimal. Therefore, clearing an entry in the network waives the fee incurred for clearing that entry, and gives a refund for the storage space that was freed.
Because computation on the Ethereum network is expensive, smart contracts are best used for applications that are not data-intensive, such as executing simple business logic and verifying signatures. More data intensive applications such as email, file storage, and streaming media would have exorbitant fees and are not suitable at this time. The gas fees disincentivize overwhelming the network.
> Observation: You can observe this in practice by seeing which types of NFT art are fully on chain. Something like this [Cranes](https://cranes.supply) project, for example, is able to be fully on chain (the metadata, the owner information, AND the art, which is in SVG format). Something like [Wanderers](https://wanderers.ai/#/) is way too complex to be fully on chain at this time. For these types of projects, the metadata and owner information might be on chain, but the art itself would be hosted on [IPFS](https://ipfs.io). I would like to write more about this and how it influences the art at some point.
## Transactions and messages
Created: November 10, 2021
Last Modified: November 14, 2021