Understand the ERC-20 token smart contract
One of the most significant smart contract standards on Ethereum is known as ERC-20, which has emerged as the technical standard used for all smart contracts on the Ethereum blockchain for fungible token implementations.
ERC-20 defines a common list of rules that all fungible Ethereum tokens should adhere to. Consequently, this token standard empowers developers of all types to accurately predict how new tokens will function within the larger Ethereum system. This simplifies and eases developers’ tasks, because they can proceed with their work, knowing that each and every new project won’t need to be redone every time a new token is released, as long as the token follows the rules.
Here is, presented as an interface, the functions an ERC-20 must implement. If you’re not sure about what is an interface: check our article about OOP programming in Solidityopens in a new tab.
1pragmasolidity^0.6.0;23interfaceIERC20{45functiontotalSupply()externalviewreturns(uint256);6functionbalanceOf(address account)externalviewreturns(uint256);7functionallowance(address owner,address spender)externalviewreturns(uint256);89functiontransfer(address recipient,uint256 amount)externalreturns(bool);10functionapprove(address spender,uint256 amount)externalreturns(bool);11functiontransferFrom(address sender,address recipient,uint256 amount)externalreturns(bool);121314eventTransfer(addressindexedfrom,addressindexed to,uint256 value);15eventApproval(addressindexed owner,addressindexed spender,uint256 value);16}Show all
Here is a line-by-line explainer of what every function is for. After this we’ll present a simple implementation of the ERC-20 token.
Getters
1functiontotalSupply()externalviewreturns(uint256);
Returns the amount of tokens in existence. This function is a getter and does not modify the state of the contract. Keep in mind that there are no floats in Solidity. Therefore most tokens adopt 18 decimals and will return the total supply and other results as followed 1000000000000000000 for 1 token. Not every token has 18 decimals and this is something you really need to watch for when dealing with tokens.
1functionbalanceOf(address account)externalviewreturns(uint256);
Returns the amount of tokens owned by an address (account). This function is a getter and does not modify the state of the contract.
1functionallowance(address owner,address spender)externalviewreturns(uint256);
The ERC-20 standard allows an address to give an allowance to another address to be able to retrieve tokens from it. This getter returns the remaining number of tokens that the spender will be allowed to spend on behalf of owner. This function is a getter and does not modify the state of the contract and should return 0 by default.
Functions
1functiontransfer(address recipient,uint256 amount)externalreturns(bool);
Moves the amount of tokens from the function caller address (msg.sender) to the recipient address. This function emits the Transfer event defined later. It returns true if the transfer was possible.
1functionapprove(address spender,uint256 amount)externalreturns(bool);
Set the amount of allowance the spender is allowed to transfer from the function caller (msg.sender) balance. This function emits the Approval event. The function returns whether the allowance was successfully set.
1functiontransferFrom(address sender,address recipient,uint256 amount)externalreturns(bool);
Moves the amount of tokens from sender to recipient using the allowance mechanism. amount is then deducted from the caller’s allowance. This function emits the Transfer event.
Events
1eventTransfer(addressindexedfrom,addressindexed to,uint256 value);
This event is emitted when the amount of tokens (value) is sent from the from address to the to address.
In the case of minting new tokens, the transfer is usually from the 0x00..0000 address while in the case of burning tokens the transfer is to 0x00..0000.
1eventApproval(addressindexed owner,addressindexed spender,uint256 value);
This event is emitted when the amount of tokens (value) is approved by the owner to be used by the spender.
A basic implementation of ERC-20 tokens
Here is the most simple code to base your ERC-20 token from:
1pragmasolidity^0.8.0;23interfaceIERC20{45functiontotalSupply()externalviewreturns(uint256);6functionbalanceOf(address account)externalviewreturns(uint256);7functionallowance(address owner,address spender)externalviewreturns(uint256);89functiontransfer(address recipient,uint256 amount)externalreturns(bool);10functionapprove(address spender,uint256 amount)externalreturns(bool);11functiontransferFrom(address sender,address recipient,uint256 amount)externalreturns(bool);121314eventTransfer(addressindexedfrom,addressindexed to,uint256 value);15eventApproval(addressindexed owner,addressindexed spender,uint256 value);16}171819contractERC20Basicis IERC20 {2021stringpublicconstant name ="ERC20Basic";22stringpublicconstant symbol ="ERC";23uint8publicconstant decimals =18;242526mapping(address=>uint256) balances;2728mapping(address=>mapping(address=>uint256)) allowed;2930uint256 totalSupply_ =10 ether;313233constructor(){34 balances[msg.sender]= totalSupply_;35}3637functiontotalSupply()public override viewreturns(uint256){38return totalSupply_;39}4041functionbalanceOf(address tokenOwner)public override viewreturns(uint256){42return balances[tokenOwner];43}4445functiontransfer(address receiver,uint256 numTokens)public override returns(bool){46require(numTokens <= balances[msg.sender]);47 balances[msg.sender]= balances[msg.sender]-numTokens;48 balances[receiver]= balances[receiver]+numTokens;49emitTransfer(msg.sender, receiver, numTokens);50returntrue;51}5253functionapprove(address delegate,uint256 numTokens)public override returns(bool){54 allowed[msg.sender][delegate]= numTokens;55emitApproval(msg.sender, delegate, numTokens);56returntrue;57}5859functionallowance(address owner,address delegate)public override viewreturns(uint){60return allowed[owner][delegate];61}6263functiontransferFrom(address owner,address buyer,uint256 numTokens)public override returns(bool){64require(numTokens <= balances[owner]);65require(numTokens <= allowed[owner][msg.sender]);6667 balances[owner]= balances[owner]-numTokens;68 allowed[owner][msg.sender]= allowed[owner][msg.sender]-numTokens;69 balances[buyer]= balances[buyer]+numTokens;70emitTransfer(owner, buyer, numTokens);71returntrue;72}73}Show all
Another excellent implementation of the ERC-20 token standard is the OpenZeppelin ERC-20 implementationopens in a new tab.
Page last update: August 21, 2025