比特币后端全解析

2020-07-25 19:44 栏目:经验之谈 来源:网络整理 查看()

在上一课中,我们学习了比特币前端的组成。今天,我们继续“拆解”比特币,看看比特币的“后端”是什么样的。

比特币节点的后端负责参与比特币网络的通信互联、维护区块链、验证区块和交易、广播和转发区块交易信息。比特币的后台程序主要由比特币和挖掘节点程序组成。比特币的核心——Qt,实际上是一个集成了前端和后端的节点(除了挖掘功能)。

1.比特币节点后端-区块链管理

区块链管理的代码逻辑在main.cpp程序中实现。主要包括四个部分:

下载区块链:当所有比特币节点第一次加入网络时,必须先下载并验证整个区块链。“头先”是一种初始的区块链下载模式,新节点先从相邻节点下载所有的块头,然后从多个相邻节点并行下载不同间隔的块,大大提高了整个区块链的下载速度。

接收区块链:当一个现有节点打开时(不是第一次),整个区块链的索引将从LevelDB转移到内存中。应当注意,该区块链的索引不是单个链,而是可以是树,也就是说,每个块只有一个父块,但是可以有多个子块。因为子块形成暂时分叉,所以有必要逐渐找出哪个子块属于最长的链。

块链验证:在区块链管理中,connectblock函数ConnectBlock()是检测“双花”事务的关键。此功能检测新接收块中的所有交易,并验证每个交易的比特币来源是否可以在当前“未使用交易输出(UTXO)”记录中找到匹配。

比特币后端全解析

重组区块链:当一个节点发现网络中有一个不再基于其当前区块链的区块链时,它需要断开现有的区块链并重组区块链。

大多数重组只是一个区块重组,而且大多数重组发生在不同的矿商几乎同时挖掘法律区块的时候。

断开块并重新组织区块链涉及UTXO更改,断开块中的事务将回滚到事务内存池。此时,“回滚”记录可用于在断开的块中来回回滚事务。

2.比特币节点后端块验证

交易验证模块将根据以下条件检查接收到的比特币交易是否合规:

事务的格式是数据结构必须正确

交易输入输出不能为空;(未输入硬币基础交易)。

事务大小不能超过定义的最大块大小最大块大小(最早1MB,然后逐渐调整)。

每个事务的输出和所有输出的总和必须在一定范围内,即大于0且小于2100万。

交易输入哈希值不能为零,并且不应转移到Coinbase交易。

Nlocktime小于或等于INT_MAX。

事务字节大小应等于或大于100。

事务的签名操作数应该小于签名操作的上限。

锁定脚本(scriptPubkey)必须是标准格式。

必须在当前交易池或主链中的一个区块中找到与接收的交易匹配的交易。

对于交易的每个输入,如果在当前交易池中可以找到其相应的UTXO输出,则交易必须被拒绝(双花交易),因为当前交易池在区块链是一个未记录的交易,并且交易的每个输入应该来自确认的UTXO。如果在当前交易池中找到它,则是双花交易。

对于事务的每个输入,如果在主链或当前事务池中找不到其对应的UTXO输出,则该事务是孤立事务,应该将该事务放入孤立事务池。

对于交易中的每个输入,如果其对应的UTXO输出是一个硬币基础交易,则初始交易应该由100个确认块确认(普通交易由6个确认块确认)。

对于事务中的每一个输入,相应的输出必须是UTXO(已存在且未使用)。

使用相应的输出事务获取输入值,并检查每个输入值及其总和是否在允许的范围内(0 ~ 2100万个比特币)。

如果事务的总输入小于总输出,则事务被拒绝。

如果交易成本太低,拒绝交易。

每个输入解锁脚本必须与相应的输出锁定脚本一起验证事务的一致性。

最后,这张支票是比特币平台设计的精髓。比特币的一大创新是依靠脚本来验证交易的合法性,也就是说,每一枚要花掉的比特币都必须有相应的来源。

锁定脚本由一系列堆栈命令和公钥哈希组成,公钥哈希是大小为20字节的RIPEMD160(SHA256(公钥))。锁定脚本的格式是:

OP _ DUP OP _ HASH 160 PubKeyHash OP _ equal verify OP _ CHECKSIG

解锁脚本由签名和公钥组成,确保拥有私钥的用户可以解锁某个交易。解锁脚本的格式是Sig PubKey。

比特币是通过将解锁脚本和锁定脚本串在一起执行的。如果最终结果是逻辑值“真”,则验证交易的比特币来源是否合法。脚本执行的过程和每次脚本执行后的堆栈状态如下:

因为它是一个堆叠的计算引擎,sig和pubKey这两个数值是一个接一个堆叠的。当脚本OP_DUP被执行时,它复制堆栈头的pubKey并将其压入堆栈。

脚本OP_HASH160将在栈头弹出pubKey,用HASH160算法散列它,把散列结果放回栈,然后遇到pubKeyHash?值,该值也被推送到堆栈上。

