Blockchain
文章目录
介绍
区块链是由一串使用密码学方法产生的数据块组成的,每一个区块都包含了上一个区块的哈希值(hash),从创始区块(genesis block)开始连接到当前区块,形成块链(类似数据结构中的链表).每一个区块都确保按照时间顺序在上一个区块之后产生,否则前一个区块的哈希值是未知的。
其优势在于:
- 完全分布式的,无中心节点(单点故障)
- 任何节点都可以创建交易。在经过一段时间的确认之后,就可以合理地确认该交易是否有效。
- 修改交易记录的成本非常高
区块链也是比特币等技术的基础。它也是一种非常重要的新思想,促使人们对现有的网络,社会,经济等进行重新思考。
区块结构
头结构
| 大小(bytes) | 字段 | 描述 |
|---|---|---|
| 4 | 版本 | 版本号 |
| 32 | 父区块哈希值 | 引用区块链中父区块的哈希值 |
| 32 | merkle 根 | 该区块交易的 merkle 树根的哈希值 |
| 4 | 时间戳 | 该区块产生的近似时间(精确到秒的 unix 时间戳) |
| 4 | 难度目标 | 该区块工作量证明算法的难度目标 |
| 4 | Nonce | 用于工作量证明算法的计数器 |
区块结构
| 大小(bytes) | 字段 | 描述 |
|---|---|---|
| 4 | 区块大小 | 该字段之后的区块大小 |
| 80 | 区块头 | 区块头结构 (上面的大小之和) |
| 1-9 | 可变整交易计数器 | 交易的数量 |
| 可变 | 交易 | 记录在区块里的交易信息 |
创世区块
比特币区块链的第一个区块,创建于 2009 年,我们称之为创世区块。它是比特币区块链里所有区块的共同祖先,这意味着你从任一区块,循链向后回溯,最终都将到达创世区块。每一个节点都“知道”创世区块的哈希值、结构、被创建的时间和里面的一个交易。因此,每个节点都把该区块作为区块链的首区块,从而构建了一个安全的、可信的区块链的根。
创世区块的哈希值为
分叉
对于区块链中的任意一个区块,到达创世块的路径只有一条。然而,从创世块开始,会有分叉的情况出现。当创建两个区块的时间差只有几秒时,经常会创建出一个分叉区块。这时候不同的客户端可能接收到的区块不一样,然后各自在这个基础上继续拓展新的区块,直到有一个较长的出现,则作为主链条.其他的视为无效.

如上图所示,绿色区块为创世区块。黑色区块为主区块(主链条),紫色的称为 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
上面包含了接受者,所以对不于不同的邮件接收人,哈希值都要重新计算。
对于发送者来说:
- Header 中包含了接受者,所以对不于不同的邮件接收人,哈希值都要重新计算。
- 首先设一个初始化的 Header(包含一个初始的随机数),然后开始计算 160 位的
SHA-1hash 值。如果前 20 位为 0,那么成功生成一个合法的 Header.如果不成功,增加计数器继续计算。平均下来每次大概需要2^20次计算能得到一个合法的值。
对于接收者来说:
- 根据 Header 内容计算哈希值,判断前二十位是否为 0.这是有一个耗时固定的操作,而且远比发送者所耗资源要少
- 检查发送时间及邮件是否正确
- 将 hash 值入库,如果已经存在,则视为非法
在 Linux/Mac 上可以用openssl的命令来进行一个简单地校验:
| |
(注意 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
文章作者 涯余
上次更新 2017-08-12