Ethereum & Smart Contracts: A Developer’s Guide

Transition from Web2 to Web3. Master the EVM, Solidity, and Gas mechanics. Learn to build and deploy secure smart contracts on Ethereum. Start your journey today!

Welcome to the definitive guide on transitioning from traditional web development to the decentralized world of Ethereum. While Bitcoin introduced the world to decentralized digital currency, Ethereum expanded that vision by turning the blockchain into a general-purpose, programmable computer. This course will take you beyond the buzzwords and into the architectural mechanics of the Ethereum Virtual Machine (EVM) and Solidity development.

Overview

Target Audience

This course is designed for:

  • Web2 Developers: Professionals proficient in JavaScript, Python, or Go who want to pivot into Web3.
  • System Architects: Engineers looking to understand distributed state machines.
  • Technical Product Managers: Leaders who need to understand the constraints and capabilities of smart contracts.

Key Takeaways

By the end of this module, you will understand:

  1. The architecture of the EVM and how it differs from traditional server environments.
  2. The lifecycle of a transaction and the mechanics of Gas.
  3. How to write, compile, and deploy a basic Smart Contract using Solidity.
  4. Security best practices for immutable code.

1. The Ethereum Virtual Machine (EVM)

Ethereum is often described as a “World Computer.” Unlike a distributed ledger that only tracks balances (like Bitcoin), Ethereum maintains a state that can be updated through arbitrary computer code. The environment in which this code lives and executes is the Ethereum Virtual Machine.

The Concept of State

At any given block height, Ethereum has a single canonical “state.” This state includes accounts, balances, and machine state (storage). The EVM is the engine that computes a new valid state from the old state and a set of new transactions.

Expert Insight: “Think of the EVM not as a computer that sits on a desk, but as a mathematical function: Y(S, T) = S’. Given the old State (S) and a set of Transactions (T), the EVM produces a deterministic new State (S’).”

Accounts: EOA vs. Contract Accounts

There are two types of accounts in Ethereum, and understanding the difference is crucial:

  1. Externally Owned Accounts (EOAs): Controlled by private keys (users). They have no code.
  2. Contract Accounts: Controlled by their contract code. They have code and internal storage.

Practical Application: Reading State with Ethers.js

Before writing contracts, let’s look at how to read the current state of the blockchain using a JavaScript library. We will query the balance of the Ethereum Foundation.

// Using ethers.js to query the blockchain
const { ethers } = require("ethers");

// Connect to a mainnet provider (e.g., Infura, Alchemy, or public RPC)
const provider = new ethers.providers.JsonRpcProvider("https://eth.public-rpc.com");

async function getBalance() {
    const address = "0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe"; // Eth Foundation
    const balance = await provider.getBalance(address);

    // Convert from Wei (smallest unit) to Ether
    console.log(`Balance: ${ethers.utils.formatEther(balance)} ETH`);
}

getBalance();

2. Smart Contracts: The Logic Layer

A smart contract is a program that runs on the Ethereum blockchain. It is a collection of code (its functions) and data (its state) that resides at a specific address on the Ethereum blockchain.

Immutability and “Code is Law”

Once a contract is deployed, its code cannot be changed. This provides trust (no one can secretly change the rules), but it also creates high stakes for security.

Security Warning: “In Web2, if you ship a bug, you patch it later. In Web3, if you ship a bug, you might lose millions of dollars instantly. Audit twice, deploy once.”

Solidity Basics

Solidity is the primary language for Ethereum. It is statically typed, supports inheritance, and looks somewhat similar to JavaScript and C++.

Practical Application: The “Hello World” of Storage

Let’s write a contract that simply stores a number. This demonstrates the persistence of data on the blockchain.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SimpleStorage {
    // State variable to store a number
    // This data is written to the blockchain permanently
    uint256 private storedData;

    // Event to emit when value changes (useful for front-end listeners)
    event DataChanged(uint256 newValue);

    // Function to write data
    function set(uint256 x) public {
        storedData = x;
        emit DataChanged(x);
    }

    // Function to read data
    // 'view' means it does not modify state (free to call externally)
    function get() public view returns (uint256) {
        return storedData;
    }
}

3. Gas and Execution Costs

