Level: Beginner | Duration: 2 hoursPrerequisites: Basic programming knowledge (any language)
Overview
This module provides a comprehensive refresher on Solidity fundamentals required before diving into Fully Homomorphic Encryption on the EVM. You will revisit core data types, contract patterns, the ERC-20 standard, and Hardhat testing workflows. By the end of this module you should feel confident reading and writing standard Solidity smart contracts.Learning Objectives
By completing this module you will be able to:- Declare and use Solidity value types (
uint,address,bool) and reference types (string,bytes) - Define and interact with mappings and structs
- Emit events and understand their role in off-chain indexing
- Write custom modifiers for access control (
onlyOwner) - Use
msg.sender,require, andrevertfor input validation - Describe the ERC-20 token standard interface and its core functions
- Write and run basic Hardhat tests using ethers.js and Chai
1. Solidity Data Types
Solidity is a statically-typed language. Every variable must have its type declared at compile time.Value Types
Value types are passed by value — when you assign them to a new variable or pass them to a function, a copy is made.Use
uint256 unless you have a specific reason to use a smaller size. The EVM operates on 256-bit words natively.Reference Types
Type Comparison Table
| Type | Size | Default Value | Example |
|---|---|---|---|
uint256 | 32 bytes | 0 | uint256 x = 42; |
bool | 1 byte | false | bool ok = true; |
address | 20 bytes | 0x0...0 | address a = msg.sender; |
string | dynamic | "" | string s = "hello"; |
bytes32 | 32 bytes | 0x0...0 | bytes32 h = keccak256(...); |
2. Mappings & Structs
Mappings
A mapping is a key-value store. It is the most gas-efficient way to look up data by a key.Mappings cannot be iterated, have no length, and all possible keys exist (unmapped keys return the default value).
Structs
Combining Mappings and Structs
3. Events & Emit
Events are the mechanism by which smart contracts communicate with the outside world. When emitted, events write data to the transaction log.Declaring and Emitting Events
The
indexed keyword allows filtering on that parameter when querying logs. You may index up to three parameters per event.Why Events Matter
- Off-chain indexing: Services like The Graph index events to build queryable APIs
- Debugging: Events appear in transaction receipts and are visible in block explorers
- Cost: Events are much cheaper than storage writes (~375 gas for the topic + 8 gas per byte)
4. Modifiers & Access Control
Modifiers allow you to attach reusable preconditions to functions.The onlyOwner Pattern
5. msg.sender, require, revert
msg.sender
msg.sender is a global variable that holds the address of the account (or contract) that directly called the current function.
require
require is used for input validation. If the condition is false, the transaction reverts and any state changes are undone.
revert with Custom Errors
Since Solidity 0.8.4, custom errors provide a gas-efficient alternative torequire with string messages.
| Pattern | Gas Cost | Use When |
|---|---|---|
require(cond, "msg") | Higher (stores string) | Quick checks, readability |
if (!cond) revert CustomError() | Lower | Production contracts |
6. ERC-20 Standard Overview
ERC-20 is the most widely adopted token standard on Ethereum. It defines a common interface that all fungible tokens implement.Interface
Minimal Implementation
Key Concepts
Understanding decimals
Understanding decimals
Most tokens use 18 decimals. USDC uses 6. Always check the decimals of a token before performing arithmetic.For a token with 18 decimals:
- 1 token =
1 * 10^18base units - 0.5 tokens =
500000000000000000base units
Approve/TransferFrom pattern
Approve/TransferFrom pattern
Allows contracts (like DEXs) to spend tokens on behalf of the owner:
- Owner calls
approve(spender, amount) - Spender calls
transferFrom(owner, recipient, amount)
Zero-address checks
Zero-address checks
Production code should check that
to != address(0) to prevent accidental token burns.7. Hardhat Testing Basics
Hardhat is the most popular Solidity development framework. It provides a local EVM environment, compilation, deployment scripting, and a testing framework.Project Setup
Writing a Test
test/SimpleToken.test.js
Running Tests
Common Chai Matchers
| Matcher | Description | Example |
|---|---|---|
expect(x).to.equal(y) | Strict equality | expect(balance).to.equal(100n) |
.to.be.revertedWith(msg) | Expects revert | expect(tx).to.be.revertedWith("...") |
.to.emit(contract, event) | Expects event | expect(tx).to.emit(token, "Transfer") |
.to.changeTokenBalance | Checks balance change | expect(tx).to.changeTokenBalance(token, addr, 100) |
Summary
In this module you reviewed the essential Solidity building blocks:- Data types:
uint256,address,bool,string,bytes - Mappings & structs: Primary data structures for on-chain storage
- Events: Cheap, indexable logs for off-chain consumption
- Modifiers: Reusable preconditions (
onlyOwner, custom guards) - Validation:
requireand customreverterrors - ERC-20: The standard fungible token interface
- Hardhat testing: Write, run, and debug tests locally
Next Module: Module 01: Introduction to FHE