脚本OP_EQUALVERIFY在堆栈的首端弹出两个哈希值,并对它们进行比较。如果它们不同,验证将出错,交易将是非法的。如果验证通过,堆栈上只剩下sig和pubKey。

最后,脚本OP_CHECKSIG将它们弹出,执行检查签名的脚本,并验证事务签名是否由拥有公钥和私钥的相应用户签名。如果是这样,交易是合法的,否则就是非法的。

比特币后端全解析

3.比特币节点后端-内存池管理

比特币内存池管理也称为事务池管理。

节点将经过验证的事务放入事务池,并准备将它们放入挖掘块中。当挖掘准备就绪时,它会按照特定的优先级顺序从交易池中选择交易。

优先级根据与交易输入相对应的UTXO的“链龄”和交易金额的大小来划分。UTXO事务越老,事务量越大,事务优先级越高。

以下公式用于计算优先级:优先级=总和(输入值输入年龄)/交易大小,其中输入值根据比特币的基本单位(satoshi,satoshi)计算,一个Satoshi等于10-8个比特币。InputAge从事务在链中被记录的块开始,计算它后面的块的数量,也就是说,测量区块链中块的“深度”。事务的大小以字节为单位。

当块已满时,剩余的事务将留在内存池中,等待下一个块到达。随着他们的“链条年龄”逐渐增加,他们将来被选中的机会也会逐渐增加。

内存池中的比特币交易不会过期,但内存池中的交易不会保存在硬盘上。当挖掘节点重新启动时,内存池中的事务将被清空。

如果一个交易在一定时间内不能被矿工包含在区块链,钱包软件需要重新发送该交易,这可以附加更高的交易费用并获得优先权。

在一些比特币节点维护一个独立的“孤儿”交易池。如果找不到事务输入对应的UTXO,即没有“父”事务,它将被视为“孤立”事务,并被临时放入“孤立”事务池。当父事务到达时,孤立事务将从孤立事务池移动到内存池。

4.比特币节点后端-邻居节点管理

当一个新的比特币节点被引导时,它需要发现网络中的其他节点,并与至少一个节点连接。

通常,在端口8333与已知节点建立一个TCP连接。

连接的“握手”过程发送版本信息,包括P2P协议版本、该节点支持的服务、当前时间、对端节点的IP地址、该节点的IP地址、比特币软件版本以及该节点的当前区块链长度。

在接收到握手消息后,对方节点将回复接收确认消息。

如何通过新节点发现相邻节点;

第一种方法是使用一些“域名系统种子”来查询域名系统。

第二种方法是直接使用一个已知的邻居节点作为种子节点,然后通过它发现更多的邻居节点。

如果在一段时间内连接中没有信息交互,节点将定期发送一些信息来维持连接。

如果一个节点与其邻居之间的连接超过90分钟,则该邻居节点将被视为离线,该节点将寻找新的邻居节点进行连接。

比特币网络可以动态调整节点的连接,保证比特币网络的正常运行。

5.比特币节点后端——共识管理

比特币的广义共识管理应该包括挖掘、块验证和交易验证规则。

由于比特币的关键是在不熟悉的P2P环境中建立共识机制,因此共识管理非常重要。

在比特币版本0.12.0中,一些共识管理代码被移到了共识子目录中。

目前,共识子目录中的共识程序包括共识。*,merkle。*,参数。*和验证。*。

6.比特币节点后端-规则管理

比特币的协商一致规则是所有节点都必须遵守的策略,每个节点可以采用协商一致规则之外的一些个性化规则(例如,一个节点可以拒绝保存和传输大于200KB的交易)。规则的这一部分由规则管理模块实现,该模块当前位于策略子目录中。

7.比特币节点后端-密码模块

加密模块主要处理比特币地址,使用RIMEMD和SHA-256算法以及Base-58编码生成比特币地址。

比特币的公钥由私钥生成,公钥由安全哈希算法(SHA) SHA256和竞争完整性原语评估消息摘要(ripemd) RIPEMD160处理,最后由Base58编码形成比特币地址。

8.比特币节点后端签名模块

比特币采用椭圆曲线数字签名算法(ECDSA)实现数字签名并生成公钥。ECDSA是一种基于椭圆曲线离散对数难题的非对称密码算法和签名算法。

9.比特币节点后端脚本引擎

比特币脚本语言是一种基于堆栈的编程脚本语言,是专门设计的,类似于“Forth”。

基于堆栈的语言的指令只按顺序执行一次,也就是说,没有循环或跳转指令,所以脚本中的指令数量可以决定程序运行时间的上限和所需内存的上限。

比特币的脚本语言非常小,只有256条指令,每条指令都有一个字节长。在这256条指令中,75条是保留指令,15条已被丢弃。

脚本引擎是验证事务的操作平台。这个引擎的重要作用可以从解锁脚本和锁定脚本的自动验证中看出。

