A Rudimentary Blockchain Written in Crystal Part 1

in SteemAlive4 years ago

image.png

So, what is a blockchain? It’s a list of blocks linked and secured by cryptographic hashes.

Blockchains have become more practical today due to the reduced sized of and increased amount of space in hard drives.

Not too long ago, it was a lot less practical. Each full node on the Bitcoin network will have a copy of the ENTIRE blockchain (which is something like 150GB+)! The reason for that massive size is due to the chain storing every transaction that has ever occurred since it's inception.

Building CrystalChain

I'm going to write this as a brief run-through of the code and how a blockchain's core structure is set up.

There are many different hashing algorithms, but for this project, I will be using SHA256, which is the one used in Bitcoin.

Each block is stored with a timestamp and an index.

Like Bitcoin, each block’s hash will be a cryptographic hash of the block’s (index, timestamp, data, and the hash of the previous block’s hash previous_hash).

block.cr

module CrystalChain
  class Block
    include ProofOfWork
    include JSON::Serializable
    property current_hash : String, index : Int32, 
             nonce : Int32, previous_hash : String

    def initialize(index = 0, 
                   data = "data", 
                   transactions = [] of Transaction, 
                   previous_hash = "hash")
      @data = data
      @index = index
      @timestamp = Time.utc
      @previous_hash = previous_hash
      @nonce = proof_of_work
      @current_hash = calc_hash_with_nonce(@nonce)
      @transactions = transactions
    end

    def self.first(data = "Genesis Block")
      Block.new(data: data, previous_hash: "0")
    end

    def self.next(previous_block, transactions = [] of Transaction)
      Block.new(
        transactions: transactions,
        index: previous_block.index + 1,
        previous_hash: previous_block.current_hash
      )
    end

    private def hash_block
      hash = OpenSSL::Digest.new("SHA256")
      hash.update("#{@index}#{@timestamp}#{@data}#{@previous_hash}")
      hash.final.hexstring
    end
    
    def recalculate_hash
      @nonce = proof_of_work
      @current_hash = calc_hash_with_nonce(@nonce)
    end
  
  end
end

This file will create all of our blocks. Each block contains the following data:

  1. index: indicates the index of the block ex: 0, 1, 2 , 3, etc.
  2. timestamp: timestamp in epoch, number of seconds since 1 Jan 1970
  3. data: the actual data that needs to be stored on the blockchain.
  4. previous_hash: the hash of the previous block, this is the chain/link between the blocks
  5. nonce: this is the number that is to be mined/found.
  6. current_hash: The hash value of the current block, this is generated by combining all the above attributes and passing it through our hashing algorithm

Also, in this block of code, the self.first method starts the blockchain and generates the genesis block of said chain like so:

#CrystalChain::Block:0x10b13ac80 
@current_hash="acb701a9b75a061888910d34df8a7155a8c888910d34df692db92355964d54e", 
@data="Genesis Blockerinooo", @index=0, @timestamp=2020-07-13 17:54:02 +03:00, @previous_hash="0"

After the first method runs, all other blocks are created by the next method.

By storing the previous hash of each block, a block can’t be modified without changing the hash of every consecutive block.

If the data in a block is changed, all hashes of the future blocks must be changed as well. This is because the hash of the block depends on the value of the previous hash of the previous block.

These hashes act as a cryptographic proof and helps ensure that once a block is added to the blockchain it cannot be replaced or removed.

That concludes the first post of this blockchain series. In the next post I will be going over the proof of work and how the blocks are mined.

If you are interested in checking out the code and/or playing around with it, you can find it on my GitHub at the link below:

https://github.com/nolyoi/crystal-chain

Original post from my blog: https://nolanm.dev/posts/10-a-rudimentary-blockchain-written-in-crystal