The ERC-20 standard defines a common way for tokens on the Ethereum blockchain to work. It makes sure all tokens behave the same, so wallets and apps can use them easily.
ERC-20 fungible token standard in Blockchain / Solidity
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}This is an interface, meaning it only defines functions without code.
All ERC-20 tokens must implement these functions and events exactly.
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);event Transfer(address indexed from, address indexed to, uint256 value);This is a simple ERC-20 token contract. It creates tokens, lets users send tokens, approve others to spend tokens, and transfer tokens on behalf of others.
pragma solidity ^0.8.0; contract SimpleToken { string public name = "SimpleToken"; string public symbol = "SIM"; uint8 public decimals = 18; uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); constructor(uint256 initialSupply) { totalSupply = initialSupply * 10 ** decimals; balanceOf[msg.sender] = totalSupply; emit Transfer(address(0), msg.sender, totalSupply); } function transfer(address to, uint256 amount) public returns (bool) { require(balanceOf[msg.sender] >= amount, "Not enough tokens"); balanceOf[msg.sender] -= amount; balanceOf[to] += amount; emit Transfer(msg.sender, to, amount); return true; } function approve(address spender, uint256 amount) public returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transferFrom(address from, address to, uint256 amount) public returns (bool) { require(balanceOf[from] >= amount, "Not enough tokens"); require(allowance[from][msg.sender] >= amount, "Allowance too low"); balanceOf[from] -= amount; balanceOf[to] += amount; allowance[from][msg.sender] -= amount; emit Transfer(from, to, amount); return true; } }
ERC-20 tokens must emit Transfer events on token moves so wallets can track balances.
Decimals define how divisible the token is; 18 decimals means tokens can be split into very small parts.
Always check for enough balance and allowance before transferring tokens.
ERC-20 is a standard that makes tokens work the same way on Ethereum.
It defines functions to check balances, send tokens, and approve spending.
Following ERC-20 helps your token work with wallets, exchanges, and apps easily.
Practice
ERC-20 standard in Ethereum?Solution
Step 1: Understand ERC-20 purpose
ERC-20 defines a common interface for fungible tokens to work uniformly.Step 2: Identify the correct purpose
This standard allows wallets and apps to interact with tokens easily by using the same functions.Final Answer:
To ensure tokens have a common set of functions for compatibility -> Option AQuick Check:
ERC-20 = Common token interface [OK]
- Confusing ERC-20 with NFT standards
- Thinking ERC-20 controls Ethereum network rules
- Assuming ERC-20 manages deployment costs
Solution
Step 1: Recall ERC-20 balance function
The standard definesbalanceOfas a view function returning a uint256 balance.Step 2: Match function signature
function balanceOf(address owner) external view returns (uint256); matches the exact signature: external view returns (uint256).Final Answer:
function balanceOf(address owner) external view returns (uint256); -> Option AQuick Check:
balanceOf = correct signature [OK]
- Using wrong function name like getBalance
- Missing view keyword for read-only function
- Returning bool instead of uint256
function transfer(address to, uint256 amount) public returns (bool) {
if (balances[msg.sender] < amount) {
return false;
}
balances[msg.sender] -= amount;
balances[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}What will
transfer return if the sender has 50 tokens and tries to send 60 tokens?Solution
Step 1: Check sender balance condition
The function checks if sender's balance is less than amount; if yes, returns false.Step 2: Apply given values
Sender has 50 tokens but tries to send 60, so condition is true and function returns false.Final Answer:
false -> Option BQuick Check:
Insufficient balance returns false [OK]
- Assuming it throws error instead of returning false
- Thinking it returns true regardless
- Confusing return value with event emission
approve function snippet:function approve(address spender, uint256 amount) public returns (bool) {
allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}What is the common security issue with this implementation?
Solution
Step 1: Understand approve race condition
Directly setting allowance can cause race conditions if spender uses old and new allowance simultaneously.Step 2: Identify missing mitigation
Safe implementations require resetting allowance to zero before changing it to new value to avoid this issue.Final Answer:
It allows race condition by directly setting allowance -> Option CQuick Check:
approve race condition = direct allowance set [OK]
- Thinking missing zero address check is main issue
- Assuming Approval event is missing
- Believing return value is incorrect
transfer function correctly implements this?Solution
Step 1: Calculate fee and net transfer
Calculate 1% fee from amount, subtract it to get net amount to recipient.Step 2: Transfer fee and net amount correctly
Send fee to fee collector address and net amount to recipient to implement fee deduction.Final Answer:
Deduct 1% from amount, send fee to collector, send rest to recipient -> Option DQuick Check:
Fee deducted and sent correctly = Deduct 1% from amount, send fee to collector, send rest to recipient [OK]
- Adding fee on top of amount instead of deducting
- Sending full amount to recipient and fee separately from sender
- Splitting amount equally between recipient and fee collector
Ready to prove it?
Pass the test and this pattern moves unknown
