Starter Code Template

Copy this into Remix IDE and fill in the TODO sections

How to use this template:
  1. Open remix.ethereum.org
  2. Create a new file called MyToken.sol
  3. Copy the code below and paste it into your file
  4. Find every // TODO: comment and implement the described functionality
  5. 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

  1. Read through the entire file -- understand the structure before writing code
  2. Complete TODO 1 (constructor) -- this is 4 lines of code
  3. Compile (Ctrl+S) -- should compile with no errors
  4. Complete TODO 2 (transfer) -- this is 5 lines of code
  5. Compile again -- fix any errors before moving on
  6. Complete TODO 3 (approve) -- this is 3 lines of code
  7. Complete TODO 4 (transferFrom) -- this is 7 lines of code
  8. Deploy and test -- make sure basic functions work
  9. 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.