Ethereum was founded by Vitalik Buterin in 2014, positioning itself as an open-source platform for launching decentralized applications (DApps). Many of Buterin’s motivations for creating a new blockchain stemmed from the Bitcoin protocol’s lack of flexibility.
Since its launch, the Ethereum blockchain has attracted developers, businesses, and entrepreneurs, spawning a growing industry of users launching smart contracts and distributed applications.
In this article, we’ll look at the ERC-20 standard, an important framework for creating tokens. While it’s specific to the Ethereum network, the framework also inspired other blockchain standards, such as Binance Chain’s BEP-2.
In Ethereum, an ERC is an Ethereum Request for Comments. These are technical documents that outline standards for programming on Ethereum. They’re not to be confused with Ethereum Improvement Proposals (EIPs), which, like Bitcoin’s BIPs, suggest improvements to the protocol itself. ERCs instead aim to establish conventions that make it easier for applications and contracts to interact with each other.
Authored by Vitalik Buterin and Fabian Vogelsteller in 2015, ERC-20 proposes a relatively simple format for Ethereum-based tokens. By following the outline, developers don’t need to reinvent the wheel. Instead, they can build off a foundation already used across the industry.
It should be noted that the ERC-20 standard was developed into an EIP (specifically, EIP-20). This happened a couple of years after the original proposal due to its widespread use. However, even years later, the name “ERC-20” has stuck.
Unlike ETH (Ethereum’s native cryptocurrency), ERC-20 tokens aren’t held by accounts. The tokens only exist inside a contract, which is like a self-contained database. It specifies the rules for the tokens (i.e., name, symbol, divisibility) and keeps a list that maps users’ balances to their Ethereum addresses.
To move tokens, users must send a transaction to the contract asking it to allocate some of their balance elsewhere. For example, if Alice wants to send 5,000 BinanceAcademyTokens to Bob, she calls a function inside the BinanceAcademyToken smart contract asking it to do so.
Her call is contained inside what appears to be a regular Ethereum transaction that pays 0 ETH to the token contract. The call is included in an additional field in the transaction, which specifies what Alice wants to do – in our case, transfer tokens to Bob.
Even though she isn’t sending ether, she must still pay a fee denominated in it to have her transaction included in a block. If she has no ETH, she needs to get some before transferring the tokens.
Here's a real-world example of the above on Etherscan: someone is making a call to the BUSD contract. You can see tokens were transferred, and a fee has been paid, even though the Value field shows that 0 ETH has been sent.
Now that we’re up to speed, let’s take a look under the hood to better understand the structure of a typical ERC-20 contract.
To be ERC-20-compliant, your contract needs to include six mandatory functions: totalSupply, balanceOf, transfer, transferFrom, approve, and allowance. In addition, you can specify optional functions, such as name, symbol, and decimal. It might be clear to you what those functions do from their names. If not, don’t worry – we’ll break them down.
Below are the functions as they appear in Ethereum’s purpose-built Solidity language.
function totalSupply() public view returns (uint256)
When called by a user, the above function returns the total supply of tokens that the contract holds.
function balanceOf(address _owner) public view returns (uint256 balance)
Unlike totalSupply, balanceOf takes a parameter (an address). When called, it returns the balance of that address’s token holdings. Remember that accounts on the Ethereum network are public, so you can query any user’s balance provided you know the address.
function transfer(address _to, uint256 _value) public returns (bool success)
transfer aptly transfers tokens from one user to another. Here, you provide the address you want to send to and the amount to transfer.
When called, transfer triggers something called an event (event transfer, in this case), which basically tells the blockchain to include a reference to it.
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
The transferFrom function is a handy alternative to transfer that enables a bit more programmability in decentralized applications. Like transfer, it’s used to move tokens, but those tokens don’t necessarily need to belong to the person calling the contract.
In other words, you can authorize someone – or another contract – to transfer funds on your behalf. A possible use case involves paying for subscription-based services, where you don’t want to manually send a payment every day/week/month. Instead, you just let a program do it for you.
This function triggers the same event as transfer.
function approve(address _spender, uint256 _value) public returns (bool success)
approve is another useful function from a programmability standpoint. With this function, you can limit the number of tokens that a smart contract can withdraw from your balance. Without it, you run the risk of the contract malfunctioning (or being exploited) and stealing all of your funds.
Take our example of a subscription model again. Suppose that you have a huge amount of BinanceAcademyTokens, and you want to set up weekly recurring payments to a streaming DApp. You’re busy reading Binance Academy content day and night, so you don’t want to take the time every week to create a transaction manually.
You have a massive balance of BinanceAcademyTokens, far exceeding what’s needed to pay for the subscription. To prevent the DApp from draining all of them, you can set a limit with approve. Suppose that your subscription costs one BinanceAcademyToken per week. If you capped the approved value at twenty tokens, then you could have your subscription paid automatically for five months.
At worst, if the DApp attempts to withdraw all your funds or if a bug is found, you can only lose twenty tokens. It may not be ideal, but it’s certainly more appealing than losing all of your holdings.
When called, approve triggers the approval event. Like the transfer event, it writes data to the blockchain.
function allowance(address _owner, address _spender) public view returns (uint256 remaining)
allowance can be used in conjunction with approve. When you’ve given a contract permission to manage your tokens, you might use this to check how many it can still withdraw. For instance, if your subscription has used up twelve of your twenty approved tokens, calling the allowance function should return a total of eight.
The previously-discussed functions are compulsory. On the other hand, name, symbol, and decimal don’t need to be included, but they can make your ERC-20 contract a bit prettier. Respectively, they allow you to add a human-readable name, set a symbol (i.e., ETH, BTC, BNB), and to specify how many decimal places tokens are divisible to. For example, tokens that are used as currencies may benefit more from being more divisible than a token that represents ownership of a property.
Check out this example on GitHub to see these elements in a real contract.
By putting together all of the functions above, we’ve got an ERC-20 contract. We can query the total supply, check balances, transfer funds, and give permissions to other DApps to manage tokens for us.
A big part of the appeal of ERC-20 tokens is their flexibility. The conventions set out don’t restrict development, so parties can implement additional features and set specific parameters to suit their needs.
Stablecoins (tokens pegged to fiat currencies) often use the ERC-20 token standard. The transaction to the BUSD contract that we referenced earlier is one example, and most major stablecoins are also available in this format.
For a typical fiat-backed stablecoin, an issuer holds reserves of euros, dollars, etc. Then, for every unit in their reserve, they issue a token. This means that if $10,000 were locked away in a vault, the issuer could create 10,000 tokens, each redeemable for $1.
This is quite easy to implement in Ethereum, technically speaking. An issuer simply launches a contract with 10,000 tokens. Then, they’ll distribute them to users with the promise that they can later redeem the tokens for a proportionate amount of fiat currency.
Users can do a number of things with their tokens – they can buy goods and services or use them in DApps. Alternatively, they could request that the issuer exchange them right away. In that instance, the issuer burns the returned tokens (making them unusable) and withdraws the correct amount of fiat from their reserves.
The contract that governs this system, as aforementioned, is relatively simplistic. However, launching a stablecoin requires a lot of work on external factors such as logistics, regulatory compliance, etc.
Security tokens are similar to stablecoins. At the contract level, both could even be identical as they function in the same way. The distinction occurs at the issuer’s level. Security tokens represent securities, such as stocks, bonds, or physical assets. Often (though it isn’t always the case), they grant the holder some kind of stake in a business or good.
Utility tokens are perhaps the most common types of tokens found today. Unlike the previous two offerings, they’re not backed by anything. If asset-backed tokens are like shares in an airline company, then utility tokens are like frequent-flyer programs: they serve a function, but they have no external value. Utility tokens can cater to a myriad of use cases, serving as in-game currency, fuel for decentralized applications, loyalty points, and much more.
You can mine ether (ETH), but tokens are not mineable – we say they’re minted when new ones are created. When a contract is launched, developers distribute the supply according to their plans and roadmap.
Typically, this is done via an Initial Coin Offering (ICO), Initial Exchange Offering (IEO), or Security Token Offering (STO). You may come across variations of these acronyms, but these concepts are quite similar. Investors send ether to the contract address and, in return, receive new tokens. The money collected is used to fund further development on the project. Users expect to be able to use their tokens (either immediately or at a later date) or resell them for a profit as the project develops.
The token distribution doesn’t need to be automated. Many crowdfunding events allow users to pay with a range of different digital currencies (such as BNB, BTC, ETH, and USDT). The respective balances are then allocated to the addresses provided by the users.
ERC-20 tokens are fungible – each unit is interchangeable with another. If you held a BinanceAcademyToken, it wouldn’t matter what specific token you had. You could trade it for someone else’s, and they’d still be functionally identical, just like cash or gold.
This is ideal if your token aims to be a currency of some kind. You wouldn’t want individual units with distinguishable traits, which would make them non-fungible. This could cause some tokens to become more – or less – valuable than others, undermining their purpose.
As we explored in the previous section, ERC-20 tokens are highly customizable and can be tailored to many different applications. For instance, they can be used as in-game currency, in loyalty points programs, as digital collectibles, or even to represent fine art and property rights.
ERC-20’s popularity in the cryptocurrency industry is a highly compelling reason to use it as a blueprint. There are a plethora of exchanges, wallets, and smart contracts already compatible with newly-launched tokens. What’s more, developer support and documentation is abundant.
As with many cryptocurrency networks, Ethereum is not immune to growing pains. In its current form, it doesn’t scale well – trying to send a transaction at peak times results in high fees and delays. If you launch an ERC-20 token and the network gets congested, its usability could be impacted.
This isn’t a problem exclusive to Ethereum. Rather, it's a necessary trade-off in secure, distributed systems. The community plans to address these problems in the migration to Ethereum 2.0, which will implement upgrades like Ethereum Plasma and Ethereum Casper.
Learn more about scalability issues in Blockchain Scalability: Sidechains and Payment Channels.
While not an issue with the technology itself, the ease with which a token can be launched could be considered a downside in some respects. It takes minimal effort to create a simple ERC-20 token, meaning that anyone could do it – for good or for bad.
As such, you should be careful with what you’re investing in. There are a number of Pyramid and Ponzi schemes disguised as blockchain projects. Do your own research before investing to reach your own conclusions on whether an opportunity is legitimate.
ERC-20 was the first (and, to date, the most popular) Ethereum token standard, but it’s by no means the only one. Over the years, many others have emerged, either proposing improvements on ERC-20 or attempting to achieve different goals altogether.
Some of the less common standards are the ones used in non-fungible tokens (NFTs). Sometimes, your use case actually benefits from having unique tokens with different attributes. If you wanted to tokenize a one-of-a-kind piece of art, in-game asset, etc., one of these contract types might be more appealing.
The ERC-721 standard, for instance, was used for the immensely popular CryptoKitties DApp. Such a contract provides an API for users to mint their own non-fungible tokens and to encode metadata (images, descriptions, etc.).
The ERC-1155 standard could be seen as an improvement on both ERC-721 and ERC-20. It outlines a standard that supports both fungible and non-fungible tokens in the same contract.
Other options like ERC-223 or ERC-621 aim to improve usability. The former implements safeguards to prevent accidental token transfers. The latter adds extra functions for increasing and decreasing token supply.
For more on the topic of NFTs, be sure to check out A Guide to Crypto Collectibles and Non-Fungible Tokens (NFTs).
The ERC-20 standard has dominated the crypto asset space for years, and it’s not hard to see why. With relative ease, anyone can deploy a simple contract to suit a wide range of use cases (utility tokens, stablecoins, etc.). That said, ERC-20 does lack some of the features brought to life by other standards. It remains to be seen whether subsequent types of contracts will take its place.