Very Simple Blockchain Implementation in Ruby

1. Why I implemented it in Ruby

I created simple version of blockchain in Ruby.

This is because I read this article “Learn Blockchains by Building One” and I’m impressed with this. It creates simple blockchain in Python less than 200 lines of code. Then I thought why not in Ruby?

For the engineers, it is easier to figure out something by creating simple one by coding, isn’t it?

2. Implement blockchain in Ruby

Just implement it in Ruby one by one.

Complete version -> https://github.com/takp/blockchain-ruby

It looks long because it’s all inside one fiile, but it is simple less than 200 lines of code.

3. Run

3.1 Preparation for run

After git clone it to local, run bundle install and install necessary gems.

$ git clone git@github.com:takp/blockchain-ruby.git
$ cd blockchain-ruby/
$ bundle install
$ bundle exec ruby blockchain.rb
[2018-01-09 21:49:25] INFO  WEBrick 1.4.2
[2018-01-09 21:49:25] INFO  ruby 2.5.0 (2017-12-25) [x86_64-darwin16]
== Sinatra (v2.0.0) has taken the stage on 4567 for development with backup from WEBrick
[2018-01-09 21:49:25] INFO  WEBrick::HTTPServer#start: pid=12067 port=4567

This will start Sinatra and become ready to accepet the requeset.

3.2 BlockChain’s State

You can know the blockchain’s state by requesting GET /chain. At this point, nothings are done so it returns only genesis block.

$ curl http://localhost:4567/chain

{
  "chain":[
    {
      "index":1,
      "timestamp":"2018-01-09 21:59:51 +0700",
      "transactions":[],
      "proof":1,
      "previous_hash":100
    }
  ],
  "length":1
}

3.3 Mining!

You can execute mining by requesting GET /mine. From the response, you can see the hash value is added to it.

$ curl http://localhost:4567/mine

{
  "message":"New Block Forged",
  "index":2,
  "transactions":[
    {
      "sender":"0",
      "recipient":"caedf4a87f7841838061dd7dffca2916",
      "amount":1
    }
  ],
  "proof":94813,
  "previous_hash":"84e609b88e68764ac4546cb807d7cf0e"
}

3.4 Add new transaction

You can add new transaction by requesting POST /transactions/new. The content of the transaction is sent by curl’s -d options.

$ curl -X POST -H "Content-Type: application/json" -d '{
 "sender": "d4ee26eee15148ee92c6cd394edd974e",
 "recipient": "someone-other-address",
 "amount": 5
}' "http://localhost:4567/transactions/new"

{
  "message":"Transaction will be added to Block 3"
}

Here, do mining again and add more transaction to the blockchain.

$ curl http://localhost:4567/mine
{
  "message":"New Block Forged",
  "index":3,
  "transactions":[
    {
      "sender":"d4ee26eee15148ee92c6cd394edd974e",
      "recipient":"someone-other-address",
      "amount":5
    },
    {
      "sender":"0",
      "recipient":"caedf4a87f7841838061dd7dffca2916",
      "amount":1
    }
  ],
  "proof":183390,
  "previous_hash":"91d2d1296158c7faf58a37ddc152593d"
}

3.5 Check the Blockchain’s State

Though the response looks longer, let’s investigate it again. You can find the 1st block to the 3rd block were chained.

$ curl http://localhost:4567/chain
{
  "chain":[
    {
      "index":1,
      "timestamp":"2018-01-09 22:04:06 +0700",
      "transactions":[],
      "proof":1,
      "previous_hash":100
    },
    {
      "index":2,
      "timestamp":"2018-01-09 22:04:11 +0700",
      "transactions":[
        {
          "sender":"0",
          "recipient":"caedf4a87f7841838061dd7dffca2916",
          "amount":1
        }
      ],
      "proof":94813,
      "previous_hash":"84e609b88e68764ac4546cb807d7cf0e"
    },
    {
      "index":3,
      "timestamp":"2018-01-09 22:06:40 +0700",
      "transactions":[
        {
          "sender":"d4ee26eee15148ee92c6cd394edd974e",
          "recipient":"someone-other-address",
          "amount":5
        },
        {
          "sender":"0",
          "recipient":"caedf4a87f7841838061dd7dffca2916",
          "amount":1
        }
      ],
      "proof":183390,
      "previous_hash":"91d2d1296158c7faf58a37ddc152593d"
    }
  ],
  "length":3
}

4. Reflection

It is very intuitive to write it down with the simple code. We can know how it adds a transaction and it confirms the block by calculating the hash value.

In the original version, there’s the consensus implementation, but I skipped it. I’ll implement it when I can!

Repository in Github: https://github.com/takp/blockchain-ruby

@takp