引言
我们所构建的原型已经具备了区块链所有的关键特性:匿名,安全,随机生成的地址(公私钥加密)
;区块链数据存储(key-value存储)
;工作量证明系统(pow)
;可靠地存储交易(MerkleTree)
。
尽管这些特性都不可或缺,但是仍有不足。能够使得这些特性真正发光发热,使得加密货币成为可能的,是网络(network)
你可以将这些区块链特性认为是规则(rule),类似于人类在一起生活,繁衍生息建立的规则,一种社会安排。区块链网络就是一个程序社区,里面的每个程序都遵循同样的规则,正是由于遵循着同一个规则,才使得网络能够长存。类似的,当人们都有着同样的想法,就能够将拳头攥在一起构建一个更好的生活。如果有人遵循着不同的规则,那么他们就将生活在一个分裂的社区(州,公社,等等)中。同样的,如果有区块链节点遵循不同的规则,那么也会形成一个分裂的网络。
区块链网络
区块链网络是去中心化的,这意味着没有服务器,客户端也不需要依赖服务器来获取或处理数据。在区块链网络中,有的是节点,每个节点是网络的一个完全(full-fledged)成员。节点就是一切:它既是一个客户端,也是一个服务器。这一点需要牢记于心,因为这与传统的网页应用非常不同。
区块链网络是一个 P2P(Peer-to-Peer,端到端)的网络,即节点直接连接到其他节点。它的拓扑是扁平的,因为在节点的世界中没有层级之分。下面是它的示意图:
节点角色
尽管节点具有完备成熟的属性,但是它们也可以在网络中扮演不同角色。比如:
- 矿工:这样的节点运行于强大或专用的硬件(比如 ASIC)之上,它们唯一的目标是,尽可能快地挖出新块。矿工是区块链中唯一可能会用到工作量证明的角色,因为挖矿实际上意味着解决 PoW 难题。在权益证明 PoS 的区块链中,没有挖矿。
- 全节点:这些节点验证矿工挖出来的块的有效性,并对交易进行确认。为此,他们必须拥有区块链的完整拷贝。同时,全节点执行路由操作,帮助其他节点发现彼此。对于网络来说,非常重要的一段就是要有足够多的全节点。因为正是这些节点执行了决策功能:他们决定了一个块或一笔交易的有效性。
- SPV:SPV 表示 Simplified Payment Verification,简单支付验证。这些节点并不存储整个区块链副本,但是仍然能够对交易进行验证(不过不是验证全部交易,而是一个交易子集,比如,发送到某个指定地址的交易)。一个 SPV 节点依赖一个全节点来获取数据,可能有多个 SPV 节点连接到一个全节点。SPV 使得钱包应用成为可能:一个人不需要下载整个区块链,但是仍能够验证他的交易。
比特币节点的通信流程
-
获取到当前比特币网络中网络状况正常的节点列表(获取种子节点列表)。
-
运行比特币的协议栈,与比特币网络中的其他节点通信。
1.获得比特币其他节点
使用“DNS种子”(DNS seeds)
比特币源码的chainparams.cpp文件中,一共包含了6个DNS域名,可以用于新节点加入比特币网络时获取种子节点列表。
seed.bitcoin.sipa.be |
---|
dnsseed.bluematt.me |
dnsseed.bitcoin.dashjr.org |
seed.bitcoinstats.com |
seed.bitcoin.jonasschnelli.ch |
seed.btc.petertodd.org |
dig seed.bitcoinstats.com
seed.bitcoinstats.com. 3591 IN A 172.104.154.196 seed.bitcoinstats.com. 3591 IN A 89.116.26.27 seed.bitcoinstats.com. 3591 IN A 146.4.124.134 seed.bitcoinstats.com. 3591 IN A 77.174.251.3 seed.bitcoinstats.com. 3591 IN A 93.216.157.252 seed.bitcoinstats.com. 3591 IN A 94.19.7.55 seed.bitcoinstats.com. 3591 IN A 50.38.34.178 seed.bitcoinstats.com. 3591 IN A 178.14.78.87 seed.bitcoinstats.com. 3591 IN A 62.168.65.42 seed.bitcoinstats.com. 3591 IN A 93.198.213.253 seed.bitcoinstats.com. 3591 IN A 190.2.152.245 seed.bitcoinstats.com. 3591 IN A 95.216.3.111 seed.bitcoinstats.com. 3591 IN A 193.232.158.22 seed.bitcoinstats.com. 3591 IN A 188.165.211.112 seed.bitcoinstats.com. 3591 IN A 128.199.55.88 seed.bitcoinstats.com. 3591 IN A 207.180.251.119 seed.bitcoinstats.com. 3591 IN A 134.209.84.163 seed.bitcoinstats.com. 3591 IN A 188.120.255.115 seed.bitcoinstats.com. 3591 IN A 45.227.253.238 seed.bitcoinstats.com. 3591 IN A 62.210.110.208 seed.bitcoinstats.com. 3591 IN A 95.216.226.214 seed.bitcoinstats.com. 3591 IN A 202.172.102.5 seed.bitcoinstats.com. 3591 IN A 185.78.209.40 seed.bitcoinstats.com. 3591 IN A 92.100.48.186 seed.bitcoinstats.com. 3591 IN A 92.58.171.140
DNS种子提供比特币节点的IP地址列表,Bitcoin Core客户端提供五种不同的DNS种子,通常默认使用即可。
手动指定节点
手动通过-seednode命令指定一个比特币节点的IP地址作为比特币种子节点。
2.与比特币节点进行初始“握手”,建立连接
握手的发起者会向目标节点发起TCP连接,默认为8333端口(部分节点不使用8333端口),连接建立成功后,双方需要根据比特币协议的规定,完成握手的过程,主要是确认双方版本、IP地址、端口等信息。
version请求
节点1为握手的发起者,希望与节点B进行握手,首先向2节点发送一个version消息(含有自己的协议版本等),节点2收到节点1的version消息后,会对数据包进行验证,若验证无误,则会向1回应自己的version消息,否则,节点2将忽略掉节点1的消息。节点2在回应了自己的version消息之后,会再回应一个version ack的消息。节点A在收到2节点的version ack消息后,向节点2回应一个version ack,握手过程即正常结束。
3.获取节点周围缓存节点
在完成握手后,通过向对方节点发送getaddr消息,即可获取其周围活跃节点。
getaddr请求
addr:返回节点个数和节点列表
4.下载区块链头
getblocks 请求
在version请求中,我们可以知道自己的区块高度和对方的区块高度,如果我们的区块链高度小,则需要请求区块头数据。
5.同步区块链数据,并验证
节点下载完区块头后,会开始下载区块。
Inv-type=block 请求
比特币区块链中的每个区块都包含了一系列交易记录和一些元数据,例如区块的哈希值、时间戳、难度目标、交易数量等信息。
节点会从其他节点中请求缺失的区块数据,直到下载完整个区块链。
6.处理交易
Inv-type=transaction 请求
- 如果交易是自己节点产生的,自己先把交易缓存到mempool中,并转发给所有已知的节点。
- 如果节点收到了其他节点的交易,验证交易,并放到自己的mempool,并转发给其他节点。
7.挖矿
如果这个节点是矿工节点,当mempool大于某个值时,执行挖矿操作,并清空所有的mempool。
广播自己的新区块到其他所有节点。
其他节点会验证区块,并判断这个区块是不是最长的链上,如果不是最长链节点会拒绝这个区块。
比特币分叉
比特币网络正常运行依赖于节点按一致的规则检验和收录区块,这种情况下即便偶尔同时有多个相同高度的正确的区块产生,分支博弈
也会导致全网迅速归集到同一链上。
但当涉及规则改变时,即网络中存在遵守不同的规则的旧节点和新节点时,就会存在区块链分叉且不能迅速回归同一链的可能,按具体情况又分为硬分叉和软分叉:
软分叉
比特币软分叉(Soft Fork)是指对比特币协议进行一项改进,该改进是向后兼容的,也就是说,旧版本的比特币节点可以继续运行,而无需升级。在软分叉中,升级后的节点能够处理新规则的交易,但旧版本的节点会将这些交易视为有效。
软分叉通常是为了改进比特币协议而进行的,以提高其安全性、可扩展性和其他方面的性能。软分叉通常需要比特币网络中大部分的矿工和节点支持,以确保网络的顺畅升级。如果不支持软分叉,那么这些节点和矿工将被视为“分叉”,从而分离出去,并与其他支持该软分叉的节点和矿工形成两个独立的网络。
总之,软分叉是比特币协议的一种改进方法,它可以通过向后兼容的方式升级,而无需强制用户升级其软件。
硬分叉
比特币硬分叉(Hard Fork)是指对比特币协议进行一项改进,该改进不向后兼容,也就是说,旧版本的比特币节点无法处理新规则的交易,因此必须升级节点软件。在硬分叉中,新版本的比特币节点和旧版本的比特币节点无法互相通信。
硬分叉通常是为了解决协议中存在的不兼容性问题而进行的。硬分叉可能会导致比特币网络分裂成两个独立的网络,其中一个网络遵循旧规则,另一个网络遵循新规则。在这种情况下,两个网络都可以独立运作,但可能会导致比特币的价值和市场流动性受到影响。
同时挖出区块会导致分叉吗?
会,但是短暂的。
比特币网络会选择最长的分支作为有效的区块链。矿工和节点会比较两个分支的长度,选择最长的分支,然后在其上继续进行工作。这意味着在区块链的另一个分支上工作的矿工会停止工作,并加入最长的分支。这个过程通常被称为“链的重组”。
这是因为矿工的工作量越大,他们获得的收益也就越高,因此他们更有动力在最长的分支上继续工作,而不是在较短的分支上浪费资源。因此,分叉通常是短暂的,并很快被解决。
所以这并不会影响比特币网络的稳定性。
大部分内容来自:
https://github.com/Jeiwan/blockchain_go