Understanding Blockchain Programming with R


   In this post, we'll learn some of the key elements of blockchain programming in R. Blockchain is an organized collection of data. In this collection of data, a sequence of blocks is chained to each other. A block is a data container. All blocks are linked to each other by using hash and it starts from the genesis of a block. The tutorial covers:
  1. Creating a block
  2. Creating a chain for blocks and validation
  3. Source code listing

Creating a block

   The first block is a special one that is a starting point of the chain and it is called a genesis block. A block contains index, timestamp, parent, hash, and data as shown below.

block = list(number = 3,
              timestamp = "2019-04-01 17:24:18 JST",
              data = "Hello",
              parent = 2,
              hash="fa76210bdf56ea68a9bd9e081da193f763fe3395")
print(block)
$number
[1] 3

$timestamp
[1] "2019-04-01 17:24:18 JST"

$data
[1] "Hello"

$parent
[1] 2

$hash
[1] "fa76210bdf56ea68a9bd9e081da193f763fe3395"

Since every block contains a hash code, we'll start by writing the hash code generator. We can use 'digest' package to generate a hash code.

library(digest)

CreateHash = function(block)
{
  hashData = paste(block$Index, block$Timestamp, block$Data, block$Parent)
  return(digest(hashData, "sha256"))
}

As stated the first block will be a genesis, so we'll write genesis block function.

CreateGenesisBlock = function()
{
  genesis = list(Index = 0,
                 Timestamp = Sys.time(),
                 Data = NA,
                 Parent = NA)
   
  genesis$Hash = CreateHash(genesis)
  return(genesis)
}
 
genesisBlock = CreateGenesisBlock()
 
print(genesisBlock)
$Index
[1] 0

$Timestamp
[1] "2019-07-22 15:48:44 JST"

$Data
[1] NA

$Parent
[1] NA

$Hash
[1] "0cd6858a31f3825d70f2b22c705e43c248b7ed841d0763ff8f6ad300ed541d28"

Next, we'll write the block creating function.

CreateBlock = function(previousBlock, data)
{
   block = list(Index = as.numeric(previousBlock$Index)+1,
                Timestamp = Sys.time(),
                Data = data,
                Parent = previousBlock$Hash)
   block$Hash = CreateHash(block)
   return(block)
}
 
block1 = CreateBlock(genesisBlock, "Transfer 10$")
 
print(block1)
$Index
[1] 1

$Timestamp
[1] "2019-07-22 15:57:18 JST"

$Data
[1] "Transfer 10$"

$Parent
[1] "0cd6858a31f3825d70f2b22c705e43c248b7ed841d0763ff8f6ad300ed541d28"

$Hash
[1] "e0859763708368d2eb9185b9b8d22b82d73554b1b23686226aaa92c13a262213"



Creating a chain for blocks and validation


Next step is to collect all blocks in a chain object. The first block of a chain will be a genesis block. In R, we can collect the blocks simply in a list object. The chain must be in a valid order by connected right hash keys and data should not be duplicated. Here, we write a validation function to apply the above rules for the chain.

Validate = function(chain)
{
   ret=TRUE
   for(i in 2:length(chain))
   {
     current=chain[[i]]
     previous = chain[[i-1]]
     if(current$Parent != previous$Hash)
       ret=FALSE
     if(current$Hash != CreateHash(current))
       ret=FALSE
   }
   return(ret)
}

Next, we can write a function for adding data into the chain.

AddToChain = function(chain, data)
{
   if(is.null(chain))
     chain = list(CreateGenesisBlock())
   
   l=length(chain)
   previousBlock = chain[[l]]
   
   block= CreateBlock(previousBlock, data)
   temp = chain
   temp[[l+1]]=block
   if(Validate(temp))
     chain[[l+1]]=block
   
   return(chain)
}

We'll create a chain with the genesis block.

chain = list(CreateGenesisBlock())
length(chain)
[1] 1
 
str(chain)
List of 1
 $ :List of 5
  ..$ Index    : num 0
  ..$ Timestamp: POSIXct[1:1], format: "2019-07-22 16:02:43"
  ..$ Data     : logi NA
  ..$ Parent   : logi NA
  ..$ Hash     : chr "76b9181cc329e2017f50ed43df05551d4c327e8c3e7d8ea14dcaa69b3cf6a381"
 
print(chain)
[[1]]
[[1]]$Index
[1] 0

[[1]]$Timestamp
[1] "2019-07-22 16:02:43 JST"

[[1]]$Data
[1] NA

[[1]]$Parent
[1] NA

[[1]]$Hash
[1] "76b9181cc329e2017f50ed43df05551d4c327e8c3e7d8ea14dcaa69b3cf6a381"


Finally, we can start adding data into the blockchain.

chain = NULL
chain = AddToChain(chain, "Payment for coffee 3$")
chain = AddToChain(chain, "Transfer to Jack 20$")
chain = AddToChain(chain, "Recieved 50$")
 
