Ethereum smart contracts are coded contracts written in Solidity, or other compatible languages, that exist in a solely digital form. Their purpose is to perform a specific task without the need of a middleman through the use of the immutable code of the Ethereum blockchain. To read more about what smart contracts are capable of, check out this article here.
Every token that exists on the Ethereum Blockchain is tied to a smart contract, each with their own set of functions they use to perform tasks.
ERC20, which stands for ‘Ethereum Request for Comment’, is just one type of smart contract standard that exists within the Ethereum ecosystem, but it is by far the most recognizable. Understanding the framework of an ERC20 smart contract can help shed light on exactly what’s going on when you send transactions, participate in token sales, or even check your balance.
This is not a guide to learn how to write smart contracts, but instead is an outline for those interested in learning more about what’s going on behind-the-scenes when they interact with their crypto.
ERC20 Smart Contracts
ERC20 Smart Contracts are composed of six mandatory functions and three optional (but more familiar) ones.
These first six functions are:
- balanceOf( )
- totalSupply( )
- transfer( )
- transferFrom( )
- approve( )
- allowance( )
The optional ones determine factors such as the token’s name, symbol, and the number of decimal places it measures.
The ‘totalSupply( )’ function pulls the entire circulating supply of the token that contract is tied to. Even though there may be a predetermined maximum set limit for the total supply, this function shows the current total supply in circulation, which may be less than its future total.
function totalSupply( ) constant returns (uint theTotalSupply);
The balance of your token is stored and retrieved through the ‘balanceOf( )’ function. This function requires a public Ethereum address to work properly, or else there is nowhere to pull a balance from.
function balanceOf(address _owner) constant returns (uint balance);
This function is easier to think of as an authentication step for the owner of the contract. It approves the withdrawal of tokens from the owner’s address to the address that is attempting to retrieve tokens, up to a specified amount. This function works hand-in-hand with ‘allowance( )’.
function approve(address _spender, uint _value) returns (bool success);
This function is one many users are familiar with, as it allows the transfer of tokens from the contract owner’s address to another address.
function transfer(address _to, uint _value) returns (bool success);
If we already have a ‘transfer( )’ function, why do we need a ‘transferFrom( )’?
Well, think of it as an automatic transfer function. ‘transferFrom( )’ allows the smart contract to automatically send tokens from the owner’s address to another address, assuming the person has been approved to withdraw. It’s generally used by the contract itself, not by an actual person.
function transferFrom(address _from, address _to, uint _value) returns (bool success);
This function checks the amount of tokens that the owner is allowing to be transferred by the smart contract from the owner’s address to another address. This function generally works hand-in-hand with the function ‘approve( )’, as it checks the amount of tokens that have been approved for transfer. Think of the value seen here as a limit cap on token withdrawals, so the supply can be properly managed.
function allowance(address _owner, address _spender) constant returns (uint remaining);
These additional fields are more familiar to those who have added a custom token on MEW before. These details can generally be found pretty easily on an Ethereum blockchain explorer, like Etherscan. They delegate the name, symbol, and amount of decimal places that tokens are read to.
This sets the name for the token.
string public constant name = “My Token Name”;
This sets the 3 - 4 letter abbreviation for the token.
string public constant symbol = “MTN”;
Number of Decimals
This sets the decimal place for reading the amount of the token. You can’t write decimal places in Solidity, so the only way to specify how many decimal places you want to go out to is through whole numbers and this decimal function. Decimals are usually set to ‘18’.
Uint8 public constant decimals = 18;
ERC223 Smart Contracts
After enough time, problems with the ERC20 standard began to pop up. One problem in particular has caused a lot of heartaches and lost assets. If the ‘transfer( )’ function is used to send tokens directly to the main address of a smart contract, they are locked forever within the contract and can never be retrieved.
ERC223 is one out of many proposals to fix this issue, and it’s arguably the most popular. It is built with a newly defined ‘transfer( )’ function that allows tokens to be sent to either a personal address or a smart contract. It also includes a ‘tokenFallback( )’ function that checks the receiving contract for the same function. If the receiving contract does not have a ‘tokenFallback( )’ function, then the transaction will fail and all assets are returned to the address that sent them initially.
This new definition of ‘transfer( )’ eliminates the issue of lost tokens locked in contracts until the end of time, but sadly has no effect on all the previous ERC20 contracts that have already been written. It’s also worth mentioning that sending ERC223 tokens to a contract is a one-step process (rather than the two step approve-transfer process for ERC20 tokens). As such, it requires less gas costs to execute, making it very energy efficient!
ERC721 Smart Contracts
The second most recognizable smart contract on Ethereum is the ERC721 contract, which we’ll go over briefly. ERC721 is famous for allowing the creation of unique tokens called Non-Fungible Tokens (NFTs) that cannot be duplicated. With a unique token, an address can have indisputable ownership of whatever that token represents, such as a house deed, a rare piece of art, or a crypto-collectible.
ERC721 contracts have eight functions and two optional functions, some of which are similar to the ERC20 standard.
They are defined as:
- name( )
- symbol( )
- totalSupply( )
- balanceOf( )
- ownerOf( )
- approve( )
- takeOwnership( )
- transfer( )
- tokenOfOwnerByIndex( ) - optional
- tokenMetadata( ) - optional
name( ), symbol( ), totalSupply( ), approve( ), transfer( ), balanceOf( )
These functions are pretty much the same as they are defined in the ERC20 standard above.
‘name( )’ gets the name of the token
‘symbol( )’ gets the 3 - 4 letter abbreviation
‘totalSupply( )’ pulls the total circulating supply of the token
‘approve( )’ sets permission to transfer a token
‘transfer( )’ sends the token from the owner’s address to another
‘balanceOf( )’ pulls the balance for a specified address
This is where ERC721 starts to get different. ‘ownerOf( )’ retrieves the address that owns whichever NFT ID number is searched. Ownership is defined by simply having the token, as each NFT is completely unique and can only exist on one address at a time.
This function is easier to think of as ‘withdraw’, since that’s what it does. If approved in advance with the ‘approve( )’ function, an address holder can use this function to transfer the token from another address that currently holds it.
This function is necessary for anyone who plans to have more than one NFT. It allows NFT IDs to be searched through a list of tokens owned by the user. Since each NFT is unique, they are each listed individually.
When this function is called, it retrieves any metadata about the NFT that may be included in its code, such as links showing what it’s meant to represent or any other details that may be helpful for identifying its purpose.
As ERC standards evolve over time, it’s important to stay up-to-date with the newest protocols. Make sure you follow us on Twitter, Instagram, and YouTube to stay informed with the latest happenings in the crypto-sphere.