本文个人博客地址:http://www.huweihuang.com/article/blockchain/blockchain-introduction/
区块链是一个去中心化的分布式数据库
,该数据库由一串使用密码学方法产生的数据区块有序链接而成,区块中包含有一定时间内产生的无法被篡改的数据记录信息。
区块中包含了数据记录、当前区块根Hash、前一个区块根Hash、时间戳以及其他信息。数据记录的类型可以根据场景决定,比如为资产交易记录、资产发行记录等。
从技术层面看,区块链是一个基于共识机制、去中心化
的公开数据库
,可以理解为分布式账本
。
共识机制
:指在分布式系统中保证数据一致性的算法。去中心化
:指参与区块链的所有节点都是权力对等的,所有人可以平等自由地参与区块链网络。公开数据库
:指所有人都可以看到过完的区块和交易,这也保证了造假和改写。从价值层面看,区块链是一个价值互联网
,用于传递价值。现有的互联网是一个信息互联网,基于TCP/IP协议传递信息。
1、公共区块链
公共区块链(Public Blockchain)
:指全世界任何人都可读取、可发送交易进行有效性确认,任何人都能参与其共识过程的区块链。公共区块链上的数据记录公开,共识过程的参与者通过密码学技术共同维护区块链数据的安全、透明、不可篡改。
公共区块链是完全分布式的区块链,区块链数据公开,用户参与程度高,易产生网络效应,便于推广。
公共区块链的典型应用有比特币
、以太坊
等。
2、联盟区块链
联盟(行业)区块链(Consortium Blockchain)
:指参与区块链的节点是事先选择好的,节点间通常有良好的网络连接等合作关系,区块链上的数据可以是公开也可以是内部的,为部分意义上的分布式,可视为“部分去中心化”。
3、私有区块链
私有区块链(Private Blockchain)
:参与的节点只有有限的范围,比如特定机构的自身用户,数据的访问及使用有严格的权限管理。完全私有的区块链中写入权限仅在参与者手里,读取权限可以对外开放,也可以被任意程度地限制。
区块链系统自下而上可分为六层结构:数据层、网络层、共识层、激励层、合约层和应用层。其中,数据层、网络层、共识层是区块链的必要元素,激励层、合约层、应用层不是区块链的必要元素。
数据层
:作为最底层封装了数据区块以及相关数据加密和时间戳等技术。网络层
:包括分布式组网机制、数据传播机制和数据验证机制等。共识层
:主要封装网络节点的各类共识算法。激励层
:它将经济因素集成到区块链技术体系,包括经济激励的发行机制和分配机制,主要出现在公链中。合约层
:它封装各种脚本、算法和智能合约。应用层
:封装了区块链的各种应用场景和案例。区块是一种被包含在公开账簿(区块链)里的聚合了交易信息的容器数据结构。它由一个包含元数据的区块头和紧跟其后的构成区块主体的一长串交易组成。区块头是80字节,而平均每个交易至少是250字节,而且平均每个区块至少包含超过500个交易。因此,一个包含所有交易的完整区块比区块头的1000倍还要大。
区块结构
大小 | 字段 | 描述 |
---|---|---|
4字节 | 区块大小 | 用字节表示的该字段之后的区块大小 |
80字节 | 区块头 | 组成区块头的几个字段 |
1-9 (可变整数) | 交易计数器 | 交易的数量 |
可变的 | 交易 | 记录在区块里的交易信息 |
区块头由三组区块元数据组成。
区块头结构
大小 | 字段 | 描述 |
---|---|---|
4字节 | 版本 | 版本号,用于跟踪软件/协议的更新 |
32字节 | 父区块哈希值 | 引用区块链中父区块的哈希值 |
32字节 | Merkle根 | 该区块中交易的merkle树根的哈希值 |
4字节 | 时间戳 | 该区块产生的近似时间(精确到秒的Unix时间戳) |
4字节 | 难度目标 | 该区块工作量证明算法的难度目标 |
4字节 | Nonce | 用于工作量证明算法的计数器 |
区块哈希值
是通过SHA256
算法对区块头进行二次哈希获得,作为区块的主标识符,可以唯一、明确地标识一个区块,任何节点通过对区块头进行哈希计算都可以获取该区块哈希值。
区块哈希值并不包含在区块的数据结构中,而是当区块被网络接收时由每个节点计算出来的。区块哈希值可能会作为区块元数据的一部分被存储在一个独立的数据表中方便更快的检索区块。
区块高度
表示区块在区块链中的位置,即距离第一个区块的位置。第一个区块的区块高度定义为0
,后续的区块高度在此基础上依次递增。可以类比为一个从低到高堆叠的箱子,第一个箱子的高度为0。
区块高度并不是区块的唯一标识符,因为可能出现区块链分叉
,导致同一个高度有2个或多个区块。即一个区块有唯一的一个区块高度,但一个区块高度不对应唯一的一个区块。
区块高度也不包含在区块数据结构中,当节点接收到比特币网络的区块时会动态识别该区块的区块高度。区块高度也可作为元数据存储在一个索引数据库表中以便快速检索。
创世区块
即区块链的第一个区块,每一个节点都“知道”创世区块的哈希值、结构、被创建的时间和里面的一个交易。因此,每个节点都把该区块作为区块链的首区块,从而构建了一个安全的、可信的区块链的根。
创世区块的哈希值为:
000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
也可在https://blockchain.info/block/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f查询。
在命令行使用比特币核心客户端:
$ bitcoind getblock 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
{
"hash":"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
"confirmations":308321,
"size":285,
"height":0,
"version":1,
"merkleroot":"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
"tx":["4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"],
"time":1231006505,
"nonce":2083236893,
"bits":"1d00ffff",
"difficulty":1.00000000,
"nextblockhash":"00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"
}
比特币的完整节点保存了区块链从创世区块起的一个本地副本(类似Git
的本地代码仓库副本),对于新接受的 区块,本地节点先验证该区块,如果验证通过则将该区块加入到该区块链中。为建立一个连接,一个节点将检查传入的区块头并寻找该区块的“父区块哈希值”。
示例:
本地副本有277,314个区块,最后的区块(即第277,314个区块)的区块头哈希值为00000000000000027e7ba6fe7bad39faf3b5a83daed765f05f7d1b71a1632249
。
新接收的区块信息如下:
{
"size":43560,
"version":2,
"previousblockhash":"00000000000000027e7ba6fe7bad39faf3b5a83daed765f05f7d1b71a1632249",
"merkleroot":"5e049f4030e0ab2debb92378f53c0a6e09548aea083f3ab25e1d94ea1155e29d",
"time":1388185038,
"difficulty":1180923195.25802612,
"nonce":4215469401,
"tx":["257e7497fb8bc68421eb2c7b699dbab234831600e7352f0d9e6522c7cf3f6c77",
#[...many more transactions omitted...]
"05cfd38f6ae6aa83674cc99e4d75a1458c165b7ab84725eda41d018a09176634"
]
}
对于这一新的区块,节点会在“父区块哈希值”字段里找出包含它的父区块的哈希值。这是节点已知的哈希值,也就是第277314块区块的哈希值。故这个区块是这个链条里的最后一个区块的子区块,因此现有的区块链得以扩展。节点将新的区块添加至链条的尾端,使区块链变长到一个新的高度277,315。
示意图:
区块通过引用父区块的区块头哈希值的方式,以链条的形式进行相连
Merkle树
是一种哈希二叉树,它是一种用作快速归纳和校验大规模数据完整性
的数据结构。
在比特币网络中,Merkle树被用来归纳一个区块中的所有交易,同时生成整个交易集合的数字指纹,且提供了一种校验区块是否存在某交易
的高效途径。
生成一棵完整的Merkle树方式:需要递归地对哈希节点对进行哈希,并将新生成的哈希节点插入到Merkle树中,直到只剩一个哈希节点,该节点就是Merkle树的根
,根节点为32字节
。在比特币的Merkle树中两次使用到了SHA256算法
,因此其加密哈希算法也被称为double-SHA256
。
示例:
从A、B、C、D四个交易生成一个完整的Merkle树。
步骤:
每个交易哈希化。
H~A~ = SHA256(SHA256(交易A))
相邻叶子节点哈希生成父节点。
H~AB~=SHA256(SHA256(H~A~ + H~B~))
依次类推,直到生成根节点(Merkle根)。
如果是奇数个交易则复制最后一个交易,凑成偶数个交易,并按上述方式生成。
H~CC~=SHA256(SHA256(H~C~ + H~C~))
示意图:
最后一个交易C被复制两份,参与生成Merkle树
示例:
证明某区块中存在交易K。
生成一条路径,该路径有4个哈希值(由蓝色标注)HL、HIJ、HMNOP和HABCDEFGH。由这4个哈希值产生的认证路径,再通过计算另外四对哈希值HKL、HIJKL、HIJKLMNOP和Merkle树根(由虚线标注),任何节点都能证明HK(在图中由绿色标注)包含在Merkle根中。
当N个数据元素
经过加密后插入Merkle树
时,你至多计算2*log2(N)
次就能检查出任意某数据元素是否在该树中,这使得该数据结构非常高效。
交易数量 | 区块的近似大小 | 路径大小(哈希数量) | 路径大小(字节) |
---|---|---|---|
16笔交易 | 4KB | 4个哈希 | 128字节 |
512笔交易 | 128KB | 9个哈希 | 288字节 |
2048笔交易 | 512KB | 11个哈希 | 352字节 |
65,535笔交易 | 16MB | 16个哈希 | 512字节 |
当区块大小由16笔交易(4KB)急剧增加至65,535笔交易(16MB)时,交易存在的Merkle路径长度增长极其缓慢,仅仅从128字节到512字节。
一个节点能够仅下载区块头(80字节/区块),然后通过从一个满节点回溯一条小的Merkle路径就能认证一笔交易的存在,而不需要存储或者传输大量区块链中大多数内容,这些内容可能有几个G的大小。
这种不需要维护一条完整的区块链的节点,又被称作简单支付验证(SPV)节点
,SPV节点不保存所有交易也不会下载整个区块,仅仅保存区块头。它们使用认证路径或者Merkle路径来验证交易存在于区块中,而不必下载区块中所有交易。Merkle树被SPV节点广泛使用。
参考:
Mastering Bitcoin
https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch09.asciidoc