区块链 - 如何拖慢时间

1,050 阅读5分钟

有些环节,比如生成区块ID,需要拖慢时间,以便让各个节点生成ID结果的时间拉开差距,减少冲突的可能性。

采用的方法,是工作量证明(PoW)。就是让生成ID的过程中,需要首先做一个计算非常耗时,但是容易验证计算量确实发生的函数。

工作量证明的方法

做SHA运算就是一个耗时的任务。我们可以出一个这样的题目,让生成id过程中计算:

给定的一个基本的字符串"Hello, world!",可以在这个字符串后面附加一个的整数值,对变更后的字符串进行SHA256运算,如果得到的哈希结果)是以"0000"开头的,则验证通过。

为了达到这个工作量证明的目标。我们需要不停的递增nonce值,对得到的新字符串进行SHA256哈希运算:

"Hello, world!0" => 1312af178c253f84028d480a6adc1e25e81caa44c749ec81976192e2ec934c64
"Hello, world!1" => e9afc424b79e4f6ab42d99c81156d3a17228d6e1eef4139be78e948a9332a7d8
"Hello, world!2" => ae37343a357a8297591625e7134cbea22f5928be8ca2a32aa475cf05fd4266b7
...
"Hello, world!4250" => 0000c3af42fc31103f1fdc0151fa747ff87349a4714df7cc52ea464e12dcd4e9

按照这个规则,我们需要经过4251次计算才能找到恰好前4位为0的哈希散列。

解题方需要过4251次计算才能得到结果,而验证方只要一次运算即可验证答案正确。这符合工作量证明算法的基本标准。难以解答,但是容易验证。

区块链的应用

在区块链中,每个区块都有一个80字节的区块头,其中有一个字段nouce,和此案例中的nouce是一个概念。本案例的输入是hello,world!而区块链的工作量证明的输入是区块头。

创建区块ID中的解题过程,和本案例类似,归纳如下:

  1. 所有准备打包进区块的交易组成交易列表,通过Merkle Tree算法生成Merkle Root Hash
  2. 把Merkle Root Hash及其他相关字段组装成区块头,将区块头的80字节数据作为工作量证明的输入
  3. nonce是随机变化的整数。不停的变更区块头中的随机数即nonce的数值,并对每次变更后的的区块头做双重SHA256运算,将结果值与当前网络的目标值做对比,如果小于目标值,则解题成功,工作量证明完成。

术语

  1. 工作量证明需要有一个目标值。

比特币工作量证明的目标值(Target)的计算公式如下:

目标值 = 最大目标值 / 难度值

目标值的最大值为一个恒定值:

0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 
  1. 难度值

区块大约每10分钟生成一个。然而全网算力是变化的,如果想要新区块的产生保持都基本这个速率,难度值必须根据全网算力的变化进行调整。

难度的调整是在每个完整节点中独立自动发生的。每2016个区块,所有节点都会按统一的公式自动调整难度,也就是说,如果区块产生的速率比10分钟快则增加难度,比10分钟慢则降低难度。这个公式为:

新难度值 = 旧难度值 * ( 过去2016个区块花费时长 / 20160 分钟 )

根据实际时长与期望时长的比值,进行相应调整(或变难或变易)。

  1. 区块头

大小为80字节,由以下内容构成:

4字节的版本号
32字节的上一个区块的散列值
32字节的Merkle Root Hash
4字节的时间缀(当前时间)
4字节的当前难度值
4字节的随机数组成。

区块包含的交易列表则附加在区块头后面,其中的第一笔交易是coinbase交易,这是一笔为了让生成区块的电脑获得奖励及手续费的特殊交易。

  1. Merkle Tree算法

用来保证数据不可篡改。MerkleTree是基于数据HASH构建的一个树。特点为:

  1. 数据结构是一个树,可以是二叉树,也可以是多叉树(本BLOG以二叉树来分析)
  2. Merkle Tree的叶子节点的value是数据集合的单元数据或者单元数据HASH。
  3. Merke Tree非叶子节点value是其所有子节点value的HASH值。

任何一个数据值的修改都会导致最终的Merkle Root Hash和修改前的Merkle Root Hash不一样,从而任何篡改都会被发现。一个区块一旦打包完毕,就是无法篡改的。

参考:

Merkle Tree算法详解 blog.csdn.net/yuanrxdu/ar… 此文章以快速找到两个目录的不同文件为案例。