比特币源码分析之五:区块

比特币源码分析之五:区块

区块数据结构

区块的数据结构代码在block.cpp中

区块由区块头和交易集合组成,如下图

区块头由以下字段组成

int32_t nVersion; 表示版本号

uint256 hashPrevBlock; 表示前一个区块的hash值

uint256 hashMerkleRoot; 表示交易集合算出来的merkle 树的树根hash

uint32_t nTime; 表示区块的生成时间

uint32_t nBits; 表示当前区块需要的挖矿难度,可以简单理解为定义了挖矿需要hash的前几位是0

uint32_t nNonce; 一个用于挖矿的随机数

Txs是交易的集合

交易的主要结构已经在前面的文章中有介绍这里不再赘述,但是区块中有一个特殊的交易需要单独拿出来介绍一下,这个交易是每一个区块的第一个交易,被叫做coinbasetx

对比之前介绍的标准交易coinbasetx有几个不同

1、coinbasetx必须是在每一个区块的第一个交易

2、coinbasetx没有输入,只有输出,而这个输出一般是矿工的地址,而coinbasetx的输出其实就是给矿工的奖励。比特币体系中所有的比特币都是从这个途径出来了,然后流通在各个账户中。

3、coinbasetx的输入因为没有实际的交易意义,所以被用来存放别的信息,比如区块的witness merkle树的根hash,又比如区块的高度等,其中有一个字段和挖矿有关系,单独列出来,就是输入的脚本中会放一个nExtraNonce字段,这也是一个挖矿时候可以修改的随机数和blockheader中的nNonce字段结合可以达到调整block hash的目的

区块hash的计算方式

区块头中有一个字段hashPrevBlock这个字段表示的就是前一个区块的hash值,那么区块的hash值是怎么计算出来的呢?

其实很简单,区块的hash值就是区块头所有字段的hash256。那么细心的读者一定会注意到,如果区块的hash值只计算了区块头,那么交易集合怎么能保证不被恶意的第三方串改?

这个问题是区块头中有一个hashMerkleRoot,这个字段就是通过交易集合算出来的一个hash值,从网上盗图一张,放在这里供读者理解。

其中L1 L2 L3 L4就是一个一个的交易。

区块生成方式-挖矿

挖矿的主要代码在mining.cpp和miner.cpp中

先贴出来主逻辑

UniValue generateBlocks(…) 函数名称

{

While(…)主循环

{

nHeight = chainActive.Height(); 获取当前链的高度

生成一个区块数据结构,填上了当前的交易以及coinbasetx

pblocktemplate(BlockAssembler(Params()).CreateNewBlock(coinbaseScript->reserveScript));

CBlock *pblock = &pblocktemplate->block;

调整区块coinbasetx中的输入脚本中的nExtraNonce

IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce);

不停的调整区块头中的nNonce来碰撞正确的hash

while(pblock->nNonce<nInnerLoopCount&&

!CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus()))

{

++pblock->nNonce;

}

如果区块头中的nNonce的值用完了(加到最大值了),重启大循环,调整nExtraNonce

if (pblock->nNonce == nInnerLoopCount) {

continue;

}

尝试把挖矿出来的区块放入到候选链->主链->广播出去

ProcessNewBlock(Params(), shared_pblock, true, nullptr)

}

}

这段代码主要是完成以下步骤

1、生成一个区块的模版,填写一些基本的字段

2、调整coinbasetx的nExtraNonce

3、从0- nInnerLoopCount 累加区块头中的nNonce字段,如果累加到了nInnerLoopCount,转入第2步

4、计算区块头hash是否达标(也就是前n位是否为0),达标就进入第5步,否则重复3步

5、将生成好的区块经过验证等流程进入到候选链,进而进入主链,进而进入广播流程。

其中解释几个关键点

1、模版中的前n位为0,n是怎么确认的?

有一个公式,笔者也没有详细研究,原理就是比特币设想每10分钟生成一个区块,而每2016个区块会检查一下,这2016个区块生成的平均时间是否超过或者小于10分钟,如果超过10分钟就会把n调低,也就是降低挖矿难度,反之则把n调高。

另外一个疑问,如果某些恶意矿工,人为的把n设置低,来达到挖矿的目的会怎么样?岂不是它挖矿更容易?

这个问题也引出了比特币中伟大的发明,你把n降低了,再公网中广播的时候,区块的工作量就比别的矿主的少,也就导致了你的区块可能被别的矿工挖出来的区块pk掉的概率高,这就保证了矿工不敢随意降低n。(这么解释可能会比较难理解,后续文章会找机会进一步解释)

2、矿工的挖矿费是怎么确定的?

矿工的挖矿费是有两部分构成

1)、交易费,也就是所有交易的输出减去所有交易的输入的差价就是交易费Fee

2)、奖励,这个奖励是每4年减半,比如当前的奖励是25个比特币,再过一个四年周期会变成12.5个,依次类推。4年这个时间刻度是靠区块链的高度结合每一个区块10分钟的设想生成时间确定的。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏区块链资讯

BCH测试网上出现第一个UTXO证明

我们都知道我们看到的比特币现金的余额其实都来自于UTXO,即未花费的交易输出。正是因为采用了UTXO才让我们的交易全部都记录在区块链上,保证了去中心化。

2259
来自专栏林冠宏的技术文章

(二)区块链的共识算法:PoS 及其 例子 代码 实现

关于什么是共识算法这个问题,请查看(一)区块链的共识算法:整体介绍 及 分叉 的通俗讲解 ,里面已经给出了答案。

980
来自专栏申龙斌的程序人生

解密Coin.Dance【区块链生存训练】

在比特币分叉时期,关注区块链动向的网站有很多,CoinDance网站 (https://coin.dance)就是非常有名的一个,里面提供了包括市值、价格、节点...

3486
来自专栏ImportSource

什么?区块链中的hash算法!施主,快扶老衲起来

hash算法有很多种。比如MD5、SHA1、SH2(SHA224、SHA256、SHA384和SHA512)、SH3、RIPEMD-160。

1103
来自专栏java达人

通过比特币了解以太坊(1)

作者:Mike Goldin 图标:Eva Shon 译者:java达人 来源:https://media.consensys.net/time-sure-do...

2204
来自专栏Python私房菜

最爱你的人,会让你不费脑细胞的理解区块链

区块链是一个近期非常火的概念,随便走进一个写字楼的电梯,都会听到有人谈论区块链,或者炒币: ) 希望通过这篇文章,能让你对区块链的概念有一个整体的认识,在理解概...

772
来自专栏龙行天下CSIEM

科学瞎想系列之七 大风车为什么大多为三个叶片

随着风力发电的火热,众多的大风车如雨后春笋拔地而起,成为一道道靓丽的风景,看风车甚至成了重要的旅游项目。有很多人纳闷,为什么大风车都是三个叶片?叶片之间...

2969
来自专栏架构师之路

1分钟了解“挖矿”的本质

上一篇《1分钟了解区块链的本质》,介绍了什么是区块链,区块链是一个没有管理员,每个节点都拥有全部数据,高可用的分布式存储系统。 文章的留言里,不少朋友会用比特币...

36810
来自专栏华仔的技术笔记

一些基本比特币概念

3439
来自专栏区块链大本营

一文看懂怎样用 Python 创建比特币交易

9056

扫码关注云+社区