In Part 2 of this blockchain series, we looked at a blockchain platform called Ethereum, and the reasons that led to its development. The most important being Ethereum provides the ability for regular developers to build trustless applications of arbitrary complexity without being bogged down by the details of how everything under the hood is working.
In essence, the platform abstracts the underlying blockchain’s complexity and lets people manipulate the blockchain via a high level programming language.
As I often do, In my quest to understand the platform better, I decided to actually build something on top of the Ethereum blockchain, and in the process learn the mechanics of it. Turned out it wasn’t such a good idea this time — I had trouble setting up the environment and understanding why certain things were happening the way they were.
I went back and forth on the documentation and Stack Overflow searches, and was finally able to get it to work and now believe it is a good idea to have an understanding of key aspects of the platform, learn some important concepts and then dive into the code. That is what this post is about.
Before we begin, almost whatever I am going to write is inspired from the Ethereum Documentation. All credits to them.
Alright, lets begin.
Ethereum Platform has 2 building blocks
1. Ethereum Virtual Machine
To build cool, trustless applications, Ethereum provides user friendly languages that can run on a “Virtual Machine” — called an Ethereum Virtual Machine (EVM). Simply put, a virtual machine is a software that can understand a set of instructions and execute them in some logical order, just like a real computer does. Its not important to get into the weeds here, but here is the 30,000 feet explanation:
When you use Ethereum’s programming language to build a smart contract or any other application, the EVM compiler takes that code, resolves it into lower level machine instructions for the Ethereum Virtual Machine to understand , process and execute.
2. Peer-to-Peer Network Protocol
The underlying network consists of nodes or computers connected in a decentralized , peer to peer network. Each node runs an EVM, and processes the same instructions to ensure that consensus is achieved on any particular transaction.
How the thing works
As I briefly discussed in my last post, bitcoin is transaction centric and largely stateless and that makes it difficult to build real world applications where you’d like to track a state of a particular transaction across multiple stages of a contract.
Ethereum on the other hand is built on the concept of accounts, it tracks all input and output transactions to and from accounts and this ability to track the flow of information in and out of accounts makes it stateful and valuable.
There are two types of accounts in Ethereum:
The graphic above is self explanatory, but to reiterate — if you wanted to participate in the Ethereum ecosystem, you’d have a user account and the keys to operate that account. These accounts are called Externally Owned Accounts (EOAs)in Ethereum. Once you have an EOA, you can make transactions with others accounts as well as to another type of account — known as Contract Accounts.
Accounts contain Ether
Ether is the crypto-fuel of the Ethereum network. Ether is also the incentive for miners to validate and mine Ethereum blocks on the blockchain. Ether is to the Ethereum network, what bitcoin is to the Bitcoin Blockchain network.
Developers who intend to build apps that will use the ethereum blockchain need Ether, as it is used to pay for computation within the EVM (explained below). Users who want to access and interact with smart contracts on the ethereum blockchain also need ether for the same reason.
Ether has certain denominations that are helpful to know.The smallest denomination aka base unit of ether is called Wei.
1 ether = 1×10¹⁸ Wei.
Finally, in order to obtain Ether, you need to either become an Ethereum miner, or trade other currencies for ether using centralized or trustless services.
But, what if you don’t have ether, but want to build and test distributed apps?
Ethereum platform enables a user to set up a “private” or “testnet” Ethereum chain that is separate from the main Ethereum blockchain. This is useful for testing distributed apps built on Ethereum without having to expose your apps or trials to the real Ethereum network using real Ether.
(I will show how to set up a private ethereum blockchain and two nodes in my next post!)
A Contract Account contains code to execute a particular function that it was designed for, and this code ‘lives’ on the Ethereum blockchain . Once a contract account is triggered — either by an Externally Owned Account or by another contract account — the code inside is executed by the Ethereum Virtual Machine(EVM) on each participating node. These accounts also enable “Smart Contracts”.
What is a Smart Contract?
Smart contracts are contract accounts that facilitate exchange of value in a transparent and trustless way without the need for middlemen. Here are the high level steps to create a Smart Contract:
- A contract account with rules (and specified actions based on those rules) is created. e.g. “If this is true, then do that”
- Once deployed, the contract gets a public key address, that can be used to reach the contract and trigger its code execution.
- Also, once a smart contract is deployed to the Ethereum blockchain, it cannot be changed even by the EOA that created it.
A simple example of a smart contract would be sort of an escrow account without any third party involved. Two parties can agree on a set of rules for fund disbursement, create and code a contract and deploy it on the Ethereum Blockchain. As soon as the criteria/rules for disbursing funds are met, the contract can disburse out the funds to the appropriate parties.
Here is a more detailed explanation on smart contracts, but the bottom line is that Smart Contracts are code that is deployed on the Ethereum blockchain, and this code runs on every single node connected to the Ethereum network.
How do accounts transact on the Ethereum Blockchain?
The Ethereum environment, by default is pretty un-happening. Until a user triggers an action by sending a transaction from an EOA, nothing really happens. However, once the user triggers a transaction on the Ethereum, the network springs into action.
The destination of such a transaction can be another EOA, or a Contract Account. The transaction to an EOA might simply be an ether transfer, in which case ether balances will be adjusted for both accounts. If on the other hand, destination of the transaction is a Contract Account, the contract’s code will be executed automatically.
A Transaction is a validated packet that a user account (or EOA) sends to another user account. Such a packet will typically contain
- The address of the recipient of the message
- A signature of sender that proves that they own the account
VALUEfield – The amount of ether to transfer from the sender to the recipient. Ether is the fuel that drives the
- an optional data field, which could be an arbitrary message or function call to a contract or even code to create a contract. As an example, imagine a crop insurance smart contract that releases compensation depending upon rainfall statistics in a particular area, this optional data field can then be used to feed rainfall stats to the contract.
In addition to the attributes mentioned above, transactions must mention the maximum number of computational steps, storage and bandwidth consumption expected with the its execution, and pay for it in ether.
Ethereum, Gas & Fees
So far, we haven’t really talked about the concept of Gas in Ethereum, but it is central to how transactions work, and how miners are incentivized to validate blocks in the Ethereum blockchain.
Gas is Ethereum’s metering scheme and it accounts for bandwidth used, cost of storage and cost of computation on the Ethereum blockchain.
Every computational operation in the EVM consumes gas, and different computations e.g. addition or multiplication consumes different amount of gas. Here is a list of gas consumption for different operations and computations.
All operations during transaction execution, including database reads and writes, messages, and every computational step taken by the virtual machine consumes a certain quantity of gas. Therefore, for every transaction that is originated, the following must happen to ensure that ‘denial-of-service’ attacks on the network can be prevented and that miners receive the reward for adding a transaction to the block. (source)
- Every transaction must specify a quantity of “gas” that it is willing to consume (called
startgas) to cover its use of the EVM’s computation and any storage or bandwidth used. (Unfortunately its pretty difficult to know how much compute a transaction might need, and therefore specify a
startgasvalue — here is a spreadsheet that will help. Additionally, there are certain APIs to see how much gas should be specified for a transaction, before creating the transaction such as
web3.eth.estimateGasand JSON-RPC estimateGas . This works by pretending the transaction was actually being included in the blockchain, and then returning the exact gas amount that would have been charged if that pretend operation was real — but there are caveats to using this API.)
- Transaction sender must also mention the fee that it is willing to pay per unit gas (
gasprice). At the start of execution,
startgas * gaspriceether are removed from the transaction sender’s account.This is done to ensure the miner receives the fee even if the user account is bankrupted midway during execution.
- If a transaction execution processes fully, consuming less gas than its specified limit, say with gas remaining (
gas_rem), then the transaction executes normally, and at the end of the execution the transaction sender receives a refund of
gas_rem * gaspriceand the miner of the block receives a reward of
(startgas - gas_rem) * gasprice. As mentioned earlier, this ‘miner fee’ is set aside right at the beginning of the transaction
- If a transaction “runs out of gas” mid-execution, then all execution reverts, but the transaction is nevertheless valid, and the only effect of the transaction is to transfer the entire sum
startgas * gaspriceto the miner.
All of this gas business is to make sure that a malicious node or hacker cannot simply load the Ethereum network with malicious transactions (such that an infinite loop) without incurring a cost that is too expensive.
How do Contracts transact on the Ethereum Blockchain?
Contracts talk to other contracts through messages. A message is similar to a transaction, except it is produced only by a contract account, not by an EOA (Externally Owned Account). A message contains the following attributes
- the address of the contract sending the message
- the address of recipient contract
- the amount of ether to transfer alongside the message
- an optional data field; and
Since a message is sent from one contract to another, a message results in the recipient contract running its code. In sum, contracts can have relationships with other contracts in the same way EOAs can.