个性化阅读
专注于IT技术分析

通过在R中编写代码来理解区块链

本文概述

现在, 每个人都在谈论加密货币-感谢有关BitCoin的炒作。与是否存在比特币泡沫相比, 有趣的是, 该技术实际上如何工作以及其功能如何。比特币的故事始于2008年的白皮书《比特币:点对点电子现金系统》。在本文中, 作者中本聪(关于中本聪的真正争议仍然很大)介绍了一个革命性的新技术和理念:一种在称为区块链的东西上运行的去中心化电子货币。这个想法从这一点开始传播, 现在可以应用于许多其他领域。

我首先在牛津的BlockchainSociety会议上被介绍给区块链。那里的每个人都对这项新技术的潜力感到非常兴奋。公平地说, 它确实吸引人:一个分散的, 廉洁的货币交易, 合同或任何你喜欢的东西(例如, 无法破解的投票机)数据库。区块链对加密社区的承诺是, 它将以一种不再需要像银行或律师这样的第三方的方式彻底改变信任, 从而破坏整个行业, 我们只需要加密的力量。

尽管基本思想非常直观, 但是关于区块链如何在技术层面上实际工作的问题却很难理解。上周, 我在R博客上碰到了这篇文章, 其中BigData Doc完全在R中构建了一个区块链。在R中构建的区块链可能不是世界上最高效, 最实用的东西, 但这是理解编程和加密的一种好方法背后的原则。我也想理解它, 这就是为什么我在R中实现了一个较小版本的区块链:”如果你可以对其进行编码, 那么你当然可以理解”。

什么是区块链?

假设你的目标是以安全的方式存储一些数据。为此, 你首先将数据存储在一个称为块的容器中。就比特币而言, 每个区块包含数笔金融交易。当有新交易(或有新数据)时, 将创建一个新块并将其与以前的块一起添加以形成一个链-区块链。

让我们看一下区块链如何利用加密技术变得几乎不可破解。

1.块block

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

在开始构建区块链之前(也就是将不同的容器与数据链接在一起), 你需要了解另外两个概念:散列和工作量证明算法。

2.哈希

哈希通过将块连接到链中的其他块来帮助确保块的完整性。哈希函数将某些内容作为输入, 并为你提供唯一的加密输出。下面是一个示例:你给你的朋友一个难题”哪个统计程序更好:Stata或R?”然后为她提供正确解决方案的哈希值:” 71ec0b920622cf4358bbc21d6a8b41f903584808db53ec07a8aa79119304ce86″。现在, 只需将其答案输入到哈希函数(在你的情况下为SHA256算法)中, 她就可以自己检查是否有正确的答案:

    library("digest")

    digest("Stata" , "sha256") # first try
    ## [1] "3ac273f00d52dc9caf89cbd71e73e5915229a588117ca3441630089409ddb7bc"
    digest("R", "sha256") # second try
    ## [1] "71ec0b920622cf4358bbc21d6a8b41f903584808db53ec07a8aa79119304ce86"

这对你有什么帮助?

在这种情况下, 你不仅将有关块的信息(索引, 时间戳, 数据)输入到哈希函数, 而且还将前一个块的哈希输入。这意味着, 只有知道上一个块的哈希(如果使用之前的块的哈希创建等等), 你才可以计算有效的哈希。这为你提供了一个不变的, 顺序的块链。如果之后要更改一个块, 则必须再次计算顺序块的所有哈希。

    #Function that creates a hashed "block"
    hash_block <- function(block){
      block$new_hash <- digest(c(block$index, block$timestamp, block$data, block$previous_hash), "sha256")
      return(block)
    }

3.工作量证明

如果区块链中必须存储大量信息, 则需要创建许多新块。在许多情况下, 你想控制创建多少个新块。例如, 在加密货币的情况下, 如果每秒可以创建无限数量的硬币, 则硬币将失去其价值。

因此, 我们添加了一个所谓的”工作量证明”(PoW)算法, 该算法控制了创建新块的难度。 “证明”是指计算机已经执行了一定数量的工作。实际上, 目标是创建一个难以创建但易于验证的项目。我将以下”任务”用作PoW:找到下一个可以被99整除并可以被最后一个块的证明号整除的数字。

    ### Simple Proof of Work Alogrithm
    proof_of_work <- function(last_proof){
      proof <- last_proof + 1

      # Increment the proof number until a number is found that is divisable by 99 and by the proof of the previous block
      while (!(proof %% 99 == 0 & proof %% last_proof == 0 )){
        proof <- proof + 1
      }

      return(proof)
    }

