BARRY Token: Building an Ethereum ERC20 Token using Solidity

OK, so I’m going to make a crypto token which distributes from a smart contract.

To do this I’m going to create an Ethereum smart contract in Solidity. When a person sends Ethereum to the contract, the contract will send back our tokens to the address which sent the Ethereum.

I am going to create a new crypto token BARRY.

BARRY will be distributed at a rate of 2 BARRY = 1 ETH.

1. MetaMask and Browser-Solidity

To begin we need to install the MetaMask chrome plugin. Metamask allows us to do transactions on the Eth blockchain in the browser, without having to install a full node, and is very simple to use.

Go to https://metamask.io/ and click to install the plugin

When it is finished you should have the following plugin icon in the top right corner of your browser

Metamask

Click the icon, click that you’ve read the T&C’s, after that it will ask you to enter a password - pick something secure, make a note of it and then click create.

You’ll be given the recovery phrase, keep it safe somewhere.

After that you should have MetaMask and an Eth account setup

Metamask

Next for writing the contract..

Rather than use a local IDE I am going to write the contract on https://ethereum.github.io/browser-solidity/

Ok, to begin..

In the browser editor we will create a new file

circle

Click the circle with the plus in the image above , and when prompted enter the name ‘ERCToken.sol’

As our token is an ERC20 token, it needs to be ERC-20 Compliant - that means we need it to have a number of required methods.

Paste in the the following code

pragma solidity ^0.4.11;

contract ERC20 {
    
    function balanceOf( address who ) constant returns (uint value);
    function allowance(address _owner, address _spender) constant returns (uint256 remaining);
    
    function transfer(address _to, uint256 _value) returns (bool success);
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success);
    function approve(address _spender, uint256 _value) returns (bool success);

    event Transfer( address indexed from, address indexed to, uint value);
    event Approval( address indexed owner, address indexed spender, uint value);
}

Next we will create another file for our token, ‘Barry.sol’

barrystart

pragma solidity ^0.4.11;

import './ERCToken.sol';

contract BarryToken is ERC20 {

}

This means that our BarryToken adheres to the ERC20 interface in our ERCToken.sol.

Next we’ll integrate the SafeMath library from OpenZeppelin. This will remove the potential for unsigned integer overflow in our Math operations.

Create another file ‘SafeMath.sol’ and paste in the following:

pragma solidity ^0.4.11;


/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {
  function mul(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function div(uint256 a, uint256 b) internal constant returns (uint256) {
    // assert(b > 0); // Solidity automatically throws when dividing by 0
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    return c;
  }

  function sub(uint256 a, uint256 b) internal constant returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}

Next we are going to import the SafeMath file and also add some properties to our BarryToken

pragma solidity ^0.4.11;

import './ERCToken.sol';
import './SafeMath.sol';

contract BarryToken is ERC20 {
    using SafeMath for uint256;

    address public owner;

    string public symbol = 'BARRY';
    string public name = 'BARRY Token';

    uint8 public constant decimals = 18;
    uint256 public constant tokensPerEther = 2;

    uint256 public _totalSupply =     100000000000000000000;
    uint256 public _maxSupply  =   100000000000000000000000;

    mapping(address => uint256) balances;
    mapping(address => mapping (address => uint256)) public allowed;
...

You will notice both our _totalSupply and _maxSupply are quite long. This is due us having 18 decimal places. Displayed like below makes it easier to read:

uint256 public _totalSupply = 100 000000000000000000;
uint256 public _maxSupply = 100000 000000000000000000;

In reality, our starting totalSupply (which will be the initial supply upon contract creation) will be 100, with a maxSupply of 100,000.

tokensPerEther will be the rate at which we issue BARRY to the those that send Ethereum to the address. Owner will be the owner/creator of the contract.

Ok, now that we have the properties of our Token defined, lets create the required methods and make a standard Token with a max supply:

...
    function BarryToken() {
        owner = msg.sender;
        balances[msg.sender] = _totalSupply;
    }

    function totalSupply() constant returns (uint256 totalSupply) {
        return _totalSupply;
    }    
...

The first two methods are quite self explanatory. Our constructor sets the owner and then issues the initial totalSupply of Barry, to the creator. The reason for doing this is that you may need some reserved, or for use in whatever you plan to do with the token.

...
    function () payable {
        require( msg.value > 0 && _totalSupply < _maxSupply );

        uint256 baseTokens  = msg.value.mul(tokensPerEther);

        balances[msg.sender] = balances[msg.sender].add(baseTokens);

        owner.transfer(msg.value);
        
        _totalSupply      = _totalSupply.add(baseTokens);

        Transfer(address(this), msg.sender, baseTokens);
    }
...

This is our fallback function (as you can see it has no name), this will be called whenever someone sends Ethereum to the contract (with no other data).

This is where we will do our BARRY distribution. First our method checks to see if the value sent is greater than 0 and also whether the current circulation is still less than the max supply. (Yes, this means it is possible for the totalSupply to exceed the maxSupply, depending on how much the last person to send Ethereum sends on the transaction that makes it cross the line ).

If these criteria are met, we multiply the value by the tokensPerEther. We then add this amount of BARRY balance to the balance of the sender, and transfer the sent ETH , to the owner of the contract.

...

    function balanceOf(address _owner) constant returns (uint256 balance) {
        return balances[_owner];
    }
    
    function transfer(address _to, uint256 _value) returns (bool success) {
        require((_value <= balances[msg.sender]));
        require((_value > 0));
        require(_to != address(0));
        require(balances[_to].add(_value) >= balances[_to]);
        require(msg.data.length >= (2 * 32) + 4);


        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[_to] = balances[_to].add(_value);
        Transfer(msg.sender, _to, _value);
        return true;
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        require((_value <= allowed[_from][msg.sender] ));
        require((_value > 0));
        require(_to != address(0));
        require(balances[_to].add(_value) >= balances[_to]);
        require(msg.data.length >= (2 * 32) + 4);


        balances[_from] = balances[_from].sub(_value);
        balances[_to] = balances[_to].add(_value);
        allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
        Transfer(_from, _to, _value);
        return true;
    }



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

        require( (_value == 0)  || (allowed[msg.sender][_spender] == 0) );

        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
    }


    function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
        return allowed[_owner][_spender];
    }


    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}

Ok, lets test it out on the Test network. Using Metamask, switch to the Ropsten Test network.

ropstentest

You are going to need some ETH on the test network - so click buy, then Ropsten Test Faucet and request some ETH.

Back to the IDE, click the Run tab in the top right corner. It should read ‘Injected Web3’ under environment and beneath that list our accounts ETH address.

Below that click ‘Create’. MetaMask should now open in a popup asking you to confirm the transaction. Click submit.

Open MetaMask, click the transaction to load up the contract on Etherscan.

Copy the To contract address and test the contract by sending some of your test Ethereum to this address.

In Metamask click tokens, click add Token, enter the contract address, and click add. It should now show the distributed tokens.

When you are happy that it is working, switch MetaMask back to the main Ethereum network, switch back to the IDE and go through the same steps.

barry

We now have our BARRY token with a contract address of 0x7d3613dd9b10999115fe455c0295e4b8ab8dc35e

https://etherscan.io/address/0x7d3613dd9b10999115fe455c0295e4b8ab8dc35e

Anyone who sends Ethereum to the address will receive double the amount of Barry in return.

If you are interested in understanding more about building your own token or distribution, a good place to read is

https://github.com/OpenZeppelin/zeppelin-solidity/

In the repo you will find a lot of useful sourcecode that has been used by quite a number of ICO’s