Because the EVM is a shared global resource, computation is not free. To prevent infinite loops (the Halting Problem) and spam, every operation requires a fee called Gas.

Understanding Gas Mechanics

  • Gas Limit: The maximum amount of gas you are willing to consume for a transaction.
  • Gas Price (Base Fee + Priority Fee): The amount of Ether you are willing to pay per unit of gas.

Key Concept: Operations that write to storage (SSTORE) are the most expensive operations in the EVM because they increase the size of the global blockchain database. Reading data is generally cheap or free.

Case Study: The Cost of Optimization

Consider two ways to loop through an array. In standard programming, the difference is negligible. In Solidity, it costs money.

// Expensive Loop
// Reading 'array.length' from storage on every iteration costs extra gas
function sumArrayExpensive(uint[] memory array) public pure returns (uint) {
    uint sum = 0;
    for (uint i = 0; i < array.length; i++) {
        sum += array[i];
    }
    return sum;
}

// Optimized Loop
// Caching the length in memory saves gas
function sumArrayCheap(uint[] memory array) public pure returns (uint) {
    uint sum = 0;
    uint len = array.length;
    for (uint i = 0; i < len; i++) {
        sum += array[i];
    }
    return sum;
}

4. Development Environment & Tooling

You cannot effectively develop smart contracts in a simple text editor. You need a suite of tools to compile, test, and deploy.

The Modern Stack

  1. Hardhat / Foundry: Development environments for compiling, testing, and deploying.
  2. Metamask: The browser wallet acts as a bridge between your browser and the blockchain.
  3. Etherscan: A block explorer to verify and view your contracts.

Practical Application: Setting up a Hardhat Project

To start a professional environment, follow these bash commands:

# Initialize a Node.js project
npm init -y

# Install Hardhat
npm install --save-dev hardhat

# Initialize the Hardhat environment
npx hardhat init
# Select "Create a JavaScript Object"

Capstone Project: The Decentralized Bank

For your final challenge, you will create a Bank contract. This contract must allow users to deposit Ether, track their individual balances, and withdraw their funds.

Requirements

  1. Use a mapping to track balances.
  2. Use msg.sender to identify the caller.
  3. Use msg.value to handle incoming Ether.
  4. Implement a withdraw function with checks to prevent overdrawing.

Solution

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract DecentralizedBank {
    // Mapping key: User Address -> Value: Balance in Wei
    mapping(address => uint256) private balances;

    // Event logs for transparency
    event Deposit(address indexed user, uint256 amount);
    event Withdrawal(address indexed user, uint256 amount);

    // Allows the contract to receive Ether
    function deposit() public payable {
        require(msg.value > 0, "Deposit amount must be greater than 0");

        // Update balance
        balances[msg.sender] += msg.value;

        emit Deposit(msg.sender, msg.value);
    }

    // Allows users to withdraw their funds
    function withdraw(uint256 amount) public {
        require(amount > 0, "Withdraw amount must be greater than 0");
        require(balances[msg.sender] >= amount, "Insufficient balance");

        // Optimistic accounting: Deduct balance BEFORE sending ether
        // This protects against Re-entrancy attacks
        balances[msg.sender] -= amount;

        // Transfer funds
        (bool success, ) = payable(msg.sender).call{value: amount}("");
        require(success, "Transfer failed");

        emit Withdrawal(msg.sender, amount);
    }

    // Helper to check your own balance
    function getMyBalance() public view returns (uint256) {
        return balances[msg.sender];
    }
}

Pro Tip: Notice the withdraw function logic. We deduct the balance before sending the Ether. This is a critical pattern known as “Checks-Effects-Interactions” to prevent re-entrancy attacks, one of the most common hacks in DeFi history.


Conclusion

Congratulations! You have taken the first steps into the world of programmable blockchains. You’ve learned that Ethereum is a state machine driven by transactions, that Gas forces us to write efficient code, and that Smart Contracts are powerful but require rigorous security practices.

The next steps in your journey involve exploring ERC-20 tokens (currencies), ERC-721 (NFTs), and diving deeper into security tools like Slither and MythX. The blockchain is open, permissionless, and waiting for you to build the next generation of decentralized applications.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top