对于像BitCoin或以太坊这样的区块链, 创建新区块的工作是由所谓的矿工完成的。当必须创建一个新块时, 会将计算问题发送到网络。解决PoW问题的矿工首先创建一个新区块, 并以比特币作为奖励(这是实际创建新BitCoins的方式)。寻找新的正确证据的”彩票”确保了创建新区块的权力是分散的。当一个新的区块被挖掘出来时, 它被发送给每个人, 这样网络中的每个节点都会拥有最新区块链的副本。网络中最长的区块链(“投入最多的工作”)是区块链的有效版本的想法称为”分散共识”。

在使用BitCoin的情况下, PoW问题涉及到寻找产生带有一定数量的前导零的散列的数字的问题(我发现的最佳解释是来自Savjee的视频)。为了说明计算速度的提高和网络中矿工数量的变化, 可以对PoW的难度进行调整, 以将创建新区块的时间保持在大约十分钟左右。

4.添加新块

现在你知道了一个块的外观, 如何使用散列将块链接在一起, 以及PoW如何控制创建新块的步伐。因此, 让我们将其放到一个函数中:

    #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){

      #Proof-of-Work
      new_proof <- proof_of_work(previous_block$proof)

      #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, proof = new_proof)

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

      return(new_block_hashed)
    }

在开始构建区块链之前, 你需要在某个地方启动链。这是使用所谓的创世纪模块完成的。它不包含任何数据以及用于证明和先前哈希的任意值(因为没有先前的块)。

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

5.构建区块链

现在你可以开始构建区块链了。你可以从Genesis块开始, 然后使用循环添加一些块。

    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", "Proof: ", block_to_add$proof, "\n", "\t", "Hash: ", block_to_add$new_hash)))
      }
    ## Block 2 has been added
    ##  Proof: 99
    ##  Hash: 7d3dfbb58b410838769f6080dbc62a44a4c5d411a41048c4e597d26dccd1cd38NULL
    ## Block 3 has been added
    ##  Proof: 198
    ##  Hash: 4f8bdd79d751f9e9829c14c52a737f257285b61e54b29531dd59bf1a530f1097NULL
    ## Block 4 has been added
    ##  Proof: 396
    ##  Hash: 512b877c4ff92605d9fe10ac73ced20f748742964f306c211c4691f15425a26eNULL
    ## Block 5 has been added
    ##  Proof: 792
    ##  Hash: a3baaa025186c5bcb2238a888bc65e705ffe73c17dc5c8f26ee337fd62867993NULL
    ## Block 6 has been added
    ##  Proof: 1584
    ##  Hash: d12c3f54c14f3287a9f31ab542271197ba6a658cee561a9289819dd563fe4991NULL

如果要添加更多的块, 则会注意到它花费的时间越来越多。原因是证明数量成倍增加。

区块链R

对于像BitCoin这样的加密货币, 这将是一个问题, 因为创建新区块的时间或多或少应该是恒定的(对于BitCoin, 大约为10分钟)。因此, 必须连续调整PoW的难度, 以解决在给定时间网络中计算速度的提高和矿工数量的变化。

最后, 这是你链中一个区块的样子:

    blockchain[[5]]
    ## $index
    ## [1] 5
    ## 
    ## $timestamp
    ## [1] "2018-02-08 12:02:56 GMT"
    ## 
    ## $data
    ## [1] "this is block 5"
    ## 
    ## $previous_hash
    ## [1] "26cdc16a4560df5fa2fd521dbca22670e2475c35d3dd90781872bee98a164eef"
    ## 
    ## $proof
    ## [1] 792
    ## 
    ## $new_hash
    ## [1] "2eef25bf0bc4ee81e8c7cd1dfda65855b4ba32aba218d8c525a03a72b3454d74"

本文总结

在这篇小文章中, 你创建了最小的区块链。主要目标是介绍区块链的外观, 并介绍其背后的一些核心概念。理解密码学的天才应用确实表明了人们为什么对区块链的可能性如此兴奋。

要使区块链投入生产, 还需要做更多的工作:设置API, 使用公钥-私钥对创建钱包, 数字签名等。区块链网络。

这个简短的介绍借鉴了Gerald Nash的博客文章, 他在Python中实现了”最细微​​的区块链”。我在R中实现了它, 并添加了Daniel van Flymen的PoW实现。

为了更深入地研究区块链, 我推荐中本聪(Satoshi Nakamoto)撰写的关于BitCoin的精彩原始白皮书, 以及BigData Doc的博客文章。

如果你对此博客帖子有任何想法或回应, 请随时在Twitter上与我联系:你可以在@jj_mllr上找到我, 或者查看@CorrelAid, 这是一个年轻的数据分析人员网络, 希望通过更多方式改变世界。包容, 集成和创新的数据分析方法。

赞(0)
未经允许不得转载:srcmini » 通过在R中编写代码来理解区块链

评论 抢沙发

评论前必须登录!