You've probably heard a bunch of buzz lately about cryptocurrencies, blockchain technologies, initial coin offerings, and how those will upend everything!

Blockchain surely represents one of the most important and exciting headwinds in tech (others include augmented reality, quantum computing, and the internet of things - I think blockchain will play an important role empowering and enabling those other sub-industries to reach fruition)!

This article will aim to do two things: (1) we'll try to clarify some of the murkiness surrounding the blockchain business jargon then (2) learn how to compile our own minimum viable coin, enrich it with a GUI, and then deploy it to a testnet. Along the way, we'll encounter some familiar technologies (like React) and some new ones (like Truffle)!

Introducing Cryptocurrencies

Rest assured that despite the sometimes opaque and abundant jargon one readily encounters in the cryptocurrency space, there are some true technological marvels that promise to transform our lives as developers!

Blockchain - defined: Blockchain is a network of nodes usually arranged in a kind of mesh topology. Transactions or events on the network propagate from one node to the rest and are thereby additionally verified along the way. Thus, a blockchain is a distributed ledger (think a giant .csv file) that requires multiple nodes (think multiple users sharing that .csv on a cloud-service like Google Docs) to approve or deny changes to the ledger.

Meshtopology

A friend of mine cleverly observed that a blockchain is really a kind of distributed linked-list which is another great way to frame that sometimes difficult concept.

