Ruby
Blockchain

Rubyでブロックチェーンを実装してみる(進行中 1/3くらい)

Swiftでブロックチェーンを実装してみる

この記事を読んで、これまで仮想通貨の投資や自動売買に手を出していましたが、ブロックチェーンの技術を知ったかぶりしていたな・・・と痛感しました。

そこで、この記事のオマージュとして、普段使うRubyでブロックチェーンを実装してみたいと思います。恐縮ですが、これは学習記録です。(リファクタリングのご指摘、ぜひいただきたく!)

原典は

Learn Blockchains by Building One

許可をもらった日本語訳もあるようです。

ブロックチェーンを作ることで学ぶ

今回は、英語版の原典を参照しつつ、日本語訳もちら見しています。

最初に

blockchain is an immutable, sequential chain of records called Blocks. They can contain transactions, files or any data you like, really. But the important thing is that they’re chained together using hashes.

ブロックチェーンの定義です。ブロックチェーンとは、一度作られると変更することのできない、連続した(ブロックと呼ばれる)記録のチェーンのことである。この記録には、取引やファイル、好みの様々なデータ形式を含むことが可能だ。本当に重要な点は、これらが、ハッシュを用いて連結されているという点だ。

I like learning by doing. It forces me to deal with the subject matter at a code level, which gets it sticking.

わ、わかる。。。手を動かし、抽象的な事柄をコードに落とし込むことで、理解が深まるのですよね。さあ、やっていきましょう。

ステップ1: ブロックチェーンを組み立てる

まずは、ブロックチェーンクラスを作ります。

下記が、ブロックチェーンクラスの設計図です。

クラスを初期化すると、クラスはブロックチェーンを保持するためのリスト、トランザクションを保持するためのリストをインスタンス変数に持つ。

blockchain.rb
class Blockchain
  def initialize
    @chain = []
    @current_transactions = []
  end

  def new_block
     # Creates a new Block and adds it to the chain
  end

  def new_transaction
    # Adds a new transaction to the list of transactions
  end

  def hash(block)
    # Hashes a Block
  end

  def last_block
    # Returns the last Block in the chain
  end
end

さて、ブロックとはどんなものなのでしょうか?

Each Block has an index, a timestamp (in Unix time), a list of transactions, a proof (more on that later), and the hash of the previous Block.

それぞれのブロックは、インデックス、タイムスタンプ(UnixTime)、取引のリスト、証明、そして、一つ前のブロックのハッシュを含んでいます。

これがブロックのサンプルです。

block = {
    index: 1,
    timestamp: 1506057125.900785,
    transactions: [
        {
            sender: "8527147fe1f5426f9dd545de4b27ee00",
            recipient: "a77f5cdfa2934df3954a5c7c7da5df1f",
            amount: 5,
        }
    ],
    proof: 324984774000,
    previous_hash: "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
}

そして、ここ大切ですね。

At this point, the idea of a chain should be apparent—each new block contains within itself, the hash of the previous Block. This is crucial because it’s what gives blockchains immutability: If an attacker corrupted an earlier Block in the chain then all subsequent blocks will contain incorrect hashes.

ブロックチェーンのコアアイデアとは、前のブロックのハッシュを保持することにより、チェーン全体が不変のものとなる、ということです。(ちょっと日本語にしずらいですが・・・)

では、それぞれのメソッドの中身を実装していきましょう。

blockchain.rb
require 'digest/sha2'

class Blockchain
  def initialize
    @chain = []
    @current_transactions = []
  end

  def new_block(proof, previhous_hash=nil)
    # Creates a new Block and adds it to the chain
    block = { index: @chain.length + 1,
              timestamp: Time.now.utc.to_i,
              transactions: @current_transactions,
              proof: proof,
              previhous_hash: previhous_hash || hash(@chain.last),
            }

    @current_transactions = []
    @chain.push(block)
    block
  end

  def new_transaction(sender, recipient, amount)
    # Adds a new transaction to the list of transactions
    @current_transactions.push({ sender: sender, recipient: recipient, amount: amount })
    last_block.nil? ? 1 : last_block[:index] + 1
  end

  def hash(block)
    # Hashes a Block
    Digest::SHA256.hexdigest(block.to_s)
  end

  def last_block
    # Returns the last Block in the chain
    @chain.last
  end
end

だいぶブロックチェーンの中身が具体的になってきましたね。。。
これで全体の1/3くらいでしょうか。

今日はここまで。明日23日以降少しずつ進めていきます。