交易的创建
首先,一个交易的创建是通过比特币节点的钱包应用来负责的。这里钱包应用功能的多少是由节点类型来决定的。如果是全节点,那么这个比特币钱包实际上就包含整个区块链上每笔交易的未消费输出的副本。这里提到了一个词,未消费输出。通俗点来说,就是还没有花出去的钱,也就是钱包里还可以花的钱。所以输出的意思就是花出去的钱。另外,既然有输出就要有输入,输入则指的是从别人那里得到的钱。而轻量级节点的钱包应用只负责维护自己的未消费输出。
另外,需要注意的一点是,比特币节点在创建交易的时候,可以在离线状态下进行。这个时候创建的交易暂时不会被传播到网络上,无法被网所感知,所以这笔交易会被存储在节点中的一个叫做孤立交易池的地方。而如果比特币节点在联网状态下创建的交易,交易创建完成后,就会被传播到比特币网络上,这样的话,交易就会被网络感知到,存储到每个节点的交易池中。
交易的传播
比特币网络存在的目的就是讲交易和区块传播给所有的参与者。节点在网络上的连接方式是任意的。可以通过有线、WiFi、移动网络或者其他方式进行连接。一个节点将创建的交易通过gossip协议进行传播。gossip协议是一种通信协议,主要用在分布式数据库系统中各个副本节点同步数据之用,这种场景的一个最大特点就是组成的网络的节点都是对等节点,是非结构化网络
任何收到了之前没见过的有效交易的比特币节点,会立即向连在它之上的所有其他节点转发,这个传播技巧叫做洪泛。因此,交易迅速在整个点对点网络上迅速传播,在几秒钟之内传播到大部分节点。
另外,需要注意的一点是,一笔交易需要传递至比特币网络,才能被传播,也才能加入区块链中。本质上,一笔比特币交易只是200到400字节的数据,而且它们必须被发送到成千上万个比特币节点中的任意一个。
一旦一笔比特币交易被发送到任意一个连接至比特币网络的节点,这笔交易将会被该节点验证。如果交易被验证有效,该节点将会将这笔交易传播到这个节点所连接的其他节点。同时,交易发起者会收到一条表示交易有效并被接受的返回信息。如果这笔交易被验证为无效,这个节点会拒绝接受这笔交易且同时返回给交易发起者一条表示交易被拒绝的信息。另外,比特币节点在验证交易的时候,验证方式会随着节点类型的不同而不同。对于全节点来说,因为它本身就具有整个区块链上每笔交易的未消费输出的副本,所以它既能构建交易,也能快速验证收到的新交易;而对于轻量级节点来说,由于它只维护自己未消费的输出,所以它在验证交易的时候需要通过不同的服务提供者的各种可用可编程接口(API)从比特币网络查询这个信息,或者通过全节点的API调用来查询这个信息。
由于这笔交易是经过签名且不含任何机密信息、私钥或密码,因此它可被任何潜在的便利网络公开地传播。比特币交易因此可以通过未加密网络(例如WiFi、蓝牙、NFC、ChirP、条形码或者复制粘贴至一个网页表格)被发送到比特币网络比特币交易的安全性,是由各个节点的验证,以及数字签名这些来保证的。比特币将金钱变成了一种数据结构,所以在本质上是不可能阻止任何人创建并执行比特币交易的。
交易被打包进区块上链
一个交易已经在比特币网络上进行传播,它只有通过“挖矿”的过程被检验并被包括到一个区块之中才会成为区块链的一部分。挖矿在比特币系统中有两个作用:
- 挖矿节点通过参考比特币的共识规则检验所有交易。因此挖矿通过拒绝无效或者不正常的交易为比特币交易提供安全保证。
- 挖矿在构建区块时会创造新的比特币,这与中央银行印发新的纸币很类似。每个区块创造的比特币数量是有限的并按照随着时间减少的固定发行规则。
新的交易持续地从钱包和其他应用中流入网络。当这些交易被比特币网络的节点所看到时,便会被加入每个节点维护的未验证交易的临时池子,也就是前面提到的交易池中。当矿工打包新的区块时,他们从池子中选择未验证的交易通过挖矿软件进行验证,验证通过之后加入新区块,然后尝试使用工作量证明算法来证明这个新块的有效性。
交易被加入到区块中之后,会按照最高手续费和其他一些条件进行优先级排序,一般情况下,手续费越高,交易通过验证以后打包越快。这个时候矿工开始挖矿,一旦有矿工挖出来以后,并且在全网发布了区块,那么在挖这个区块的其他矿工就知道自己输掉了这一轮的竞争,就会开始挖掘新的区块。
挖掘新区块的步骤
- 创建一个新区块
- 填入交易和前一个区块的指纹
- 为新区块计算工作量证明
- 每个矿工在新区块中添加一条特殊交易,用来指向他自己的比特币地址支付报酬,再加上来自所有被包括在这个区块中的手续费之和
如果他发现一个让这个区块“有效”的解答,便“赢得”了报酬,因为他发现的区块被加入到了全球区块链,他得到的奖励交易也变得可用。
需要注意的一点是,这个区块如果遭遇到双花攻击等类似的攻击,很有可能被废掉。所以一般情况下,任何有6个或者以上确认的区块可以被看作是不可逆的,因为如果要作废和重新计算6个区块所需要的计算量是巨大的。
虽然比特币系统平均每10分钟出一个块,或者等到6个区块挂在后面的时候,交易就已经可以完全确定被全网接受并且不会被废掉了。但是这样的延迟对于小额交易来说太长了。所以一个商人可能接受一笔有效的小额交易而不需要任何确认。因为本身交易的数额比较小,就算是损失,也损失不大,在商人的可承受范围之内。
节点之间的通信和信息交换
说完了从交易创建到交易被打包进区块的过程,不妨再进一步,看看节点之间的通信和信息交换是怎么进行的。首先,我们知道比特币是在互联网之上依照点对点网络架构来设计的。因为每一个节点在网络中都是平等的,也就是他们既可以充当客户端,也可以充当服务器,所以网络是一种扁平化的拓扑结构,以这样的形式在网状网络中相互连通。
“比特币网络”指的是运行比特币P2P协议的节点集合。在比特币P2P协议之外,比特币网络还包含其他的协议,例如Stratum,被用于挖矿,轻量级或者移动钱包。基于比特币协议访问比特币网络的网管路由器提供这些额外协议,将网络扩展到运行其他协议的节点。我们使用“扩展比特币网络”来代指包括了比特币P2P协议、矿池挖矿协议、Stratum协议以及其他任何连接比特币系统组件的相关协议的整体网络。
虽然比特币的P2P网络中的节点彼此对等,但取决于支持的功能,他们可能扮演不同的角色。一个比特币节点是一个功能集合:路由、区块链数据库、挖矿和钱包服务。
包括四种功能的全节点如图所示:
常见的比特币节点类型如下图所示:
由这些节点所组成的扩展比特币网络的拓扑如下图所示:
虽然比特币网络很好地通过P2P的网络架构实现了去中心化,通过工作量证明的共识机制实现了很好的安全性,但是由此带来的弊端就是它的网络延迟太高了。比如比特币系统区块的平均产生速率是10分钟,然后区块广播到网络上的各个节点也有时延。这其中最关键的就是矿工在传播自己的获胜区块和下一轮竞争之间的时间。一旦这个时延一长很容易出现问题。这里举一个例子,同时有两个矿工挖到了区块,然后两个矿工一块进行广播,其中一个矿工的延迟小,而另一个矿工的链路突然故障(即传播的延迟可以理解为无穷大),这个时候能够成功获得报酬的矿工显然是哪个延迟小的矿工,而另一个矿工的区块就直接废掉了。或者这个矿工在把链路修好后,换了更好的链路,使他的延迟更小,他就可以选择把这个区块保留,但是不公布,接着挖,一旦运气好,迅速挖到了下一个区块,那么就可以一下子公布两个区块,直接使主链分叉,同时因为新的链要比主链要长,依据最长链原则,那么新的链就会变成主链,那么该矿工就会一下子获得两份奖励,这就是利用该延迟(矿工在传播自己的获胜区块和下一轮竞争之间的时间)进行分叉攻击的原理。
所以,为了缩短矿工之间传送区块延时,有人开发出了比特币中继网络。最初的比特币中继网络是核心开发者Matt Corallo在2015年创建的,以便能在矿工之间以极低延时实现区块的快速同步。这个网络由几个托管在全球Amzon Web Service(由美国亚马逊公司提供的云计算服务)的基础设施上的特殊节点组成,用来连接绝大多数的矿工和矿池。
后来,最初的比特币中继网络在2016年被替换成快速互联网比特币中继引擎(Fast Internet Bitcoin Relay Engine,简称为FIBRE),它还是有核心开发者Matt Corallo创建的。FIBRE是一个基于UDP协议的中继网络,在网络节点之间传播区块。FIBRE实现了紧凑区块的优化来进一步降低传送的数据量与网络延时。
Falcon是另一个中继网络(仍在提案阶段),它是基于康奈尔大学的研究提出的。Falcon使用“直通式路由”而非“存储-转发”式路由来降低时延。这种方法当收到一个区块的一部分内容时就开始传输,而不是等到完整的区块被接收。中继网络不是比特币P2P的替代品。相反,它们是覆盖网络,为存在特殊需求的节点之间提供额外的连接。就好像高速公路不是村道的替代品,而是交通繁忙的两点之间的捷径,但你仍然需要有小路连接到高速公路。
比特币P2P网络的网络发现机制
一个新的节点启动后,为了参与网络协同,必须发现网络中其他的比特币节点
一个新节点可以使用DNS种子来查询已知节点的IP地址信息,通过查询到的IP地址,或者可以被提供至少一个比特币节点的IP地址,然后建立连接
为了连接到一个已知节点,节点间要建立一个TCP连接,通常在8333端口
建立连接的时候,节点会发送一个包含基本识别信息的版本消息开始一次握手
当一个或者多个连接被建立,新的节点会向它的邻居发送包含自己IP地址的addr消息,它的邻居们会接着将这条消息转发给它们的邻居们,保证新接入的节点变得众所周知并被更好的接入网络
另外,新接入的节点可以发送getaddr消息给它的邻居,要求他们返回其他对等节点的IP地址列表,这样,一个节点可以发现能连接的对等节点并在网络上告知自己的存在以让其他的节点发现它
一个节点必须连接到若干个不同的对等节点以建立比特币网络的不同路径,因为一条路径并不是一直可靠的,所以节点丢失老的连接的时候,还有为其他节点提供引导辅助的时候,它必须持续发现新节点
新节点在被引导之后,节点会记住它最近连接成功的对等节点,当它重启之后,它可以从之前的对等网络中快速重建连接,如果之前的节点已经离开比特币网络,没有响应它的连接请求,他可以再次使用种子节点进行引导
如果一个连接上没有通信,节点会定期发送一个消息以维持这个连接,如果一个节点在一个连接上超过90分钟没有通信,它会被认为已经从这个连接断开并寻找一个新的对等节点
比特币交易
我们回到两个人转账交易的过程中,去理解比特币区块链的数据结构。
我发起一笔交易,即我向整个区块链网络广播,我和你两个人想进行这笔交易:我向你的地址中转入一笔比特币,无须你的许可。但只有当这笔交易被打包进最新的比特币区块中时,这笔交易才真正完成。通常来说,当在一笔交易所在的区块之后又增加 5 个区块,即包括它自己在内一共经过 6 次确认时,这笔交易可认为被完全确认。按比特币每个区块的确认时间 10 分钟估算,即一笔交易最终确认要经过约 1 小时。
这里包括了两步:一是交易被打包进候选区块,每个节点可以按规则生成不同的候选区块;二是节点挖矿成功,候选区块被成功地加到区块链的尾部,成为最新的正式区块。那么,把一笔交易打包进区块是什么意思呢?这涉及区块链最基础的数据结构,这也是它不可篡改的基础。
区块链之所以被称为 blockchain,是因为它的数据块以链状的形式存储着。从第一个区块即所谓的创世区块开始,新增的区块不断地被连到上一个区块的后面,形成一条链条。每个区块由两个部分组成——区块头部和区块数据。其中,区块头部中有一个哈希指针指向上一个区块,这个哈希指针包含前一个数据块的哈希值。哈希值可以被看成是数据块的指纹,即在后一个区块的头部中均存储有上一个区块数据的指纹。如果上一个区块中的数据被篡改了,那么数据和指纹就对不上号,篡改行为就被发现了。要改变一个区块中的数据,对其后的每个区块都必须相应地进行修改。
比特币区块链设计有一种机制让这种修改难以发生,即“工作量证明”
一个区块中的数据是被打包进这个区块的一系列交易。这些交易按照既定的规则被打包形成特定的二叉树数据结构——梅克尔树(Merkle trees)。按目前的比特币区块的大小,一个区块中能容纳的交易数量在 2000 个左右,比如在第 526957 个区块中容纳了 1804 个交易。
比特币区块链的数据结构中包括两种哈希指针,它们均是不可篡改特性的数据结构基础。一个是形成“区块+链”(block+chain)的链状数据结构,另一个是哈希指针形成的梅克尔树(见图 1)。链状数据结构使得对某一区块内的数据的修改很容易被发现;梅克尔树的结构起类似作用,使得对其中的任何交易数据的修改很容易被发现。
转发:https://www.dandelioncloud.cn/article/details/1585271189360857089