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.
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
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.
Mockup of Dashboard in Balsamiq (left) and mockup on the whiteboard (right) of app and actions.
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:
ethfor key creation and signing transactions
ethereum.rbfor RPC calls to the Blockchain.
coinbasefor 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
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.
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.
Here’s some terminal output for the interactive ruby shell:
> require 'eth' > require "ethereum.rb" > client = Ethereum::HttpClient.new('http://22.214.171.124: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
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.
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.
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.
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.
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.