Tuesday, July 10, 2018

Building DApps with Ethereum: Creating, Deploying TNS Tokens

In part 1 of this tutorial series on building DApps with Ethereum, we bootstrapped two versions of a local blockchain for development: a Ganache version, and a full private PoA version.

In this part, we’ll dive right into it and build and deploy our TNS token — the token users will use to vote on proposals in the Story DAO.

Prerequisites

Have a Ganache version up and running, as per the previous part. Alternatively, have any local version of a blockchain running if you’re not following along from the first part, but make sure you can connect to it with tools we’ll need.

We’ll assume you have a working private blockchain and the ability to type commands into its console and the operating system’s terminal via the Terminal app or, on Windows, an app like Git Bash, Console, CMD Prompt, Powershell, etc.

The Basic Dependencies

To develop our application, we can use one of several frameworks and starter kits at our disposal: Dapp, eth-utils, Populus, Embark … and so on. But we’ll go with the current king of the ecosystem, Truffle.

Install it with the following:

npm install -g truffle

This will make the truffle command available everywhere. Now we can start the project with truffle init.

Starting the Token

Let’s get right into it and build our token. It’ll be a somewhat standard cookie-cutter ERC20 token with a twist. (You’ll see which twist lower in this post.) First, we’ll pull in some dependencies. The OpenZeppelin libraries are battle-tested high quality solidity contracts usable for extending and building contracts from.

npm install openzeppelin-solidity

Next, let’s create a new token file:

truffle create contract TNSToken

The default template that truffle generates here is a little out of date, so let’s get it updated:

pragma solidity ^0.4.24;

contract TNStoken {
    constructor() public {

    }
}

Up until now, the constructor of the token contract was supposed to be called the same as the contract itself, but for clarity it was changed to constructor. It should also always have a modifier telling the compiler who is allowed to deploy and interact with this contract (public meaning everyone).

SafeMath

The only Zeppelin contract we’ll be using in this case is their SafeMath contract. In Solidity, we import contracts with the import keyword, while the compiler will generally not require a full path, only a relative one, like so:

pragma solidity ^0.4.24;

import "../node_modules/openzeppelin-solidity/contracts/math/SafeMath.sol";

contract TNStoken {
    using SafeMath for uint256;
    constructor() public {

    }
}

So, what is SafeMath? Long ago, there was an issue of 184 billion bitcoins being created because of a math problem in code. To prevent issues even remotely similar to these (not that this one in particular is possible in Ethereum), the SafeMath library exists. When two numbers are of the MAX_INT size (i.e. the maximum possible number in an operating system), summing them up would make the value “wrap around” to zero, like a car’s odometer being reset to 0 after reaching 999999 kilometers. So the SafeMath library has functions like these:

/**
* @dev Adds two numbers, throws on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
  c = a + b;
  assert(c >= a);
  return c;
}

This function prevents this issue: it checks whether the sum of two numbers is still bigger than each of the two operands.

While it’s not too easy to make such silly mistakes when writing Solidity contracts, it’s still better to be safe than sorry.

By using SafeMath for uint256, we replace the standard uint256 numbers in Solidity (256bit unsigned — a.k.a. positive-only — whole numbers) with these “safe” versions. Instead of summing numbers like this: sum = someBigNumber + someBiggerNumber, we’ll be summing them like this: sum = someBigNumber.add(someBiggerNumber), thereby being safe in our calculations.

ERC20 from Scratch

With our math made safe, we can create our token.

ERC20 is a standard with a well-defined interface, so for reference, let’s add it into the contract. Read about the token standards here.

So the functions that an ERC20 token should have are:

pragma solidity ^0.4.24;

import "../node_modules/openzeppelin-solidity/contracts/math/SafeMath.sol";

contract ERC20 {
    function totalSupply() public view returns (uint256);
    function balanceOf(address who) public view returns (uint256);
    function transfer(address to, uint256 value) public returns (bool);
    event Transfer(address indexed from, address indexed to, uint256 value);
    function allowance(address owner, address spender) public view returns (uint256);
    function transferFrom(address from, address to, uint256 value) public returns (bool);
    function approve(address spender, uint256 value) public returns (bool);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

contract TNStoken {

    using SafeMath for uint256;

    constructor() public {

    }
}

This might seem complex, but it’s actually very simple. This is a “directory” of functions our token needs to have, and we’ll build them one by one, explaining what each of them means. Consider the above an interface for our token. We’ll see how and why this is useful when we create the Story DAO application.

Basic balances

Let’s start. A token is actually just a “spreadsheet” in the Ethereum blockchain, like this:

| Name | Amount |
|:--|:--|
| Bruno | 4000 |
| Joe | 5000 |
| Anne | 0 |
| Mike | 300 |

So let’s create a mapping, which is essentially exactly like a spreadsheet in the contract:

mapping(address => uint256) balances;

According to the interface above, this needs to be accompanied by a balanceOf function, which can read this table:

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

The function balanceOf accepts one argument: _owner is public (can be used by anyone), is a view function (meaning it’s free to use — does not require a transaction), and returns a uint256 number, the balance of the owner of the address sent in. Everyone’s balance of tokens is publicly readable.

Total supply

Knowing the total supply of the token is important for its users and for coin tracking applications, so let’s define a contract property (variable) to track this and another free function through which to read this:

uint256 totalSupply_;
function totalSupply() public view returns (uint256) {
    return totalSupply_;
}

The post Building DApps with Ethereum: Creating, Deploying TNS Tokens appeared first on SitePoint.


by Bruno Skvorc via SitePoint

No comments:

Post a Comment