Starter Code Template
Copy this into Remix IDE and fill in the TODO sections
How to use this template:
- Open remix.ethereum.org
- Create a new file called
MyToken.sol - Copy the code below and paste it into your file
- Find every
// TODO:comment and implement the described functionality - Compile with Ctrl+S after completing each function
ERC-20 Token Starter Template
MyToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract MyToken {
// ===================================================================
// STATE VARIABLES (provided -- do not modify)
// ===================================================================
string public name; // Token name (e.g., "My Awesome Token")
string public symbol; // Token symbol (e.g., "MAT")
uint8 public decimals = 18; // Number of decimal places
uint256 public totalSupply; // Total tokens in existence
address public owner; // Contract owner (deployer)
// balanceOf[address] = how many tokens that address holds
mapping(address => uint256) public balanceOf;
// allowance[owner][spender] = how many tokens spender can use on behalf of owner
mapping(address => mapping(address => uint256)) public allowance;
// ===================================================================
// EVENTS (provided -- do not modify)
// ===================================================================
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
// ===================================================================
// CONSTRUCTOR
// ===================================================================
// TODO 1: Complete the constructor
// It should:
// - Set the name and symbol from the parameters
// - Set the owner to msg.sender
// - Set totalSupply to _initialSupply
// - Give all initial tokens to msg.sender (set their balanceOf)
constructor(string memory _name, string memory _symbol, uint256 _initialSupply) {
// YOUR CODE HERE
}
// ===================================================================
// CORE FUNCTIONS
// ===================================================================
// TODO 2: Implement the transfer function
// It should:
// - Check that the sender has enough tokens (use require)
// - Subtract _amount from the sender's balance
// - Add _amount to the recipient's balance
// - Emit a Transfer event
// - Return true
function transfer(address _to, uint256 _amount) public returns (bool) {
// YOUR CODE HERE
}
// TODO 3: Implement the approve function
// It should:
// - Set allowance[msg.sender][_spender] to _amount
// - Emit an Approval event
// - Return true
function approve(address _spender, uint256 _amount) public returns (bool) {
// YOUR CODE HERE
}
// TODO 4: Implement the transferFrom function
// It should:
// - Check that _from has enough tokens (use require)
// - Check that msg.sender has enough allowance (use require)
// - Subtract _amount from _from's balance
// - Add _amount to _to's balance
// - Decrease the allowance by _amount
// - Emit a Transfer event
// - Return true
function transferFrom(address _from, address _to, uint256 _amount) public returns (bool) {
// YOUR CODE HERE
}
// ===================================================================
// CUSTOM FEATURE (choose at least one)
// ===================================================================
// TODO 5: Choose ONE (or more!) of the features below and implement it.
// Delete or keep the options you don't use.
// --- Option A: BURN ---
// Lets any token holder destroy their own tokens.
// Steps:
// - Check sender has enough tokens (require)
// - Subtract _amount from sender's balance
// - Subtract _amount from totalSupply
// - Emit a Transfer event to address(0) (convention for burns)
// function burn(uint256 _amount) public {
// // YOUR CODE HERE
// }
// --- Option B: MINT ---
// Lets ONLY the owner create new tokens.
// Steps:
// - Check that msg.sender == owner (require)
// - Add _amount to _to's balance
// - Add _amount to totalSupply
// - Emit a Transfer event from address(0)
// function mint(address _to, uint256 _amount) public {
// // YOUR CODE HERE
// }
// --- Option C: PAUSE ---
// Lets the owner pause and unpause all transfers.
// Steps:
// - Add a bool public paused; state variable (at the top)
// - Add require(!paused, "Paused") to transfer() and transferFrom()
// - Create pause() and unpause() functions restricted to owner
// bool public paused;
//
// function pause() public {
// // YOUR CODE HERE
// }
//
// function unpause() public {
// // YOUR CODE HERE
// }
}
What to Do After Pasting
- Read through the entire file -- understand the structure before writing code
- Complete TODO 1 (constructor) -- this is 4 lines of code
- Compile (Ctrl+S) -- should compile with no errors
- Complete TODO 2 (transfer) -- this is 5 lines of code
- Compile again -- fix any errors before moving on
- Complete TODO 3 (approve) -- this is 3 lines of code
- Complete TODO 4 (transferFrom) -- this is 7 lines of code
- Deploy and test -- make sure basic functions work
- Complete TODO 5 -- uncomment your chosen feature and implement it
Remember:
- Every line of code you write was demonstrated in Lesson 10 slides
- If you get stuck, re-read the TODO comment -- it tells you exactly what to do
- Compile after every function, not at the end
- The starter code already provides all state variables, events, and function signatures -- you only need to write the function bodies
Quick Reference
| Pattern | Solidity Code |
|---|---|
| Check a condition | require(condition, "Error message"); |
| Subtract from a mapping | balanceOf[addr] -= amount; |
| Add to a mapping | balanceOf[addr] += amount; |
| Set a mapping value | allowance[owner][spender] = amount; |
| Emit an event | emit Transfer(from, to, value); |
| Return a value | return true; |
| Check ownership | require(msg.sender == owner, "Not owner"); |
© Joerg Osterrieder 2025-2026. All rights reserved.