Smart Contract Overview — Solidity 0.8.18 Guide

·

Smart contracts are self-executing programs that run on blockchain networks like Ethereum. Written in languages such as Solidity, they automate trustless interactions by enforcing predefined rules without intermediaries. This guide explores the fundamentals of smart contracts using Solidity 0.8.18, covering core concepts, code examples, and the underlying mechanics of the Ethereum Virtual Machine (EVM).


Understanding Simple Smart Contracts

Let’s begin with a foundational example: a contract that stores a value and allows other contracts to read or modify it.

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

contract SimpleStorage {
    uint storedData;

    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}

The first line specifies the license under which the source code is released—GPL-3.0—ensuring transparency and compliance for open-source use.

The pragma solidity directive defines version compatibility. Here, the code supports Solidity versions from 0.4.16 up to, but not including, 0.9.0. This prevents unexpected behavior due to breaking changes in future compiler versions.

In Solidity, a contract encapsulates both code (functions) and data (state). The line uint storedData; declares a state variable of type uint—an unsigned 256-bit integer—persisted on the blockchain. Think of it as a database field accessible only through controlled functions.

The set and get functions allow external users to update and retrieve this value. Notably, within a contract, you access members directly—without needing this.—as omitting it affects scoping and execution context.

While simple, this contract demonstrates key blockchain traits: immutability (past values remain in history), transparency (anyone can read), and openness (anyone can overwrite). Later, we’ll explore access controls to restrict modifications.

Tip: Be cautious with Unicode characters—even visually identical ones may differ in encoding, leading to vulnerabilities.

Building a Custom Cryptocurrency

Now let’s create a more complex contract: a basic cryptocurrency.

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;

contract Coin {
    address public minter;
    mapping(address => uint) public balances;

    event Sent(address from, address to, uint amount);

    constructor() {
        minter = msg.sender;
    }

    function mint(address receiver, uint amount) public {
        require(msg.sender == minter);
        balances[receiver] += amount;
    }

    error InsufficientBalance(uint requested, uint available);

    function send(address receiver, uint amount) public {
        if (amount > balances[msg.sender])
            revert InsufficientBalance({
                requested: amount,
                available: balances[msg.sender]
            });

        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        emit Sent(msg.sender, receiver, amount);
    }
}

Key Concepts Explained

👉 Discover how to deploy and interact with token contracts securely.


Blockchain Fundamentals for Developers

Blockchain may seem complex, but developers need only understand its guarantees—not its cryptography or networking layers.

Transactions and Consistency

A blockchain is a shared transactional ledger. Every change must be packaged into a transaction, ensuring atomicity: either all operations succeed or none do.

For instance, transferring tokens deducts from one balance and credits another—both happen or neither does. Transactions are also isolated; concurrent writes don’t interfere.

Each transaction is signed cryptographically, proving ownership without passwords—only private keys.

Blocks and Finality

To prevent double-spending, transactions are grouped into blocks every ~17 seconds on Ethereum. Conflicting transactions are resolved by consensus: only the first included transaction wins.

Blocks form a chain; reorganizations (reorgs) can roll back recent blocks, though probability decreases rapidly with each new block added.

Note: There’s no guarantee your transaction will appear in the next block—it depends on miner selection and gas fees.

👉 Learn how to optimize transaction speed and cost on Ethereum.


The Ethereum Virtual Machine (EVM)

The EVM executes smart contracts in a secure, sandboxed environment isolated from network and system resources.

Accounts

There are two account types:

Both share an address space and hold ether balances (in wei: 1 ether = 10¹⁸ wei). Contract addresses are derived from the creator’s address and nonce (transaction count).

Storage, Memory, and Stack

The EVM uses three data areas:

Gas and Execution Costs

Every operation consumes gas, paid by the transaction sender. Gas prevents infinite loops and compensates validators.


Advanced EVM Features

Message Calls

Contracts interact via message calls, similar to transactions but internal. These are synchronous and return data. Failed calls propagate errors unless explicitly handled.

Delegatecall and Libraries

Delegatecall executes code from another address in the caller’s context—preserving storage, balance, and address. This enables reusable libraries (e.g., math or data structures) shared across contracts.

Logs and Events

Events write to an append-only log structure searchable via bloom filters—ideal for lightweight clients tracking activity without syncing full blockchain data.

Contract Creation and Self-Destruct

Contracts can create others using create, where initialization code returns runtime bytecode.

selfdestruct removes contract code and sends remaining funds to a target. However:

Use logical deactivation (e.g., pausing functions via a paused flag) instead of self-destruct for safer upgrades.

Frequently Asked Questions

Q: What is Solidity?
A: Solidity is a statically-typed programming language designed for writing smart contracts on Ethereum and EVM-compatible blockchains.

Q: How do I make my contract upgradeable?
A: Use proxy patterns with delegatecall to separate logic from storage, enabling updates without redeploying.

Q: Why use events instead of storage for tracking?
A: Events are cheaper to emit and ideal for off-chain monitoring, while storage is costly but readable on-chain.

Q: Can deleted contracts be recovered?
A: No. Once self-destructed, a contract’s functionality is gone—but its history remains part of the blockchain permanently.

Q: How do I prevent reentrancy attacks?
A: Use checks-effects-interactions patterns or reentrancy guards to block recursive calls during sensitive operations.

Q: What tools should I use to test Solidity code?
A: Leverage Hardhat or Foundry for local testing, combined with static analyzers like Slither for security audits.


👉 Start building secure, efficient smart contracts today with advanced developer tools.