在新版比特币中,脚本引擎被放置在脚本子目录中,以后可以变成可插拔的引擎,在不影响原有比特币代码的情况下,引入新的更强大的引擎会更加方便。

目前,翻译。*,脚本。*和标准。*程序。script.h在script子目录中定义脚本命令,解释器. cpp解析、评估和比较脚本命令,而standard.h定义标准事务。

比特币通常使用以下指令:

比特币后端全解析

10.比特币节点后端挖掘

比特币最早的挖掘程序是cpuminer,它使用中央处理器进行挖掘。

采矿设备已经通过中央处理器、图形处理器和现场可编程门阵列,专用集成电路采矿设备到目前为止已经基本使用。

针对SHA256挖掘算法优化的专用集成电路挖掘设备在性能上具有其他挖掘设备无法比拟的优势。

Bfgminer程序支持现场可编程门阵列和专用集成电路采矿设备,是目前流行的采矿程序。最新的代码显示在http://www.bfgminer.org/

那么如何将网络的阻塞速度稳定在10分钟呢?比特币网络通过调整挖掘难度来实现这一目标。难度计算公式为:新难度=旧难度(2016年最后一轮实际时间/20160分钟)

11.比特币节点后端

当比特币启动时,初始化程序init.cpp将启动HTTP/JSON RPC服务器的线程组。

该组件提供了超文本传输协议和超文本传输协议的接口,外部程序可以通过超文本传输协议RPC接口调整比特币的应用编程接口,从而实现控制比特币节点的功能。

默认情况下,此接口仅接收来自此计算机客户端的连接请求。

12.比特币节点后端——伯克利数据库和二级数据库

伯克利数据库是一个开源文件数据库(由Sleepycat软件公司开发),它位于关系数据库和内存数据库之间。它的使用方式类似于内存数据库。它提供了一系列直接访问数据库的功能,主要用于备份用户的密钥。

伯克利数据库(Berkeley DB)是一个轻量级、高性能的嵌入式数据库,可以存储任意类型的键/值对,为一个键保存多个数据,支持数千个并发线程同时操作数据库,支持最大256兆字节的数据。

级别数据库用于存储块索引和UTXO记录,这是一个由谷歌实现的非常有效的键值数据库。当前版本1.2可以支持数十亿的数据。

级别数据库的数据是冗余的,可以从原始区块链数据重建。没有二级数据库数据,比特币验证和其他操作将变得非常缓慢。

13.比特币节点后端——P2P网络管理

P2P网络管理代码主要实现与P2P网络上其他邻居节点的通信功能。这些通信功能包括:发现相邻节点;连接并管理与相邻节点的套接字连接;与相邻节点交换不同的P2P消息(包括块和事务);有时,在特殊情况下,禁止连接行为异常的相邻节点。

大多数P2P代码都集中在网络上.相邻节点的IP地址管理代码是addrman.h/addrman.cpp.地址管理器将地址存储在peers.dat数据库中,然后在启动时将其调用到内存中。

比特币节点的默认配置是主动连接8个相邻节点,并允许其他节点发起多达125个连接请求。

比特币防止拒绝服务攻击(DoS)的方法是禁止行为异常的相邻节点连接。如果相邻节点发送明显的错误信息,连接将被断开,其IP地址将被禁止,其重新连接申请将被拒绝。

比特币节点根据功能分为几种类型:全功能节点、基本全功能节点和特殊目的节点

全功能节点配有钱包和RPC服务器,具有挖掘和检查节点的块和事务,并将块和事务转移到与其相连的相邻节点的功能。

整个基础节点也进行块和事务的事务和传输,但不挖掘,钱包和RPC服务器。

简化支付验证节点信任其他节点来验证块和交易。

14.比特币节点后端队列管理

比特币使用零MQ作为消息队列管理和消息分发工具。零MQ号称是“历史上最快的消息队列”,它是基于C语言开发的。

ZMQ是一个简单易用的传输层,提供了一个像框架一样的socket库,这使得Socket编程更简单、更简洁、性能更高。

ZMQ是一个消息处理队列库,可以在多线程、内核和主机盒之间灵活扩展。

ZMQ不是一个服务器,而是更像一个底层的网络通信库。它封装在套接字接口上,将网络通信、进程通信和线程通信抽象成一个统一的接口。

这就是比特币后端的全部组成。经过第一阶段的演变,区块链的发展已经进入“可编程”时代,而区块链正逐步向产品化和实用化发展。下节课我们将讨论区块链2.0——可编程区块链,敬请期待。

微信二维码
售前客服二维码

文章均源于网络收集编辑侵删

提示:仅接受技术开发咨询!

郑重申明:资讯文章为网络收集整理,官方公告以外的资讯内容与本站无关!
NFT开发,NFT交易所开发,DAPP开发 Keywords: NFT开发 NFT交易所开发 DAPP开发