mastering bitcoin

mastering bitcoin

Posted by logicic on November 29, 2019

Mastering bitcoin

一.简介

软件工程、密码学、经济学的结合体。

需要解决数字货币的两个基本问题:

  • 这笔钱是否真实可信
  • 这笔钱怎么识别所有权

比特币构成:

  • 一个去中心化的点对点网络(比特币协议
  • 一个公共的交易账簿(区块链
  • 一个去中心化的数学的和确定性的货币发行(分布式挖矿
  • 一个去中心化的交易验证系统(交易脚本
比特币的客户端:

完整客户端:一个完整的客户端,或称为“全节点”,存储着所有比特币交易的真个交易历史(由每一个用户完成的每一笔交易,曾经所有的每一笔)的客户端,可以管理钱包,并可以在比特币网络上直接开始交易。

轻量级客户端:存储着用户的钱包,但需要依赖第三方服务器才能进行比特币交易,才能接入比特币网络。不保存所有交易的完整副本。

在线客户端:通过网页浏览器在第三方服务器上访问和储存该用户的钱包

不同客户端的选择:完整客户端就自身对钱包的管理,钱包的备份和安全责任就转移到了用户上。而其他需要考虑第三方的风险。

二.基本运作原理

运作的一个关键点:信任,不仅仅是一个人相信另一个人,而是在这个区域内的所有参与者都给予认可。如何做到的?区块链技术,一个公共的交易账本,这个账本大家都能看到,都能复制,但是里面的信息无法修改,只能在之前信息的基础上做新的信息添加作为更正。如何使得区块链上的信息无法修改呢?这个“无法”是相对的,一块区域连接着一块,下一块存储着上一块的hash值,如果其中一块被修改,则连锁反应,下一块的信息也需要修改,下下块也需要,这样修改的成本会非常大,所以就没人这么做。

那么计算区块哈希值交由谁做呢?又没有中心化的服务器,谁来提供这样的服务呢?这就产生了矿工,矿工提供算力来计算区块,使交易记录在链上,那么如何推动矿工的工作呢?一种激励手段产生了,而且是最简单暴力的,给钱干活。矿工提供算力给交易上链成功后,会得到一份收益。至于这收益怎么计算,谁来最终获取这份收益,后面在详谈。

有了这份推动力,系统就初步搭建起来了。那么交易是怎么构建的呢?也就是如何让数据是有价值的呢?这里肯定不是数据本身有价值,而是数据记录的内容,这里有一个概念,utxo—-unspent transacation output,未使用交易输出,他表示在链上的交易记录,使用这些交易记录来表示自身的财产,记录的基本信息有输入和输出,输入是本账户的支出,输出是本账户或者其他账户的收入(还包含了挖矿),表示你拥有多少财富的记录是,某个账户输入了币给你,而你可以消费这个币,形成新的记录。标记你账户的,名词为地址,即钱包地址,这个是可以公开的,大家转账的地址就是填写这个地址。这个地址是通过私钥椭圆加密算法(单向)得到公钥,公钥通过双重哈希算法(单向)得到地址,所以最重要的是私钥,他的安全性是通过两个加密算法来维护的,如果哪天这个加密算法被破解了,那么也就gg了。

三.客户端的使用

比特币客户端的编译与使用。

  • 1.直接从官网上安装bitcoin.org

  • 2.github上下载源码进行编译

四.密钥、地址、钱包,生成与使用

  • 1.比特币的所有权:数字密钥、比特币地址和数字签名来确立。

钱包:数字密钥由用户生成并存储在一个文件或简单的数据库中,而并不存储在网络中,称之为钱包。

存储在用户中的数字密钥完全独立于比特币协议,可由用户钱包软件生成并管理,而无需区块链或网络连接。

本章将密钥所在之处,钱包。了解密钥如何被产生、存储和管理。私钥和公钥、地址和脚本地址的各种编码格式。密钥的特殊用途:生成签名、证明所有权以及创造比特币靓号地址和纸钱包。

  • 2.私钥===椭圆曲线相乘(单向)===》公钥===哈希函数(单向)===》比特币地址

如何获取安全的私钥?

首先私钥可以取值的范围是:1-(n-1),n=1.158*10^77。要生成一个相对安全的私钥,可以随机一个256位的数字,检查他是否小于n,从编程的角度,一般是通过在一个 密码安全的随机源中取出一长串随机字节,对于使用sha256哈希算法运算,就可以得到一个256位的数字了,再检查是否满足范围。

如何获取公钥?

使用私钥计算椭圆曲线相乘,得到公钥,具体我搞不明白。使用的是secp256k1标准。

如何获取比特币地址?

比特币地址常作为交易的收款方出现。比特币地址可由公钥经过单向的加密哈希算法得到。哈希算法在比特币中被广泛使用:比特币地址、脚本地址以及挖矿中的工作量证明算法。由公钥生成比特币地址时使用的哈希算法是:Secure Hash Algorithm(SHA)和the RACE Integrity Primitives Evaluation Message Digest(RIPEMD),尤其是SHA256和RIPEMD160。

公钥====》SHA256===》RIPEMD160===》公钥哈希====》Base58check编码(前缀版本位0x00)===》比特币地址(Base58Check编码的公钥哈希)

你认识base58和Base58Check编码

为了更简洁方便地表示长串的数字,使用数字和自负组成的大于十进制的表示法。例如十六进制。Base64使用了26个小写字母、26个大写字母、10个数字以及两个符号(例如“+”,“/”)。Base58是一种基于文本二进制的编码格式,用于比特币和其他加密货币中。 这种编码格式不仅实现了数据压缩,还保持了易读性。Base58不包括0数字零,O字母大写o,l小写字母L,I大写字母i。

Base58Check增加了错误校验码来检查数据在转录中出现的错误。校验码长度为4byte,添加到需要编码的数据的后面。

数据====》版本前缀+数组==Hash(版本+数据)截取前四个字节作为校验码==》版本+数据+校验码==Base58编码==》Base58编码的数据

公钥的格式

可分为非压缩格式或压缩格式两种形式。公钥是椭圆曲线上的一个点,由一对坐标(x,y)组成。 非压缩格式:04+x+y 压缩格式:需要判断y的正负,因为压缩之后需要带上y的正负信息,y上的正负表现为,当我们在素数p阶的有限域上使用二进制算术计算椭圆曲线的时候,y可能是奇数或者偶数,分别对应y值的正负符号。y为偶数:02x,y为奇数:03x

场景:一个起拿包应用导入另一个钱包应用的私钥的时候,需要扫描区块链并找到所有与这些被导入私钥相关的交易。那么钱包应该扫描哪个比特币地址呢?(因为有两种格式的公钥,压缩格式公钥和非压缩格式公钥,得到的比特币地址也不同)

解决办法:导出私钥的时候加上后缀来标志公钥能不能压缩表示,加上后缀01表示私钥是来自于一个较新的钱包,只能用来生成压缩的公钥。形成一个规范。

钱包导入格式(WIF,Wallet Import Format):私钥以Base58校验和编码格式显示。

比特币钱包的概念

钱包是私钥的容器,通常通过有序文件或者简单的数据库实现。

另一种生成私钥的途径:使用原先的私钥,通过单向哈希函数生成每一个新的私钥,并将新生成的密钥按顺序连接。

不同私钥生成方法及其钱包结构。

  • 1.非确定性(随机)钱包

非确定性钱包,亦被称为零型非确定性钱包。就是从最开始的时候就生成足后多的私钥并且每把钥匙都只使用一次。它难以管理、备份以及导入,因为你生成很多,你必须保存他们所有的副本。现在正在被确定性钱包所替换。

  • 2.确定性(种子)钱包

确定性钱包包含了通过使用单项离散方程而可从公共的种子生成的私钥。这里的种子是随机生成的数字。这个数字也包含了索引号码或者生成私钥的“链码”。有了种子,那么就不必对每一份私钥都进行备份,只需要在出事创建的时候一个简单备份就可以搞定了。

  • 3.助记码词汇

助记码词汇是英文单词序列代表(编码)用作种子对应所确定性钱包的随机数。就是使用助记码词汇作为种子的确定性钱包。它的一个优势是:它相对于随机数字顺序来说,可以更容易地被读出来并且正确抄写。

BIP0039定义助记码和种子创建过程如下:
- 1.创造一个128到256位的随机顺序(熵);

- 2.提出SHA256哈希前几位,就可以创造一个随机序列的校验和;

- 3.把校验和加载随机顺序的后面;

- 4.把顺序分解成11位的不同集合,并用这些集合去和一个预先已经定义的2048个单词字典做对应;

- 5.生成一个12至24个词的助记码。
  • 4.分层确定性钱包(BIP0032/BIP0044)

the hierarchical deterministic wallet or HD wallet defined

HD钱包提供了随机(不确定性)钥匙有两个主要的优势,

  • 1.树状结构可以被用来表达额外的组织含义。比如当一个特定分支的子密钥被用来接收交易收入并且有另一个分支的子密钥用来负责支付话费。
  • 2.他可以允许使用者去建立一个公共密钥的序列而不需要访问相对应的私钥。
从种子中创造HD钱包

密码学上安全的

伪随机数发生器

        ||
    
        ||                                                                                        |主私钥m(256bits)
    
         \/                                                                                       |         |
    
     根种子                    ===== 》HMAC-SHA512        ====== |  主公钥M(264bits)

(128、256或512bits)        (512bits输出)单向哈希函数         |

        ||                                                                                       |主链编码(256bits)
    
        ||
    
         \/
    
      助记码

在这里插入图片描述

为什么会用到那么多的比特币地址,公钥?

五.交易过程

比特币交易的本质是数据结构,这些数据结构中含有比特币交易参与者价值转移的相关信息。

系统中任何其他的部分都是为了确保比特币交易可以被生成、能在比特币网络中得以传播和通过验证,并最终加入全球比特币交易总帐本(比特币区块链)。

比特币交易本身不含有敏感信息,所以可以通过未加密网络(例如wifi、蓝牙、NFC、ChirP、条形码或者复制粘贴至一个网页表格)被发送到比特币网络。

一笔比特币交易被发送到任意一个连接至比特币网络的节点,这笔比特币会被该节点验证,如果验证有效,该节点将会传播到这个接待你所连接的其他节点,同时会返回一条表示交易成功的返回信息。如果此交易被验证为无效,这个节点会拒绝接收这笔交易且同时返回给交易发起者一条表示交易被拒绝的消息。

那么比特币的交易验证引擎依赖于两类脚本来验证比特币交易:

一个是锁定脚本和解锁脚本。锁定脚本上带着一个公钥;解锁脚本由使用者提供,用以解决锁定脚本的“锁定”。

这个脚本是一种基于逆波兰表示法的基于堆栈的执行语言。它被故意设定为一种重要的方式——没有循环或者复杂流控制功能以外的其他条件的流控制。使得这个脚本语言的图灵非完备性。受限制的语言能防止交易激活机制被人当作薄弱环境而加以利用。

交易的基本单位是未经使用的一个交易输出,简称为UTXO。

什么是UTXO?

Unspent transaction output未使用交易输出。他是不能再被分割、被所有者锁住或记录于区块链中的并被整个网络识别成货币单位的一定量的比特币货币。一个用户的比特币余额是指通过扫描区块链并聚合所有属于该用户的UTXO来计算该用户的余额,它被分散到数百个交易和数百个区块链中。

交易输出包含两部分:

  • 1.一定的比特币,被命名为“聪”,是最小的比特币单位;

  • 2.一个锁住脚本,提出支付输出所必须被满足的条件以“锁住”这笔总额。

交易产生的交易费,即挖矿费。它是基于交易的尺寸,用千字节来计算。

标准交易

五大标准脚本分别为P2PKH、P2PK、MS、P2SH、OP_Return。

  • 1.P2PKH(Pay-to-Public-Key-Hash)

此类交易脚本的特点:需要键入公钥和由相应私钥的数字签名才得以解开一个带公钥哈希实现的锁定脚本。。

  • 2.P2PK(Pay-to-Public-Key)

与P2PKH的区别在于,P2PK的锁定脚本中公钥本身已经存储在锁定脚本中了。

  • 3.MS(多重签名)

多重签名脚本设置了一个条件,如果记录在脚本中的公钥数为N,则至少需要其中的M个公钥才可以解锁。这被称为M-N组合。N是记录在脚本中的公钥总个数,M是使得多重签名生效的公钥阈值(最少数目)。

  • 4.数据输出(OP_RETURN)

比特币的分发和时间戳账户机制(也即区块链),其潜在运用大大超越了支付领域。发挥其交易脚本语言的安全性和可恢复性优势,将其运用于电子公正服务、证券认证和智能合约协议等领域。但是他在非支付领域的应用,使开发者们产生了分歧,因为在非支付领域的使用会使得所有的区块链节点都将以消耗磁盘存储空间为成本,负担存储此类数据的任务。通过采用OP_RETURN操作符实现了妥协,可以避免使UTXO集产生内存膨胀。

  • 5.P2SH(Pay-to-Script-Hash)

P2SH是为了解决MS多重签名产生的复杂操作,使得复杂脚本的运用能与之结向比特币地址支付一样简单。

六.网络的构建与通信

P2P是指位于同一网络中的每台计算机都彼此对等,各个节点共同提供网络服务,不存在任何“特殊”节点。

虽然网络中节点相互对等,但是根据所提供的功能不同,各节点可能具有不同的分工。每个比特币节点都是路由、区块链数据库、挖矿、钱包服务的功能集合。

每个节点都会参与全网络的路由功能,同时也可包含其他功能。每个节点都参与验证并传播交易及区块信息,发现并维持与对等节点的连接。包含不同的功能可以分为以下几种节点:

比特币核心客户端:路由+区块链数据库+挖矿+钱包服务

全节点:保存有一份完整的、最新的区块链拷贝,能够自主地娇艳所有交易,而不需借由任何外部参照。路由+区块链数据库+钱包服务

SPV节点(轻量级节点):通过一种“简易支付验证SPV”的方式完成交易验证。路由+钱包服务

完整区块链节点:路由+区块链数据库

独立矿工节点:路由+具有完整区块链数据库副本+挖矿

矿池协议服务器:将运行其他协议的节点(例如矿池挖矿节点、Stratum节点),连接至P2P网络的网管路由器。包含了Pool服务器,Stratum服务器。

挖矿节点:包含不具有区块链、但具备Straum协议节点或其他矿池挖矿协议节点的挖矿功能。

轻量(spv)stratum钱包:包含不具有区块链的钱包,运行Straum协议的网络节点。

节点间的通信与已知的对等节点建立连接时,会发送一条基本认证内容的version消息开始握手通信过程:

  • PROTOCOL_VERSION:常量,定义了客户端的比特币P2P协议所采用的版本。

  • nLocalServices:一组该节点支持的本地服务列表,当前仅支持NODE_NETWORK

  • nTime:当前时间

  • addrYou:当前节点可见的远程节点的IP地址

  • addrMe:本地节点所发现的本机IP地址

  • subver:指示当前节点运行的软件类型的子版本号

  • BaseHeight:当前节点区块链的区块高度

新节点是如何发现网络中的对等节点呢?

  • 1.客户端中会维护一个列表,列表中存放着长期稳定运行的节点,这样的节点被称为种子节点。种子节点可以帮助新节点快速发现网络中的其他节点。

  • 2.起始时将至少一个比特币节点的ip地址提供给正在启动的节点(该节点不包含任何比特币网络的组成信息)。

当已经建立一个或多个连接后,新节点可以将一条包含自身IP地址的信息推送给邻居节点,邻居可以再推送给他自己的邻居节点,从而保证新节点信息被多个节点所接收、保证连接更稳定,即为泛洪机制。新介入的节点还可以向他的相邻节点发送申请,拉取邻居节点的已知ip地址列表。

实际网路上,节点会随机加入和离开,通讯路径时不可靠的。实际的解决方案:1.在失去已有连接时发现新节点(怎么发现新节点?),并在其他节点启动时为其提供帮助。一个节点如果连接到大量的其他对等节点时浪费网络资源的。2.在启动完成后,节点会记住他最近连接的对等节点(存进数据库中?),当他重新启动后可以迅速与先前的对等点网络重新建立连接。如果先前的网络没有应答,该节点可以使用种子节点进行重启动。

连接成功后,第一件要做的事是后见完整的区块链。如果是一个全新的节点,那么他只有一个创世区块——静态植入在客户端软件中的。两个节点在进行通信是,发送version时,从该消息中含有的BestHeight字段标示可一个节点当前的区块链高度(数量),双方有了一个基本的相互连接,版本,区块的数量。可以发送消息要求getblock要求交换他们本地区块链的顶端区块链哈希值,可以根据哈希值在本地的位置来判断谁的区块长,需要发送哪些区块去补充。他会使用inv(inventory)消息把区块哈希值传播出去,缺少这些区块的节点可以通过各自的发送的getdata消息来请求得到全区块的信息。

例如,假设一个节点仅具有创世块。然后,它将从其对等方收到一条inv消息,其中包含链中接下来500个块的哈希值。它将开始从其所有连接的对等方请求块,分散负载并确保它不会因请求而压倒任何对等方。节点跟踪每个对等连接“正在传输”的块数,即已请求但尚未接收的块,并检查它是否未超过限制(MAX_BLOCKS_IN_TRANSIT_PER_PEER)。这样,如果需要大量的块,则仅在满足先前的请求时才请求新的块,从而允许对等方控制更新的速度,而不会使网络不堪重负。收到每个块后,它将被添加到区块链中。随着本地区块链的逐步建立,更多的块被请求和接收,并且该过程一直持续到节点赶上网络的其余部分为止。

对于具有完整区块信息的节点的检验方式就是构造一条验证链,这条链时由沿着区块链按时间倒序一直追溯到创世区块的数千区块及交易组成,建立一个完整的UTXO数据库,通过确认UTXO是否还未被支付来证实交易的有效性。

简易支付验证(SPV)节点

spv节点只需下载区块头,而不用下载包含在每个区块中的交易信息。通过检查在其上面的区块将它压在下面的深度来验证交易。由于spv节点需要读取特定交易从而选择性地验证交易,这样就产生了隐私风险,spv节点对特定数据的请求可能无意中透露了钱包里的地址信息。Bloom过滤器,用以解决spv节点的隐私风险问题。采用概率而不是固定模式的过滤机制,允许spv节点只接收交易信息的子集,同时不会精确泄漏哪些是他们感兴趣的地址。

Bloom过滤器怎么做到的呢?

Bloom过滤器是一个允许用户描述特定关键词组合而不必精确表述的基于概率的过滤方法。他能让用户在有效搜索关键词的同时保护他们的隐私。在spv节点里,被用来向对等点发送交易信息查询请求,同时交易地址不会被被暴露。

Bloom过滤器具体实现

交易池

几乎每个节点都会维护的一份未确认交易临时列表。他是矿工们提前准备好的“材料”,为下一块新区块开始做准备。当交易发起,会在网络中广播,存储在交易池中,当新区块开始竞争,会从交易池中拿出进行验证,加入到区块并广播到网络中,开始进行解题完成proof of work,此时交易放在utxo池中,因为他通过了验证,但是交易还不算完成,区块还没上链,没有得到网络的承认,如果包含此交易的区块完成工作量证明,则交易算是成功完成,从utxo池中移除,如果包含此交易的区块竞争上链失败,则还在utxo池中,交易为完成。

七.区块链技术

区块结构:由一个包含元数据的区块头和紧跟其后的后程区块主体的一长串交易组成。

区块头组成:三组区块元数据组成。首先一组引用父区块哈希值的数据,这组元数据用于将该区块与区块链中前一区块相连接。第二组元数据,即难度、时间戳和nonce,与挖矿竞争相关。第三组元数据是merkle树根(一种用来有效地总结区块中所有交易的数据结构)。

区块标识符:区块头哈希值和区块高度

通过对区块头进行二次哈希计算得到的数字指纹。

子区块里的区块头里存放着父区块的头哈希值,计算子区块的区块头哈希值作为孙区块里的区块头里的“上一区块头哈希值”。

Merkle树是一种哈希二叉树,用作快速归纳和校验大规模数据完整性的数据结构。这种二叉树包含加密哈希值。在比特币网络中,被用来归纳一个区块中的所有交易,同时生成整个交易集合的数字指纹,且提供了一种校验区块中是否存在某交易的高效途径。

Merkle树的生成:需要递归地对哈希节点对进行哈希,并将新生成的哈希节点插入到Merkle树中,知道只剩下一个哈希节点,该节点即为Merkle树的根。 在这里插入图片描述

在这里插入图片描述

需要证明交易k是否存在区块中===》证明Merkle树中是否有Hk(k交易的double哈希值)===》需要一条到底根顶的Merkle路径===》计算四次哈希值进行认证对比。

如何获取Merkle路径呢?

Merkle树和简单支付验证(SPV)相结合。一个spv节点想要知道它的钱包中某个比特币地址即将到达支付,该节点会在节点间的通信链接上建立起bloom过滤器,限制只接受含有目标比特币地址的交易。当节点探测到某交易符合bloom过滤器,他将以Merkle区块消息的形式发送该区块。Merkle区块消息包含区块头和一条链接目标交易与Merkle根的Merkle路径。spv节点就可以使用该路径找到与该交易相关的区块,进而验证对应区块中该交易的有无。

八.共识与激励推动,挖矿

挖矿:通过计算完成一种基于哈希算法的数学难题,这些学习难题的答案包括在新区块中,作为矿工的计算工作量的证明,被称为工作量证明(proof of work)。

奖励:分为两种,创建新区块的奖励,还有完成计算难题的交易路费。

挖矿(共识与激励推动)===》支撑比特币安全的去中心化

每个节点在校验每一笔交易时,都需要对照一个长长的标准列表。如果是无效的,则会在第一个节点处被废弃,否则就会在网络中传播。如果该节点接收到的交易数量比较多,还没来得及完全验证,那么会以接收时的相应顺序,为有效的新交易建立一个池,即为交易池。

挖矿的竞争是以新区块的传播而结束。(如何得知?需要自己维护一个区块链完整的记录,并且不断的监听网络上的交易,确保自己是最新的区块链状态,并且准备着新区块的挖掘)每一个挖矿节点会在新区块传播后(宣布赢家,新新区块开始诞生),拷贝一份区块在本地作为候选区块,(如果能够拔得头筹解开工作量证明解之后则真正成为区块),不断记录新的交易,完善区块头信息,并且解决该区块的“难度”工作量证明,也为下一个新新新区块提前收集好交易放进交易池中做好准备(注意不要有与前面区块重复的交易,确保任何留在内存池中的交易都是未被确认的,等待被记录到新区块中)。

因为区块的大小有限,矿工们需要为内存池中的每笔交易分配一个优先级,并选择高优先级的交易记录来构建候选区块。

交易的优先级:

交易输入值高,交易“块龄”大的优先级高。如果区块中有足够的空间,则高优先级的交易则不需要矿工费。

Priority = Sum(Value of inout * Input) / Transaction Size;

交易输入的值的单位是比特币单位“聪”来表示,UTXO块龄是该UTXO被记录到区块链为止所经历过的区块数,交易记录的大小由字节表示。进行排序,优先选择矿工费高的交易来填充剩下的区块,区块大小上限为MAX_BLOCK_SIZE。其余的,按照“每千字节矿工费”

当交易存放在交易池中时,是没有被验证到的,所以用户那里是未验证状态,存放在内存池中,有可能节点的重新启动,这条交易就被擦除了,或者因为有优先级,所以他一直被放置在内存池,太长时间未处理的话,就会消失,此时钱包软件应该重新发送交易或重新支付更高的矿工费,提高优先级。

创币交易或coinbase交易,用来奖励矿工创建新区块的。奖励的数目会每开采出210,000个区块就减少一半。

当填充完区块头部的信息时,就可以开始挖矿。挖矿的目标时找到一个使区块头哈希值小于难度目标的nonce。挖矿节点通常需要尝试数十亿个不同的nonce取值,知道找到一个满足条件的nonce值。

工作量证明算法:根据某种规则设定一个target,通过nonce计数(0,1,2,3…往上计数)附加到一串数上来计算其哈希值,当计算得到的哈希值小于这个target时,则证明一定的工作量已经达到了。

随着算力的提升,发展出一个解决区块头基本结构限制的方案——随机值升位方案。以解决随机数的变化不够的情况:经过一轮的计算,nonce已经到底,然后采取的后移时间戳来重新计算数值,以达到target的目的,但是随着难度的提升,不断的后移时间戳,会使得该区块因时间太久远而无效,所以使用coinbase脚本可以存储的2-100字节,进行额外随机值的来源。

那如何设定这个target值呢?

通过难度目标,标记的值被存为系数/指数,前两位十六进制数字为幂,接下来得六位系数。例如0x1903a30c,计算难度目标的公式为:

target = coefficient * 2^(8 * (exponent - 3));

想要比特币网络中的挖矿速度维持在一个区块大约十分钟

每发现2016个区块时会根据前2016个区块的使用的实际时间对难度作一个调整。

当完成工作量证明的挖矿后,会向网络中传播给他的相邻节点,相邻节点验证后,也会传播给他的相邻节点,扩散到网络中。以确保传播的这个节点是有效的。

如何验证新区块呢?

验证标准在CheckBlock函数和CheckBlockHead函数中获得。

将区块集合至有最大工作量证明的链中

一旦一个节点验证了一个新的区块,他将尝试将新的区块连接到现存的区块链,将他们组装在一起。

那么新区块会连接到哪个链上呢?

每个节点上会维护三种区块:1.连接到主链上的,2是从主链上产生分支的(备用链),3是已知链中没有找到父区块。主链是累计了最多难度的区块链,主链与备用链是相对的,当累计的难度更大的,将成为新的主链,剩下为备用链。如果节点收到一个区块,但是他的父区块找不到,这个区块被称为“孤块”。孤块会被保存在孤块池中,直到他被的父区块被节点找到。

区块链的分叉

难免会同时产生两个节点(设为A,B)对相同的父区块(设为P),机会同时完成新区块的工作量证明,要广播到网络中,那么就会形成两个区块分叉,就会有p–》A,p–》B,两条不同的链,这两条链都是合法的,此时网络上这两条链都马上投入新的采集当中,以延长自身的长度,竞争成为主链。剩下那条会成为备用链。此时,这些节点接纳了新的更长的链,改变原有对区块链的观点,这就叫做链的重新共识。产生的结果就是:备份链上的候选区块会成为孤块,因为他的父区块是在备份链上,主链上找不到了,原使用备份链的矿工全部停下来,使用成为主链的链条。