介绍

区块链是由一串使用密码学方法产生的数据块组成的,每一个区块都包含了上一个区块的哈希值(hash),从创始区块(genesis block)开始连接到当前区块,形成块链(类似数据结构中的链表).每一个区块都确保按照时间顺序在上一个区块之后产生,否则前一个区块的哈希值是未知的。

其优势在于:

  • 完全分布式的,无中心节点(单点故障)
  • 任何节点都可以创建交易。在经过一段时间的确认之后,就可以合理地确认该交易是否有效。
  • 修改交易记录的成本非常高

区块链也是比特币等技术的基础。它也是一种非常重要的新思想,促使人们对现有的网络,社会,经济等进行重新思考。

区块结构

头结构

大小(bytes) 字段 描述
4 版本 版本号
32 父区块哈希值 引用区块链中父区块的哈希值
32 merkle 根 该区块交易的merkle树根的哈希值
4 时间戳 该区块产生的近似时间(精确到秒的unix时间戳)
4 难度目标 该区块工作量证明算法的难度目标
4 Nonce 用于工作量证明算法的计数器

区块结构

大小(bytes) 字段 描述
4 区块大小 该字段之后的区块大小
80 区块头 区块头结构 (上面的大小之和)
1-9 可变整交易计数器 交易的数量
可变 交易 记录在区块里的交易信息

创世区块

比特币区块链的第一个区块,创建于2009年,我们称之为创世区块。它是比特币区块链里所有区块的共同祖先,这意味着你从任一区块,循链向后回溯,最终都将到达创世区块。每一个节点都“知道”创世区块的哈希值、结构、被创建的时间和里面的一个交易。因此,每个节点都把该区块作为区块链的首区块,从而构建了一个安全的、可信的区块链的根。

创世区块的哈希值为

0000000000 19d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

分叉

对于区块链中的任意一个区块,到达创世块的路径只有一条。然而,从创世块开始,会有分叉的情况出现。当创建两个区块的时间差只有几秒时,经常会创建出一个分叉区块。这时候不同的客户端可能接收到的区块不一样,然后各自在这个基础上继续拓展新的区块,直到有一个较长的出现,则作为主链条.其他的视为无效.

如上图所示,绿色区块为创世区块。黑色区块为主区块(主链条),紫色的称为 orphan blocks. 主链条的累积工作量是最大的,并不总是区块长度(高度)最长的。

Proof-of-work(工作量证明)

区块链从第一个区块开始,依赖于旷工们去拓展链条的长度。矿工们都进行一些数学计算,谁先算出一个合法的目标数值就可以宣称自己挖到了一个新的Block.这种检验的方式可以成为“工作量证明”(以下简称为POW).POW在blockchain之前就已存在,应用于垃圾邮件过滤以及防范拒绝服务攻击扥等。其基本原理都是相同的,但不同的系统会应用不同的hash算法以及进行不同长度的难度调整。下面以垃圾邮件的过滤为例来简要说明一下:

邮件Header

基本原理: 发送邮件的人需要在邮件的Header里加一条,里面是一个字符串,字符串里包含了发送的时间,接受者邮件,以及一个随机数等。这个字符串的哈希值必须符合一定的条件(前置N位为0).有了这样的要求,发送者必须经过暴力破解方式来尝试出一个合法的值,需要消耗一定的计算量。对于接受者来说,它可以很快地检验出来这个字符串是否满足要求(hash函数的单项特性).对于前者来说,增加N之后计算难度会成指数级增长,而对于后者来说校验时间是固定的。对于普通的邮件接收来说,这两个时间都是可以忽略不计(通常在s级之内)的。 但对于垃圾邮件的发送者来说,因为他需要发送大量的邮件,这个时间累积起来就很可观了。所以可以有效地进行垃圾邮件的过滤。

Header格式如下

X-Hashcash: 1:20:1303030600:adam@cypherspace.org::McMybZIhxKXu57jd:ckvi

  • 1 : Hashcash版本
  • 20 : hash值的前置0的个数
  • 1303030600 : 发送邮件的时间
  • adam@cypherspace.org: 接收者
  • (ext): 扩展(Version 1 里忽略)
  • McMybZIhxKXu57jd : 随机数的base64
  • ckvi: 计数器的base64

上面包含了接受者,所以对不于不同的邮件接收人,哈希值都要重新计算。

对于发送者来说:

  1. Header中包含了接受者,所以对不于不同的邮件接收人,哈希值都要重新计算。
  2. 首先设一个初始化的Header(包含一个初始的随机数),然后开始计算160位的SHA-1 hash值。如果前20位为0,那么成功生成一个合法的Header.如果不成功,增加计数器继续计算。平均下来每次大概需要2^20次计算能得到一个合法的值。

对于接收者来说:

  1. 根据Header内容计算哈希值,判断前二十位是否为0.这是有一个耗时固定的操作,而且远比发送者所耗资源要少
  2. 检查发送时间及邮件是否正确
  3. 将hash值入库,如果已经存在,则视为非法

在Linux/Mac上可以用openssl的命令来进行一个简单地校验:

echo -n 1:52:380119:calvin@comics.net:::9B760005E92F0DAE | openssl sha1
0000000000000756af69e2ffbdb930261873cd71

(注意52是要求二进制的0,上面的结果是13位10进制的)

Bitcoin

挖矿的流程与上面非常类似,只是具体的变量不同. 挖矿的公式可以概括为如下所示:

SHA256(SHA256(version + prev_hash + merkle_root + ntime + nbits + x )) < TARGET

目的就是找到一个合适的x(0~2^32)

  • SHA256: hash算法
  • versio: block的版本
  • prev_hash: 上一个block的hash值
  • merkle_root: 需要写入的交易记录的hash树的值
  • ntime: 更新时间
  • nbits: 当前难度

TARGET越小,解出x的难度就越大(类比于前面的邮件的例子就是前置的0越多,计算的次数越多).

一旦你找到了x,你就可以广播一个新的block,其他客户端会验证你的block是否合法。如果你的block被接受,由于每个block中的第一笔交易必须是将新产生25个比特币发送到某个地址(public key),当然你会把这个地址设为你所拥有的地址来得到这25个比特币。

REF

  1. Wiki
  2. Hashcash