- Creating a block
- Creating a chain for blocks and validation
- 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