The upshot is that blockchains are distributed (no single entity controls them, all changes must be mutually verified), redundant (every node has a copy of the entire blockchain's history), and a great way to decentralize server-processing across many actors (including desktop owners as well as large server farms or data warehouses).

Cryptocurrency - defined: A cryptocurrency is a kind of digital asset with inherent functionalities. This makes cryptocurrencies both a kind of digital money and more than just money (since money does not have any other inherent functionalities beyond being simply physical currency).

For example, cryptocurrencies are exchanged like money in that they can be used to purchase things. However, cryptocurrencies are also inherently programmatic and belong to digital service platforms by their very nature. Thus, they are also more than merely money or currency.

Many are also traded like other purchased commodities, securities, or interbank transactions (stocks, gold bars, real estate, short-term currency trades, etc.).

Thus, when cryptocurrencies are combined with blockchains, we get low transaction fee, high availability, no-chargeback, fully transparent, automatically accounted-for money systems that provide inherent functionality for the platforms they are a part of.

For those with a finance, day-trading, or equities bent - check out this historical graph of Ethereum on Trading View:

TradingView

Many sites now exist to help clarify, analyze, and track the many different cryptocurrencies that exist. My favorite is CoinCheckUp:

CoinCheckUp

To be clear, how such cryptocurrencies are traded is largely independent of their programmatic or service-directed functionality. And, sometimes they just act like laundromat tokens or reward points granting the holder the right to exercise some operation on the platform or network of which the cryptocurrency is a part.

As we can see, cryptocurrencies represent another way to easily send value across borders, between family members, raise money for startup capital, and easily integrate payment or reward incentives into software.

Mining - defined: Cryptocurrencies are often mined (created and rewarded through solving a complicated algorithm). These mining activities may include solving important medical problems, helping to send money through the network, executing functions. Cryptocurrencies that are mined are called proof of work cryptocurrencies.

Smart Contracts - defined: A smart contract is a block of code containing methods and functions that is called by sending data and payment to a specific address on the blockchain.

This is directly analogous to sending an HttpRequest to an endpoint and executing a function. Such a function would also be supported by a pay-by-compute-cycle business model. In other words, if you've used something like AWS Lambda or Google Cloud Functions then you're well-positioned to understand how smart contracts work.

Let's dive into this some more...

Ethereum

ethereum

Ethereum is a cryptocurrency that is also a giant decentralized super-computer. As it turns out, the Ethereum blockchain is actually a gigantic implementation of a Turing Machine called the Ethereum Virtual Machine. Unlike Bitcoin, Ethereum was built from the beginning to support smart contracts!

ERC20 is a specification and standard to write customized tokens, compile them, and then deploy them on the Ethereum network using Solidity. In other words, ERC20 is a set of rules about how to build a coin over Ethereum leveraging the pre-existing Ethereum network.

I've had the chance to work with a few great cryptocurrencies now: Dash, Decred, and Kleros.io. While all of these are profoundly interesting from a business and technology standpoint, the relative ease of building a custom coin and software solution on top of Ethereum (Kleros.io) definitely impressed me!

This means more time can be spent worrying about the actual software service and infrastructure and less time about making sure they'll be a blockchain network in place to make your coin run!

Solidity, Open Zeppelin, and Building a Smart Contract

Solidity is a JavaScript-like programming language for writing smart contracts for the Ethereum Virtual Machine.

The simplest version of a Solidity smart contract is the following:

pragma solidity ^0.4.17;

contract Example {
  function Example() {
  }
}

And, using Open Zepplin, we can import several pre-built, tested, and production-worthy (in some cases) smart contracts:

pragma solidity ^0.4.11;

import "../../node_modules/openzeppelin-solidity/contracts/token/ERC20/StandardToken.sol";

contract MyCoin is StandardToken {
  string public name = "MyCoin";
  string public symbol = "MC";
  uint public decimals = 18;
  uint public INITIAL_SUPPLY = 10000 * (10 ** decimals);

  function ExampleToken() {
    totalSupply_ = INITIAL_SUPPLY;
    balances[msg.sender] = INITIAL_SUPPLY;
  }
}

This helps to ensure that our contracts are secure and our methods are properly asynchronous.

Truffle, and Ganache

Truffle provides a suite of tools for testing and developing Ethereum.

Of these, Ganache provides one of the simplest ways to set up a robust testing environment quickly. Download the Ganache GUI distribution and spin it up. You should see it populated with fake accounts and balances:

Ganache

We can then configure our application to use Ganache by ensuring that our Truffle provider configuration matches our Ganache host and port settings like so:

Truffle

By running the following Bash commands:

    $ truffle init
    $ truffle compile

We can create a Truffle project and then compile our contracts. After compilation, smart contracts exist as Application Binary Interfaces or ABI's which allows them to be used easily through JSON-RPC and in JavaScript as JSON.

Our Example contract ends up looking like:

{
  "contractName": "Example",
  "abi": [
    {
      "inputs": [],
      "payable": false,
      "stateMutability": "nonpayable",
      "type": "constructor"
    }
  ],
  "bytecode": "0x60606040523415600e57600080fd5b603580601...",
    //...
}

We can then import or require the contract's ABI as needed!

React and Redux

Now that we have our Ethereum development and test environment set up, let's wrap it with a GUI and use Web3.js to interact with our local testnet!

We'll divide our app into three main views:

  1. A home landing page:

Screenshot.1.v2

At the bottom, you should see Google Maps in all its Australian glory!

  1. A general blockchain statistics page:

Screenshot.2.v2

We can hover over the listed addresses and choose one (by clicking) to be the address we deploy our contracts to.

Notably, this address will be saved into a custom encapsulated state store object:

export const SafeStorage = (state = encapsulatedStateObj, action) => {
  const type = action['type']
  switch (type) {
    case SAFE_SAVE:
      return set(action['v']['index'], action['v']['data'])
    case REMOVE:
      return remove(action['v']['index'])
    case GET:
      return Object.assign({}, encapsulatedStateObj[action['v']['index']])
    case CLEAR:
      return clear()
    default:
      return state
  }
}

This allows us to protect the address value from being accessed in localstorage but allowing it to be used throughout our other views.

The key we assign to store our address, myAddress, and its value are then available as this.props.myAddress everywhere the store provider has coverage:

//MyCoin.jsx
 deployContracts (e) {
    const addr = this.props.myAddress

    if (check(addr)) {
      try {
        const contract = eth.contract(this.state.web3),
          myCoin = contract.instance(MyCoinAbi, addr),
          wallet = contract.instance(MyCoinWalletAbi, addr)
            //...
      } catch (ex) {
        console.log(ex)
      }
    }
    e.preventDefault()
  }
  1. A page that lets us deploy the smart contract we built above:

Screenshot.3

Web3

The main way that we link our React app to our Truffle testnet is through Web3.js. Web3.js abstracts intercommunication methods inherent to every Ethereum node (which communicate primarily through JSON-RPC).

To make things easy, let's set up a facade that will simplify our code reuse.

To connect our client to our testnet we'd do the following:

const web3 = require('web3')
const w = new web3.providers.HttpProvider("http://localhost:7545")

Then, for general blockchain methods like getting the current block number we'd have something like:

blockchain: web3 => {
    return {
        block: blockHash => web3.eth.getBlock(blockHash),
        currentBlockNumber: async () => {
            let response = await web3.eth.getBlockNumber()
            console.log(response)
            return await response
        }
    }
}

This we can then call elsewhere by passing in our active web3 connection:

const web3 = require('web3')
const w = new web3.providers.HttpProvider("http://localhost:7545")
eth.blockchain(w).currentBlockNumber().then(blockNumber => {
    resolve(blockNumber)
})

Ditto for the list of current accounts:

accounts: async web3 => await web3.eth.getAccounts(console.log)
const web3 = require('web3')
const w = new web3.providers.HttpProvider("http://localhost:7545")
eth.accounts(w).then(accounts => {
    //...
})

Working with contracts can get a little tricky. To deploy our MyCoin contract we have to import the correct ABI and Bytecode:

import { MyCoinAbi } from '../../../../production_bindings/abiMappings'
import { MyCoinBytecode } from '../../../../production_bindings/bytecodeMappings'

Our facade supports two key methods - one to create a new contract instance and another to deploy such an instance to the testnet:

instance: (abi, address) => new web3.eth.Contract(abi, address),
deploy: async (contract, bytecode, args, gas) => await contract.deploy({ "data": bytecode, "gas": gas || 2000000, "arguments": args || [] })

... which we actually do like so:

const web3 = require('web3')
const w = new web3.providers.HttpProvider("http://localhost:7545")
const contract = eth.contract(this.state.web3), myCoin = contract.instance(MyCoinAbi, YOUR_ADDRESS)
contract.deploy(myCoin, MyCoinBytecode).then(deployedCoinObject => {
    //...
})

That's it! We've deployed our minimum viable coin to our testnet. You can switch out the testnet for the main Ethereum network or another testnet (like Infura, Kovan, or the official Ropsten testnet) by modifying the Truffle configuration settings!

Special Shout-Outs

Thanks a lot to the great folks at Unsplash who provide outstanding API's and static content.

In particular, the work of Eberhard Grossgasteiger and James Donovan is both highly appreciated and showcased in the code example available over on GitHub!