length(chain)
[1] 4
 
str(chain)
List of 4
 $ :List of 5
  ..$ Index    : num 0
  ..$ Timestamp: POSIXct[1:1], format: "2019-07-22 16:12:37"
  ..$ Data     : logi NA
  ..$ Parent   : logi NA
  ..$ Hash     : chr "e8041c45fe41af474d701101bf79e255a4cb52b1d6e9a492c6e796863635d012"
 $ :List of 5
  ..$ Index    : num 1
  ..$ Timestamp: POSIXct[1:1], format: "2019-07-22 16:12:37"
  ..$ Data     : chr "Payment for coffee 3$"
  ..$ Parent   : chr "e8041c45fe41af474d701101bf79e255a4cb52b1d6e9a492c6e796863635d012"
  ..$ Hash     : chr "de5711e18c8e317b9f92c0bef6702e35a4f1bd49e4b718f5e1ebfdd7c08a8e98"
 $ :List of 5
  ..$ Index    : num 2
  ..$ Timestamp: POSIXct[1:1], format: "2019-07-22 16:12:37"
  ..$ Data     : chr "Transfer to Jack 20$"
  ..$ Parent   : chr "de5711e18c8e317b9f92c0bef6702e35a4f1bd49e4b718f5e1ebfdd7c08a8e98"
  ..$ Hash     : chr "c908e191080590f45ba018e6dbd9219132517c53fad049eaec2b229ca7eb3c52"
 $ :List of 5
  ..$ Index    : num 3
  ..$ Timestamp: POSIXct[1:1], format: "2019-07-22 16:12:37"
  ..$ Data     : chr "Recieved 50$"
  ..$ Parent   : chr "c908e191080590f45ba018e6dbd9219132517c53fad049eaec2b229ca7eb3c52"
  ..$ Hash     : chr "9b88f301c38793e754088e49ad93e4cd38cd2a233ccf7516e97aced5c5168aeb"

print(chain[2])
[[1]]
[[1]]$Index
[1] 1

[[1]]$Timestamp
[1] "2019-07-22 16:12:37 JST"

[[1]]$Data
[1] "Payment for coffee 3$"

[[1]]$Parent
[1] "e8041c45fe41af474d701101bf79e255a4cb52b1d6e9a492c6e796863635d012"

[[1]]$Hash
[1] "de5711e18c8e317b9f92c0bef6702e35a4f1bd49e4b718f5e1ebfdd7c08a8e98"


In this post, we've briefly learned blockchain programming basics in R. The full source code is listed below. Thank you for reading!


Source code listing

library(digest)
 
block = list(number = 3,
              timestamp = "2018-10-01 17:24:18 CEST",
              data = "Hello",
              parent = 2,
              hash="fa76210bdf56ea68a9bd9e081da193f763fe3395")
print(block)
 
CreateGenesisBlock = function()
{
   genesis = list(Index = 0,
                  Timestamp = Sys.time(),
                  Data = NA,
                  Parent = NA)
   genesis$Hash = CreateHash(genesis)
   return(genesis)
}
 
genesisBlock = CreateGenesisBlock()
print(genesisBlock)
 
CreateHash = function(block)
{
   hashData = paste(block$Index, block$Timestamp, block$Data, block$Parent)
   return(digest(hashData, "sha256"))
}
 
CreateBlock = function(previousBlock, data)
{
   block = list(Index = as.numeric(previousBlock$Index)+1,
                Timestamp = Sys.time(),
                Data = data,
                Parent = previousBlock$Hash)
   block$Hash = CreateHash(block)
   return(block)
}
 
block1 = CreateBlock(genesisBlock, "Transfer 10$")
print(block1)
 
AddToChain = function(chain, data)
{
   if(is.null(chain))
     chain = list(CreateGenesisBlock())
   
   l=length(chain)
   previousBlock = chain[[l]]
   
   block= CreateBlock(previousBlock, data)
   temp = chain
   temp[[l+1]]=block
   if(Validate(temp))
     chain[[l+1]]=block
   
   return(chain)
}
 
Validate = function(chain)
{
   ret=TRUE
   for(i in 2:length(chain))
   {
     current=chain[[i]]
     previous = chain[[i-1]]
     if(current$Parent != previous$Hash)
       ret=FALSE
     if(current$Hash != CreateHash(current))
       ret=FALSE
   }
   return(ret)
}
 
chain = list(CreateGenesisBlock())
length(chain)
str(chain)
print(chain)
 
chain = NULL
chain = AddToChain(chain, "Payment for coffee 3$")
chain = AddToChain(chain, "Transfer to Jack 20$")
chain = AddToChain(chain, "Recieved 50$")
length(chain)
str(chain)
print(chain[2])

No comments:
Post a Comment