目录

用R语言编码理解区块链的数据形式

参考资料

Understanding Blockchains by Coding One in R:这篇文章使用了另外一个proof-of-work算法,有助于理解设计和评估算法的思路。

Building your own blockchain in R:这篇文章非常详细,并且在本地建立了可交互的API。

整体思路
  1. 区块链中的每一个block在R中使用一个list表示,包含需要储存的内容;

  2. 新建的block通过将前一个block的内容取hash值来确保前一个block的内容不被修改,目前的算力下不能通过穷举倒推出hash值代表的内容;

  3. 加入proof-of-work算法来增加建block的难度,即在每个block中加入额外的验证来判断新block是否有效。

建立第一个block

数据类型list可以在一个对象中存放多个不同类型的数据。

一个block中,除了需要存储的数据,还有时间、block序号、前一个block的hash和用来校验proof-of-work的字段。

1# Create a list to store our blockchain
2blockchain <- list()
3
4# Create the first block in the blockchain
5blockchain[[1]] <- list(index = 1,
6                       timestamp = Sys.time(),
7                       data = "Genesis Block",
8                       previous_hash = "0",
9                       nonce = 0)

计算单个block的hash

使用digest计算一个block的hash:

1# Function to calculate the hash of a block
2hash_block <- function(block) {
3  return(digest::digest(toString(block)))
4}

“挖矿”函数

通常说的“挖矿”即通过proof-of-work算法的校验新建一个block。BTC使用的校验是新建block的hash满足开头为连续的$n$个0,$n$通过过去2周实际新建的block数量调整,目标是达到平均每10分钟新建一个block。

最新区块
在本文撰写时,BTC.com上播报的最新区块高度760,446,hash为00000000000000000004ee4fcb027dce239c91568cbbc367790a26c06d5b5e2c。这是以16进制表示的256Bit,第一个4表示为0100,因此当前校验要求的前导0个数为 77 / 256.

在单个block中加入一个计数器字段nonce,通过不断穷举nonce使这个block的hash满足校验。

以$n=4$ (16进制表示) 为示例,函数的输入参数为当前区块链和新block需要存储的数据,输出为增加了1个block的区块链。

 1# Function to mine a new block
 2mine_block <- function(blockchain, data) {
 3  # Get the last block in the blockchain
 4  last_block <- blockchain[[length(blockchain)]]
 5  
 6  # Create a new block
 7  new_block <- list(index = last_block$index + 1,
 8                    timestamp = Sys.time(),
 9                    data = data,
10                    previous_hash = hash_block(last_block),
11                    nonce = 0)
12  
13  # Find a nonce that satisfies the proof-of-work requirement
14  while(substr(hash_block(new_block), 1, 4) != "0000") {
15    new_block$nonce <- new_block$nonce + 1
16  }
17  
18  # Add the new block to the blockchain
19  blockchain[[new_block$index]] <- new_block
20  
21  return(blockchain)
22}

应用示例

以下是在区块链中新增block,存储自定义数据的示例。

1# Add some data to our blockchain
2blockchain <- mine_block(blockchain, "Block 1 Data")
3blockchain <- mine_block(blockchain, "Block 2 Data")
4blockchain <- mine_block(blockchain, "Block 3 Data")
5
6# View the blockchain
7blockchain