Tutorial & Homework 1

Author

Yan Ren

Published

September 23, 2022

Components of Blockchains

Blocks

A blockchain is a chain of blocks. Hence, we first describe a block. A block is a container for data. In its simplest form it contains:

  • an identification number
  • a timestamp of block creation
  • a bunch of data
  • a reference to the previous block (parent block) in the chain

Here is an block example which contains only the basic information of a block:

block <- list(number = 3,
             timestamp = "2018-10-01 17:24:18 CEST",
             data = "London",
             parent = 2)

Hash

A hash helps to ensure the integrity of a block by connecting it to the other blocks in the chain. A hash function takes something as an input and gives you a unique, encrypted output. Use R package cli to generate hashed output given an input.

library(cli)
hash_sha256("I Love Data Science")
[1] "5e5240b063d3a4419d0e9558a0a4fc990e65761f9d375656a9abd665162a1fd9"

Then the block with the hash value should be modified as:

block <- list(index = 1,
              timestamp = "2018-01-05 17.00 MST",
              data = "some data",
              previous_hash = 0,
              new_hash = NULL)

Notice that in this case, the parent of the block is identified by its hash value instead of parent index. Now let’s build a function that create the hash value using the basic information of the block. The hash value itself becomes one property of the block as well.

#Function that creates a hashed "block"
hash_block <- function(block){
  # the hash code contain all info included in the block
  block$new_hash <- hash_obj_sha256(c(block$index,
                               block$timestamp,
                               block$data,
                               block$previous_hash))
  return(block)
}

Build a Blockchain

Now that we have all necessary components for a block chain, now we try to build an actual blockchain. Bofore the iteration to add blocks one by one, a genesis block is needed to start with. A genesis block is nothing different from all other blocks but with no parent identifier because there is no parent block for it. It can be defined as:

# Define Genesis Block (index 1 and arbitrary previous hash)
block_genesis <- list(index = 1,
                       timestamp = Sys.time(),
                       data = "Genesis Block",
                       previous_hash = "0")

Based on the genesis block, we can generate new blocks as

#A function that takes the previous block and normally some data (in our case the data is a string indicating which block in the chain it is)
gen_new_block <- function(previous_block){

  #Create new Block
  new_block <- list(index = previous_block$index + 1,
                    timestamp = Sys.time(),
                    data = paste0("this is block ", previous_block$index +1),
                    previous_hash = previous_block$new_hash)

  #Hash the new Block
  new_block_hashed <- hash_block(new_block)

  return(new_block_hashed)
}

Last step, assemble all blocks in the chain.

blockchain <- list(block_genesis)
previous_block <- blockchain[[1]]

# How many blocks should we add to the chain after the genesis block
num_of_blocks_to_add <- 5

# Add blocks to the chain
for (i in 1: num_of_blocks_to_add){
  block_to_add <- gen_new_block(previous_block) 
  blockchain[i+1] <- list(block_to_add)
  previous_block <- block_to_add

  print(cat(paste0("Block ", block_to_add$index, " has been added", "\n",
             "\t", "Hash: ", block_to_add$new_hash)))
}
Block 2 has been added
    Hash: a4a87460569d803f5cd005388a88087d4eb29b596b4d04612b828fb3144f5231NULL
Block 3 has been added
    Hash: 73153233345b30c24a3cfc68d3d984785b6934f3409eeea71091e1e051ef4764NULL
Block 4 has been added
    Hash: a4e55369ee9009adca2beaf1daeb17d2163fb4cfe3d4b9e844e7147886da234eNULL
Block 5 has been added
    Hash: b0cae335f679bca2cdddea701bfd86364234c1bffb7cf76d20a5d1e8acb2ade9NULL
Block 6 has been added
    Hash: 2f365aa486c1088c96f11f1fa530353b52c3cd8cfd203a79f843e6c58ff67911NULL

Homework

Question 1 - Hash

  1. Compare the difference of function hash_obj_sha256 and hash_sha256 in cli function. Try to change the code of the tutorial from using hash_obj_sha256 to hash_sha256 and see what will happen.

  2. There are also another package called digest to generate hash values. Run the code like the one below and pick the one you like.

library(digest)
library(cli)

hash_sha256("some hashes")
hash_obj_sha256("some hashes")
digest("some hashes", "sha256")

Question 2 - Validation

How do you validate a blockchain? Let’s also write a validation function for the blockchain. For now, we only check that the parent field of a non-genesis block references to the previous block in the chain. If the blockchain is valid, we should get TRUE and FALSE in other cases.

  1. Write the validation function using R with the blockchain built in the tutorial.
  2. Change some properties in a block and validate the blockchain again