比特币源码分析之一:总览
一、编译
1.环境准备
通过以下命令可安装并编译bitcoind所需要的依赖库:
sudo apt-get install build-essential libtool autotools-dev autoconf automake libssl-dev libboost-all-dev libdb-dev libdb++-dev pkg-config libevent-devgit-core
2.复制Bitcoin源代码并进入其目录
通过以下命令可复制Bitcoin源代码,并且进入它的目录:
git clone https://github.com/bitcoin/bitcoin
cd bitcoin
3.编译bitcoind
首先,生成编译源码所需要的库配置,命令如下:
./autogen.sh
然后,生成makef ile文件,命令如下:
./configure--without-gui
如果在生成makef ile文件时,遇到这样的提示:
configure: error: Found Berkeley DB other than 4.8, required for portable wallets
那就可以使用如下命令:
./configure--without-gui —with-incompatible-bdb
若禁用钱包界面功能,仅提供比特币网络节点功能,则使用如下命令:
./configure --without-gui—disable-wallet
接下来,就是利用make进行编译了,命令如下:
make -j
编译好的bitcoind、bitcoin-tx和bitcoin-cli在src目录下。
最后,安装编译好的二进制文件(可选),命令如下:
make install
初期用到的主要是bitcoind(主后台程序)和bitcoin-cli(用来和bitcoind交互的命令行程序)
二、运行
1.运行bitcoind –deamon 在后台运行程序(其中可以使用—help查看命令行),如果有调试需求建议使用bitcoind –regtest 命令启动,regtest是bitcoin的三种模式(mainnet,testnet和regtest)中的一种,简单理解就是regtest是一个本地网络,策略全由自己控制,而mainnet代表主链,testnet是一个测试链(和主链的区别是挖矿更简单)
2.运行bitcoind-cli通过rpc消息和bitcoind交互
三、架构
架构图
一)模块组成
1、p2p模块
代码主要分布在net.cpp和addrman.cpp中,由于其运行也需要通过消息机制的支持,所以部分代码在net_processing.cpp中
该模块主要负责p2p网络,也就是底层的通信,包含了地址发现、地址维护、接受数据(消息)以及发送消息等功能
2、消息处理模块
代码主要在net_processing.cpp中
该模块主要负责消息的接受、发送和处理
笔者将其分为三种类型的消息
1)p2p网络类型的消息如VERSION、VERACK、ADDR、GETADDR 、PING、PONG等
2)交易类消息如TX、INV、BLOCKTXN、GETBLOCKTXN、MEMPOOL等
3)区块类消息如SENDHEADERS、SENDCMPCT、INV、GETBLOCKS、GETHEADERS、CMPCTBLOCK、HEADERS、BLOCK等
其中交易和区块类的消息是理解整个系统工作的关键,下图可以帮助代码梳理
3、区块和交易验证模块
主要在validation.cpp中
主要负责区块和交易的合法性验证(这里引出的区块链的一些核心代码,包括脚本虚拟机、验证机制等十分重要)
4、交易池模块
主要在txmempool.cpp中
该模块维护了一个交易池,池子中的交易有几个来源
1)网络上发送过来的交易
2)本地生成的交易
3)区块加入到链中失败被打回来分拆的交易(可能是工作量不够)
该模块是挖矿的源头,挖矿模块从该模块中选取交易生成区块
5、挖矿模块
主要在miner.cpp中
该模块主要负责生成区块,并尝试链接到主链(中间要经过候选链)
主要负责从交易池中根据fee(手续费)多少、时间等捞出来一些交易组成区块,生成符合标准hash(工作量证明),然后放入到候选链尝试链入区块链
6、候选区块链
是一个集合结构,变量为setBlockIndexCandidates,是一些经过了验证的区块的集合,这个是进去区块链(主链条)的必经通路
7、区块链
是一个链条,变量为chainActive(validation.cpp),一个经过验证的主链,内部结构网上介绍比较多,是一个通过hash和prehash链接起来的链
二)流程
1、网络接收区块数据流
注意:这里为了讲清楚流程部分步骤可能过于简单甚至用词不当,后续系列会详细展开
2、挖矿流程
需要解释几点
1)区块的第一个tx是basetx是这次挖矿的收益,也就是凭空生成一个交易,没有输入,只有输出,输出到矿主的比特币地址
2)挖矿是通过修改区块头中的随机数和basetx中的输入脚本中的随机数(因为basetx不需要输入所以输入脚本可以附加别的信息其中一个就是用于挖矿的随机数),两个变量共同完成的,很多资料中只是提到了区块头中的随机数是不正确的
3)挖矿是否成功是判断区块的hash是否达到标准,简单来说是前n位是否为0,n是根据历史的挖矿时间决定的,叫做挖矿难度,如果千2016个区块的平均区块生成时间大于10分钟那么n就会变大,小于则n变小
下一篇文章会介绍比特币交易是如何通过非对称加密机制来完成安全交易的,欢迎大家互动留下问题和希望讲解的题目
由于笔者能力有限,并且代码看的时间比较久远了(一直没时间来整理),可能部分写的有错误,请谅解
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。