Crypto on Rails @ Hack Western 4

November 20, 2017

“Java Script is eating the world”

Returning from Hack Western 4 I worked with my team to build Horizon - a first generation machine to machine payments platform using Rails.

The following is an account of the events, mistakes, and frusterations experienced in building our app!

Why Rails and not Node you ask? I’ve been increasingly fascinated how so many successful startups have launched on Rails, and as a result have been motivated to learn Rails for a long time.

Stack Share

Despite debates about Rails’ relevance today in the age of Node.js I set out to answer the question myself during Hack Western 4.

Is Rails still a valuable tool today, and how does it stack up with new technologies?

But first.. what is Horizon all about?

Horizon: First Generation M2M Payments Platform

At a high level, Horizon tackles the future market for autonomous machine to machine payments.

In 10+ years it’s not hard to see that our smart toasters will be bartering with our electric sockets for the best rate they can get transacting in cryptocurrency or tokens such as Bitcoin or Ethereum.

While this is wonderful, on a higher enterprise scale say Uber level, how is a company supposed to manage 1000+ cryptocurrency accounts for 1000+ autonomous vehicles needing to pay for their gas, electricity, and parking?

Just as businesses have working capital today, autonomous machines will require working capital in the future.

Horizon solves this issue by being to IoT Working Capital what Amazon Web Services is to CPU Resource Containers. Users can create dedicated containers with a group of authorized IoT devices to draw from a single funded cryptowallet acting like a ‘bank account’ for requested transactions.

Ruby on Rails + Horizon

Using Rails we built a full front facing web app, backend API and attempted to interact with a private Ethereum Blockchain network.

Ideating and Building stage

The initial Balsamiq design was fairly simple. A dashboard a list of containers, a show view for each container, user profile, etc. We decided to keep it simple because the meat of the project would be in the backend API and blockchain modules.

Rails Win #1 One of the immediate benefits of using Rails is that it gives you a great vocabulary for talking about and building up a web application. The show, index, new, and edit actions coupled with their respective views in that convention over configuration mentality made it easy for us to white board up and toss together a few mockups to run against.

horizon dashboard whiteboard Mockup of Dashboard in Balsamiq (left) and mockup on the whiteboard (right) of app and actions.

Configuration

After our initial design of the app, we began determining our configurations and gem packages. We went with standard Gemfile suspects like Devise and embedded Haml, and additionally included some new faces:

  1. eth for key creation and signing transactions
  2. ethereum.rb for RPC calls to the Blockchain.
  3. coinbase for funding wallets via Coinbase (Sign up for free bitcoin!)
    # Gemfile
    gem 'rails', '~> 5.0.2'
    gem 'pg'
    // ..
    gem 'devise', '~> 4.2'
    gem 'simple_form', '~> 3.2', '>= 3.2.1'
    gem 'haml', '~> 4.0', '>= 4.0.7'
    gem 'bootstrap-sass'
    gem 'eth'
    gem 'ethereum.rb'
    gem 'coinbase

Building

For the most part tried and testing gems made it easy to get user authentication up, some decent styling and a functional web app going in the first 24 hours.

Building a Rails’ app feels very streamlined, and you seldom run into any major issues regarding traditional CRUD actions that can’t be overcome in 20 minutes of searching Google.

uber Container details for an Uber autonomous vehicle fleet

The basic structure of app composed of three modules:

Mod 1. Web App:
    ContainersController
        index, show, new, edit
    ProfilesController
        show
    PagesController
        index, aboutt,privacy
    DeviseController
        sign_up,login

Mod 2. API:
    ApiController
        /register
        /payments

Mod 3. Ethereum Blockchain 

The largest difficulty began arising through integrating the Ethereum Blockchain network calls into our app for actions. Scotia Bank Digital Factory was kind enough to host a private geth node for us to use.

While key and address creation via the eth gem seemed to work, we ran into issues regarding the ethereum.rb library and it’s ability to sign valid transactions.

Here’s some terminal output for the interactive ruby shell:

> require 'eth'
> require "ethereum.rb"

> client = Ethereum::HttpClient.new('http://52.242.26.191:8545')
# Private DF Node for event

> key = Eth::Key.new priv: '7b388eac4673607a570a6d878a34d110337cb1d3a544081796a59ef981012856'
# Private key generated from testrpc 

> client.transfer(key,'0x7456f537c1e90ef315db9d74a19ece2231a789aa',50000000000000000)

> IOError: invalid sender
    from ethereum.rb-2.1.8/lib/ethereum/client.rb:129:in `send_command'
    from ethereum.rb-2.1.8/lib/ethereum/client.rb:137:in `block (2 levels) in <class:Client>'
    from ethereum.rb-2.1.8/lib/ethereum/client.rb:102:in `transfer'
    from (irb):14
    from /ruby-2.4.0/bin/irb:11:in `<main>'

At first we thought the chainID used for signing transactions in the ruby-eth gem could be incorrect because we were using a private geth node. But changing that did us little good.

After testing numerous other methods of the library such as transfer_to, get_balance, eth_send_raw_transaction, we noticed a common theme that we could read from the blockchain but not write. This gave us a bit of insight that perhaps this portion of the library was outdated with regards to the newer versions of geth, and it turns out it might have been requiring geth 1.3, parity 1.5 or less. Supposedly there are some changes from geth v1.3 to 1.4 which may explain why things weren’t working but we didn’t have enough time to really look into it.

Rails Loses #1 Despite Ruby being an awesome language, it has much lower spread and accepted today compared to JavaScript or something similar. This means libraries syncing to highly evolving and experimental technology can become dated and slightly unusable very quickly.

We considered several other libraries including vtada-ethereum(most promising) but all proved to have too little documentation to execute on.

One learning gained from the experience was a new appreciation for sending transactions via JSON-RPC calls in terminal. Although we have web3js libraries now adays, I think diving into the yucky RPC calls themselves can teach you a lot about how Ethereum really works.

Pivoting

With 12AM ticking on the click we had about 9-10 hours left, so we decided to pivot to an alternate strategy: hosting a private Bitcoin Blockchain on Digital Ocean (Sign up for free credits!) and interacting with via bitcoin-ruby a gem.

horizon dashboard rails

One of the greatest parts about hackathons is the time pressure, forcing you to make decisions and try things you might have considered passing up before. For me, I had never experimented developing on cloud technology, so getting an Ubuntu box up and running was exciting and interesting to say the least!

Attempting to follow Sam Bowne’s tutorial on launching a private bitcoin blockchain from source, we explored and discovered several other interesting private chain projects including Multichain and Blockchain CLI.

mc

Realizing time running out of time we switched from a private Bitcoin node to attempting to deploy a Multichain demo on our droplet. We were successful in getting the Multichain node up, but didn’t have a chance to mimic and modify the bitcoin-ruby library to suit our needs for interacting with a Multichain node instead.

In The End

In the end, we still produced and executed on an interesting concept. Going from ideation, to white boarding, to design, to full front end in 24 hours. Our backend registration through our api was functional, and we even created a two IoT device simulation with our iOS phones mimicking the bartering of machine-to-machine transactions and payments request to horizon. (Code here).

If it’s granted that most applications don’t have to use technology which evolves every month, like the Blockchain, then from this experience, I think Rails certainly still has it’s place. It’s quick, it’s streamlined, it’s documented and very fun to use. However, I think the Rails community is seeing a decline and there is some increased interest in new frameworks such as Phoenix and Elixr, but it might be a while until we see full adoption and loss of rails.

Until then, I think Rails still serves as one of the quickest ways to build and launch a prototype and early scale a web app, and I will continue to use it - just like it was built to do back in 2004.