文章目录 前言哈希指针区块链Merkle tree防篡改验证身份 比特币区块链比特币区块获取区块数据coinbase交易总结参考文献摘要:本文主要介绍比特币区块的相关概念
前言
比特币账本是以区块链的形式组织起来的,每个区块以merkle tree
的形式记录着多条交易的具体信息, 而区块与区块间则通过哈希指针链接起来,从而实现了对所有历史交易的记录。本文将对比特币区块的所有相关概念进行简介。
以下是本篇文章正文内容
前面提到,比特币区块与区块间是通过哈希指针链接起来的,那么,哈希指针是什么呢?这里介绍一下这个概念。哈希指针(Hash pointer)
,顾名思义,是一个带有哈希值的指针。其结构如下图所示,该指针不仅记录了其所指向的数据块的地址,同时也记录了该数据块的哈希值。
比特币的账本(ledger
)是以区块链(block chain
)的形式组织起来的,其结构如下图所示。每个区块里包含了一个字段previousblockhash
,记录着上一个区块的哈希值。每往区块链里添加一个新的区块时,需要计算上一个区块的哈希值并填入新加的区块的previousblockhash
字段中。
区块链的这种特殊的结构形式,使得它具有防篡改的属性。那么,区块链是如何体现出其防篡改属性的呢?以下图为例,假如有人恶意篡改了区块1的内容,那么为了保持一致,他必然要对篡改后的区块1的内容重新进行哈希运算,然后将所得到的哈希值填入区块2的previousblockhash
字段,而因为区块2的previousblockhash
字段改变了,他又不得不对区块2重新进行哈希运算并将得到的哈希值填入区块3的previousblockhash
字段 。最终,他将不得不修改区块链链首的哈希指针。只要我们记录了这个指针,那么他将无法篡改这个指针的信息。结果就是,如果我们对最后一个区块(在下面的例子中是区块3)求哈希,那么结果一定和我们所保存的链首哈希指针不一致,从而就可以识别出区块链内容有被人篡改过。
每个比特币区块中记录了多条交易信息,这些交易是以merkle tree
的形式组织起来的,如下图所示。首先会对每条交易求哈希,然后对得到的哈希两两配对,再求哈希,然后再将所求得的哈希两两配对,最终,将会得到一个哈希值,这个哈希值就是merkleroot
。
以merkle tree
的形式将区块内的所有交易组织起来,主要有两个好处。
与前面区块链防篡改的机制类似,只要我们记住了merkle tree
的根节点的哈希值merkleroot
,我们就能防止篡改。具体过程如下,以下图为例,假如有人恶意篡改了交易1的信息,那么为了保持信息一致,他必须沿着交易1所在的分支一直往上,重新计算所有的哈希值,直到根节点。但是,因为我们在本地保存了merkleroot
的值,所以攻击者在篡改根节点的其中一个哈希值后,他无法再进一步篡改merkleroot
的值了,而我们验证时,只要计算一下根节点的哈希值,然后与本地保存的merkleroot
比较一下,就能检测出这个区块的交易信息有被篡改过。所以,在区块链的基础之上,merkle tree
进一步加强了防篡改的能力。
merkle tree
的另一大优点是通过它可以很轻易地验证一条交易是否属于这个区块。以下图为例,假如某人想证明交易1属于这个区块。与前面一样,我们只需要记住merkleroot
。当某人要证明交易1属于这个区块时,他需要给出一条分支,该分支的根节点的哈希值要等于我们所保存的merkleroot
,叶子节点则是要证明的交易,下图里是交易1。我们只要沿着这条分支,对路径上所有的哈希值验算一遍,如果得到的所有哈希值都与分支上各个节点所记录的哈希值一致,那么就证明了交易1属于该区块。
从上面的例子可以看出,利用merkle tree
可以很容易地验证交易1属于这个区块。反过来,要是一个交易不属于该区块,那么也很容易证明。以下图为例,假如某人想将不属于该区块的交易x伪装成属于该区块,那么他必须将这个伪交易插入到merkle tree
的某个位置。假如他插入的是交易2的位置,那么在证明交易x属于这个区块时,我们可以要求他出示交易x在merkle tree
上的前一个交易和后一个交易以及其所在的分支 。于是,他需要给出下图所示的几个分支,为了保持信息一致,他不得不沿着原来交易2所在的分支,对所有的哈希重新算一遍并进行篡改,而由于我们记住了merkleroot
,他无法篡改这个值,所以只要我们对根节点的哈希进行验算,就会发现得到的哈希值与我们保存的merkleroot
不一致,从而证明了交易x并不属于这个merkle tree
,即不属于这个区块。
比特币区块链结构图如下图所示,由图可以看出各个区块之间以哈希指针
链接起来,区块内部各个交易则以merkle tree
的形式组织起来。每个区块都记录两个哈希指针,一个是previousblockhash
,指向上一个区块,记录着上一个区块的哈希值,另一个是merkle root
,指向其所在区块的merkle tree
的根节点,记录着该节点的哈希值。
比特币区块的结构如图所示,区块由两部分组成,一部分是区块头
,记录着区块的一些关键的特征信息,受限于页面大小,下面图中只展示出一部分,后面会介绍不在图上的其它项。另一部分是交易列表
,记录着该区块里每条交易的哈希值,这里的划分只是一种概念上的划分,实际上区块的数据结构中不会专门用两个不同数据结构来分别存放区块头
和交易列表
,而是会把它们统一记录在一个数据结构中。
比特币区块各字段如下表所示。
字段 | 说明 |
---|---|
hash | 当前区块Hash |
confirmations | 区块链网络确认数 |
size | 区块大小 |
height | 区块高度 |
version | 区块版本 |
versionHex | 区块版本的16进制表示 |
merkleroot | 区块中所有交易的merkle根Hash |
tx | 交易列表 |
time | 区块的时间戳 |
mediantime | 过去11个区块的中值时间 |
nonce | 32位的任意随机数,挖矿时用于工作量证明算法的一个扰动输入参数 |
bits | 区块的难度目标 |
chainwork | 区块链上的总计工作量,它是一个32位的整数,代表了区块链上所有区块的计算工作量 |
previousblockhash | 前一个区块的Hash值 |
nextblockhash | 下一个区块的Hash值 |
获取区块数据
前面介绍了比特币区块的结构以及里面的各个字段,下面介绍在实际网络中如何获取一个真实存在的区块的数据。目前网络上有多个区块链浏览器,这些区块链浏览器不光能查询区块的内容,还能实时地监测网上正在进行的交易,一个比较常用的在线区块链查询网站是https://www.blockchain.com/explorer。
点击进入该网址,在Assets->Bitcoin页面,可以看到最新加入到区块链中的区块(Latest Blocks),以及最新的交易情况(Latest Transactions)。滚动到该页面的最下方,点击进入Resources->APIs页面。
在Resources->APIs页面,可以看到这个网站提供了很多不同的API和查询功能,点击查看Blockchain Data API的Documentation,这个Documentation就是关于如何查询区块数据的说明书。
在里面可以看到,我们既可以查询某个区块的内容,也可以查询某个交易的内容,要查询区块内容,只需要在浏览器输入https://blockchain.info/rawblock/$block_hash
格式的URL然后跳转即可,其中$block_hash
是该区块的哈希值。
点击查看前面的Assets->Bitcoin->Latest Blocks页面,查看最新的区块,作为例子,从其中选一个比较小的区块,如下图的Block 740337,查看该区块的内容,可以看到,其哈希值为000000000000000000055092e5f54d01ea178a879cef5f331f4b974172cccefe,则查询该区块内容的URL为https://blockchain.info/rawblock/000000000000000000055092e5f54d01ea178a879cef5f331f4b974172cccefe
转到上面的URL后,我们看到的JSON格式的网页内容是乱序的,需要进行排序以便观察。将其内容复制到https://www.bejson.com/json/format/)这个网址,格式化校验之后,点击保存校验数据,然后即可看到格式化后的JSON文件内容,如下图所示。
上面的JSON文件可以到以下地址中下载,文件名为Block 740370.json。
每个区块的第一条交易是coinbase交易
。coinbase交易
会生成新的比特币,要生成新的比特币,只能通过coinbase交易
。与普通的交易相比,coinbase交易
有如下的几个特点:
以上面的JSON文件为例,摘取其交易列表的第一条交易(即coinbase交易
)出来,从下面可以看到,这个区块的coinbase交易
新造了6.25150003枚比特币,其中block reward为6.25150003BTC,fee reward为0。
"tx": [{
"hash": "f58dc5d553b86f47fb901757e3be85b2b08f3f36317fc1e690fb2ca7cbe37156",
"ver": 2,
"vin_sz": 1,
"vout_sz": 2,
"size": 217,
"weight": 760,
"fee": 0,
"relayed_by": "0.0.0.0",
"lock_time": 0,
"tx_index": 3041508898170271,
"double_spend": false,
"time": 1654947331,
"block_index": 740337,
"block_height": 740337,
"inputs": [{
"sequence": 4294967295,
"witness": "01200000000000000000000000000000000000000000000000000000000000000000",
"script": "03f14b0b04037ea4622f466f756e6472792055534120506f6f6c202364726f70676f6c642f0c027cef00003c1706000000",
"index": 0,
"prev_out": {
"tx_index": 0,
"value": 0,
"n": 4294967295,
"type": 0,
"spent": true,
"script": "",
"spending_outpoints": [{
"tx_index": 3041508898170271,
"n": 0
}]
}
}],
"out": [{
"type": 0,
"spent": false,
"value": 625150003,
"spending_outpoints": [],
"n": 0,
"tx_index": 3041508898170271,
"script": "76a9145e9b23809261178723055968d134a947f47e799f88ac",
"addr": "19dENFt4wVwos6xtgwStA6n8bbA57WCS58"
}, {
"type": 0,
"spent": false,
"value": 0,
"spending_outpoints": [],
"n": 1,
"tx_index": 3041508898170271,
"script": "6a24aa21a9edeb61edfb90d450a17115e960c6e6b216442b28c0ff48a9e390dfa2a767e80ec0"
}]
},
该coinbase交易
的细节可以到https://www.blockchain.com/btc/tx/f58dc5d553b86f47fb901757e3be85b2b08f3f36317fc1e690fb2ca7cbe37156查看,如下图所示。这个URL的最后一部分是该交易的哈希,假如我们要查询其它交易的细节,将其它交易的哈希替换这个URL的最后一部分(该交易的哈希)即可。
下图又是另外一个例子https://www.blockchain.com/btc/block/000000000000000000032e39bbd3a6af9b311982a256acf1dab5518b2eb79c9a,从图中可以看出,Block Reward是6.25000000BTC,而Fee Reward是0.00080987,因此挖得此区块的总的收益(revenue)是6.25150003。
本文介绍了与比特币区块链有关的数据结构以及相关概念,包括哈希指针
,merkle tree
,比特币区块链
,比特币区块
,介绍了它们所具有的一些属性,它们是比特币网络的基本部件(building block),要理解比特币网络,首先必须要正确理解这些概念。
[1] 通俗易懂揭秘比特币区块的内部结构
[2] Bitcoin 区块和交易数据结构
[3] bitcoin区块结构分析
[4] 区块结构
[5] 比特币区块结构解析
[6] Bitcoin and Cryptocurrency Technologies by Arvind Narayanan, Joseph Bonneau etl. Section 3.4
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)