Blockchain Academy Blockchain Blogs

What is TatiCoin(TTC)

TatiCoin (TTC) is a test ICO built on a test Ethereum Blockchain to demonstrate how to build an ERC20, that can be used for ICO-purposes.

Althought acquired on this website, TatiCoin(TTC) can be transferred to any Rinkeby Ether Address, traded at any exchange that lists the token. It has all the attributes of a real Ethereum ERC20 token.


ERC20 token are essentially a smart contract, they are Solidity code that is deployed to the Ethereum Blockchain, and you interact with then as you would with any other smart contract.




Below is the Solidity Smart Contract Adapted from the Ethereum Website that we just tested above. It complies to all ERC20 specifications:

  • The tokens are transferrable - from one account to another
  • You can enquire if a certain address contains the tokens
  • You can set allowances for other addresses to move tokens on your behalf
  • You must emit certain events - such as transferring tokens
  • Tokens have a name, symbol - making them identifiable on exchanges
  • With our tokens - owners have the ability to burn their token in to thin air - reducing total supply
  • The initial total supply is assigned to the person who deployed the contract
                  
                    pragma solidity ^0.4.21;

                      interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) external; }

                      contract TatiCoin {
                          // Public variables of the token
                          string public name;
                          string public symbol;
                          uint8 public decimals = 18;
                          // 18 decimals is the strongly suggested default, avoid changing it
                          uint256 public totalSupply;

                          // This creates an array with all balances
                          mapping (address => uint256) public balanceOf;
                          mapping (address => mapping (address => uint256)) public allowance;

                          // This generates a public event on the blockchain that will notify clients
                          event Transfer(address indexed from, address indexed to, uint256 value);

                          // This generates a public event on the blockchain that will notify clients
                          event Approval(address indexed _owner, address indexed _spender, uint256 _value);

                          // This notifies clients about the amount burnt
                          event Burn(address indexed from, uint256 value);


                          constructor (
                              uint256 initialSupply,
                              string tokenName,
                              string tokenSymbol
                          ) public {
                              totalSupply = initialSupply * 10 ** uint256(decimals);  // Update total supply with the decimal amount
                              balanceOf[msg.sender] = totalSupply;                // Give the creator all initial tokens
                              name = tokenName;                                   // Set the name for display purposes
                              symbol = tokenSymbol;                               // Set the symbol for display purposes
                          }

                          /**
                           * Internal transfer, only can be called by this contract
                           */
                          function _transfer(address _from, address _to, uint _value) internal {
                              // Prevent transfer to 0x0 address. Use burn() instead
                              require(_to != 0x0);
                              // Check if the sender has enough
                              require(balanceOf[_from] >= _value);
                              // Check for overflows
                              require(balanceOf[_to] + _value >= balanceOf[_to]);
                              // Save this for an assertion in the future
                              uint previousBalances = balanceOf[_from] + balanceOf[_to];
                              // Subtract from the sender
                              balanceOf[_from] -= _value;
                              // Add the same to the recipient
                              balanceOf[_to] += _value;
                              emit Transfer(_from, _to, _value);
                              // Asserts are used to use static analysis to find bugs in your code. They should never fail
                              assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
                          }

                          /**
                           * Transfer tokens
                           *
                           * Send `_value` tokens to `_to` from your account
                           *
                           * @param _to The address of the recipient
                           * @param _value the amount to send
                           */
                          function transfer(address _to, uint256 _value) public returns (bool success) {
                              _transfer(msg.sender, _to, _value);
                              return true;
                          }

                          /**
                           * Transfer tokens from other address
                           *
                           * Send `_value` tokens to `_to` on behalf of `_from`
                           *
                           * @param _from The address of the sender
                           * @param _to The address of the recipient
                           * @param _value the amount to send
                           */
                          function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
                              require(_value  allowance[_from][msg.sender]);
                              allowance[_from][msg.sender] -= _value;
                              _transfer(_from, _to, _value);
                              return true;
                          }

                          /**
                           * Set allowance for other address
                           *
                           * Allows `_spender` to spend no more than `_value` tokens on your behalf
                           *
                           * @param _spender The address authorized to spend
                           * @param _value the max amount they can spend
                           */
                          function approve(address _spender, uint256 _value) public
                              returns (bool success) {
                              allowance[msg.sender][_spender] = _value;
                              emit Approval(msg.sender, _spender, _value);
                              return true;
                          }

                          /**
                           * Set allowance for other address and notify
                           *
                           * Allows `_spender` to spend no more than `_value` tokens on your behalf, and then ping the contract about it
                           *
                           * @param _spender The address authorized to spend
                           * @param _value the max amount they can spend
                           * @param _extraData some extra information to send to the approved contract
                           */
                          function approveAndCall(address _spender, uint256 _value, bytes _extraData)
                              public
                              returns (bool success) {
                              tokenRecipient spender = tokenRecipient(_spender);
                              if (approve(_spender, _value)) {
                                  spender.receiveApproval(msg.sender, _value, this, _extraData);
                                  return true;
                              }
                          }

                          /**
                           * Destroy tokens
                           *
                           * Remove `_value` tokens from the system irreversibly
                           *
                           * @param _value the amount of money to burn
                           */
                          function burn(uint256 _value) public returns (bool success) {
                              require(balanceOf[msg.sender] >= _value);   // Check if the sender has enough
                              balanceOf[msg.sender] -= _value;            // Subtract from the sender
                              totalSupply -= _value;                      // Updates totalSupply
                              emit Burn(msg.sender, _value);
                              return true;
                          }

                          /**
                           * Destroy tokens from other account
                           *
                           * Remove `_value` tokens from the system irreversibly on behalf of `_from`.
                           *
                           * @param _from the address of the sender
                           * @param _value the amount of money to burn
                           */
                          function burnFrom(address _from, uint256 _value) public returns (bool success) {
                              require(balanceOf[_from] >= _value);                // Check if the targeted balance is enough
                              require(_value  allowance[_from][msg.sender]);    // Check allowance
                              balanceOf[_from] -= _value;                         // Subtract from the targeted balance
                              allowance[_from][msg.sender] -= _value;             // Subtract from the sender's allowance
                              totalSupply -= _value;                              // Update totalSupply
                              emit Burn(_from, _value);
                              return true;
                          }
                      }

                  
                

In order to run this code, you need to specify:

  • The number of tokens you want to create
  • The name of your tokens
  • The Symbol of your token - unique identifier

Then => DEPLOY and you have just created an ERC20 token. Of course at this stage - the creator of the contract will have the full supply of token assigned to them.If you are creating an ICO, you would want to distribute those tokens:

There are two ways to do this:

  • Create a second smart contract to handle the sale, through your ICO website
  • Ditribute the token through an exchange

We can assist you with both methods - it is all dependent on the client preferrence, there are benefits and drawbacks for both options.

Option 1 - Create a distribution SmartContract on your website (like we did here). It is the simplest approach

Users will need to be able to send Ether, you can incorporate meta-mask and simplify the process.

You can not easily keep track of who actually bought the tokens for KYC purposes, unless if you implement authentication on your ICO website - which is a time-consuming effort.

Option 2 - Use an existing exchange to distribute tokens

Users do not need to use Ether, they could trade FIAT for the main trading pair and immediately get your tokens. Your tokens can continue to be traded for as long as you want.

Exchanges already have KYC implementation, you do not need to manage client data and store information on your servers.