Understanding the ERC-20 Token Standard
In the previous chapter, we created a simple token contract. However, it only worked within our custom front end for queries and transfers—it wasn’t compatible with real on-chain operations or wallet integrations like MetaMask.
To enable full compatibility, your contract must adhere to the ERC-20 standard. This ensures seamless interaction with wallets and decentralized applications. For instance, when a wallet imports a token contract address, it retrieves the token name, symbol, and balance by calling specific methods defined in the ERC-20 standard. Similarly, transfers are executed by invoking standardized functions.
Core Components of ERC-20
The ERC-20 standard defines six mandatory functions and two events that must be implemented in your smart contract. These elements enable wallets and exchanges to interact uniformly with your token.
Mandatory Functions
totalSupply: Returns the total token supply.
function totalSupply() public view returns (uint256)balanceOf: Returns the token balance of a specified address.
function balanceOf(address _owner) public view returns (uint256 balance)transfer: Transfers tokens from the sender’s address to another address.
function transfer(address _to, uint256 _value) public returns (bool success)transferFrom: Transfers tokens from one address to another, provided the sender has sufficient allowance.
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)approve: Allows a spender to withdraw tokens from the owner’s account up to a specified value.
function approve(address _spender, uint256 _value) public returns (bool success)allowance: Returns the remaining number of tokens that a spender is allowed to withdraw from an owner.
function allowance(address _owner, address _spender) public view returns (uint256 remaining)
Mandatory Events
Transfer: Triggered when tokens are transferred.
event Transfer(address indexed _from, address indexed _to, uint256 _value)Approval: Triggered when an approval occurs.
event Approval(address indexed _owner, address indexed _spender, uint256 _value)
Deploying an ERC-20 Token Using Truffle
To get started, you can use a standardized ERC-20 example from the ConsenSys Tokens repository. This provides a reliable foundation for your token contract.
Setup and Configuration
- Replace the
truffle.jsfile in the Tokens-master project with thetruffle-config.jsfrom your Webpack example to ensure compatibility with Ganache. - Set the Solidity compiler version to
0.4.21in the configuration to match the code requirements. Compile and deploy the contract using the following commands:
truffle compile truffle migrate
After successful deployment, you can import the token contract address into MetaMask to view and transfer tokens.
Importing Tokens into MetaMask
- Open MetaMask and click "Add Token."
- Paste the contract address of your deployed EIP20.sol contract.
- The token details (name, symbol, balance) will automatically populate.
You can now test transfers between addresses to ensure everything works correctly.
Analyzing the ERC-20 Contract Code
Key Variables
The EIP20 contract includes several critical variables:
- MAX_UINT256: A constant representing the maximum value of a 256-bit unsigned integer.
- balances: A mapping that stores token balances for each address.
- allowed: A nested mapping that tracks allowed transfer amounts between addresses.
- name, decimals, symbol: Optional but recommended metadata for displaying token information.
Constructor Function
The constructor initializes the token with essential parameters:
function EIP20(
uint256 _initialAmount,
string _tokenName,
uint8 _decimalUnits,
string _tokenSymbol
) public {
balances[msg.sender] = _initialAmount;
totalSupply = _initialAmount;
name = _tokenName;
decimals = _decimalUnits;
symbol = _tokenSymbol;
}Parameters are passed during deployment via the migration script (e.g., 2_deploy_tokens.js).
Critical Functions Explained
- transfer: Checks the sender’s balance, deducts the transfer amount, and updates the recipient’s balance. Emits a Transfer event.
- transferFrom: Checks allowance and balance before transferring tokens. Adjusts the allowance if necessary and emits a Transfer event.
- approve: Sets the allowance for a spender and emits an Approval event.
- balanceOf and allowance: Provide read-only access to balance and allowance data.
Deploying to a Test Network Using Remix
For broader accessibility, you can deploy your ERC-20 token to a testnet like Sepolia using Remix IDE.
Steps for Remix Deployment
- Switch MetaMask to the Sepolia test network.
- Create a new file in Remix named
EIP20.soland paste your contract code. - Compile the contract using a compatible Solidity version (e.g.,
0.8.2). - Deploy the contract by providing constructor parameters: initial supply, name, decimals, and symbol.
- After deployment, copy the contract address and import it into MetaMask.
Handling Decimals
Note: The initial supply accounts for decimals. For example, if you want 10,000 tokens with 1 decimal, you must input 100,000 (10000.0). Adjust the initial supply accordingly based on your decimal precision.
Verifying the Contract on Etherscan
After deployment, verify your contract on Etherscan to enable transparency and interaction:
- Navigate to your contract’s address on Etherscan.
- Click "Verify and Publish."
- Fill in contract details, ensuring the compiler version and settings match your deployment exactly.
- Complete the human verification step and submit.
Verification fails if bytecode discrepancies exist. Ensure compiler version, optimization settings, and constructor arguments are identical to the deployment.
Frequently Asked Questions
What is the ERC-20 standard?
ERC-20 is a technical standard for Ethereum-based tokens. It defines a common set of rules and functions that ensure interoperability across wallets, exchanges, and dApps. This includes methods for transferring tokens, checking balances, and managing allowances.
Why is my token not appearing in MetaMask?
Ensure your contract implements all mandatory ERC-20 functions and events. Also, verify that you’ve imported the correct contract address and that the token has been deployed successfully to the network.
How do I handle decimals in token creation?
Decimals determine the divisibility of your token. If you set decimals to 2, the smallest unit is 0.01 tokens. Adjust the initial supply accordingly; for example, for 10,000 tokens with 2 decimals, issue 1,000,000 units.
What is the purpose of the approve and transferFrom functions?
These functions enable delegated transfers. A token owner can approve another address (e.g., a smart contract) to spend tokens on their behalf. The approved address can then use transferFrom to move tokens within the allowed limit.
Why did my contract verification fail on Etherscan?
Verification fails if the compiled bytecode doesn’t match the on-chain bytecode. Ensure the compiler version, optimization settings, and constructor arguments exactly match those used during deployment. Even minor differences can cause failures.
Can I deploy an ERC-20 token to mainnet?
Yes, the process is identical to testnet deployment but requires real ETH for gas fees. Always test thoroughly on testnets before deploying to mainnet to avoid costly errors.
For more advanced deployment strategies and real-time tools, feel free to explore additional resources here.