Understanding ERC-20 tokens

With the ERC-20 token standard an interface for ethereum smart contracts was defined to represent tokens on the ethereum blockchain. A common standard for the representation has many benefits for the future advent of blockchain based applications. Various applications can be built based on the token standard, which will allow to plugin every token complying with the standard and make it workable with the application:

function transfer(address _to, uint256 _value) returns (bool success)

Generic token representation

Tokens are represented within a very simple balance sheet to track ownership and transfers of tokens. In the following an example of a token balance is given. Three token holders A, B and C and a total supply of 10,000 tokens are shown.

Owner Token Balance
A 640
B 50
C 100
... ...
Total 10,000

In the case of A wanting to transfer 40 tokens to B a simple transformation of the balance sheet is happening. The balance of A is decreased by 40 and the balance of B is increased by 40. This would leave the balance sheet in the following form:

Owner Token Balance
A 600
B 90
C 100
... ...
Total 10,000

Basic ERC-20 token contract

A basic ERC-20 token contract has 4 defining attributes name, symbol, decimals and totalSupply. The attributes name, symbol and decimals are generally optional within the standard, however are important for user interfaces to present the token accordingly.

Besides the 4 attributes the token standard defines functions for transfering tokens between holders and querying balances of holders. The transfer function has the following signature:

function transfer(address _to, uint256 _value) returns (bool success)

The signature of the function for querying the balance is as follows:

function balanceOf(address _owner) constant returns (uint256 balance)

The transfer function is responsible for transfering a specified token amount from one entry in the balance sheet to another. In the case of a transfer the message sender (msg.sender) is initiating the transfer and thus on his entry the specified amount is deducted and the given _to address is receiving the amount. The tranfer function is always returning a boolean (success) for showing a successful or unsuccessful transfer.

The balanceOf function is returning the token balance for a given _owner address. The balance entry is represented as an integer which represents tokens + token fractions according to the given decimals.

In the following an examplary solidity smart contract is shown, which implements an Example Token. The amount of full tokens available is 10,000 and 18 decimal places are defined, which means the total supply of tokens is 10,000 * 10^18. Within the constructor function of the token the total supply of tokens is transfered to the balance of the creator of the contract (msg.sender). This means the creator is in possession of all tokens and can transfer them to other accounts.

contract BasicERC20TokenExample {

string public constant name = "Example Token";
string public constant symbol = "EXP";
uint8 public constant decimals = 18;
uint256 public constant totalSupply = 10000 * (10 ** uint256(decimals));

mapping(address => uint256) balances;

function BasicERC20TokenExample() public {
balances[msg.sender] = totalSupply;
}

function transfer(address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[msg.sender]);
balances[msg.sender] = balances[msg.sender] - _value;
balances[_to] = balances[_to] + _value;
return true;
}

function balanceOf(address _owner) public view returns (uint256 balance) {
return balances[_owner];
}
}

Additional ERC-20 token functions

Besides the generic transfer function described above, an ERC-20 token provides functions for granting allowances. This offers the possibility to do token transfers on behalf of a token holder. ERC-20 token exchanges rely on this functionality to do token exchanges between holders of two different ERC-20 tokens (Check the EtherDelta smart contract as an example). Therefore an approve function is introduced for token holders to set an allowance for spenders. Supplementary to the approve function a transferFrom function allows the spender to transfer to a given _to address up to the approved value and from the approved balance entry.

In the following the approve function signature is shown. A token holder can approve a specific _value for transferals for a given _spender address.

function approve(address _spender, uint256 _value) returns (bool success)

The transferFrom provides the functionallity for the approved _spender to transfer a _value from the _from address to a given _to address. The transferFrom function can be used multiple times as long as the allowance for a specific _from address is consumed.

function transferFrom(address _from, address _to, uint256 _value) returns (bool success)

Lastly a function for querying the allowance of a _spender address on a specified _owner address should be available.

function allowance(address _owner, address _spender) constant returns (uint256 remaining)

Further notes