比特币源码分析之一:总览

比特币源码分析之一:总览

一、编译

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变小

下一篇文章会介绍比特币交易是如何通过非对称加密机制来完成安全交易的,欢迎大家互动留下问题和希望讲解的题目

由于笔者能力有限,并且代码看的时间比较久远了(一直没时间来整理),可能部分写的有错误,请谅解

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏极客编程

比特币钱包隔离认证开发指南 原

本文件的大部分内容可以在与隔离认证相关的BIP中找到,包括BIP141,BIP143,BIP144和BIP145。请将此视为阅读其他相关文件的第一个参考点,并作...

1051
来自专栏深入浅出区块链技术

如何编写一个可升级的智能合约

区块链信任基础的数据不可修改的特性,让它传统应用程序有一个很大的不同的地方是一经发布于区块链上就无法修改(不能直接在原有的合约上直接修改再重新发布)。

1921
来自专栏丑胖侠

以太坊rpc接口调用之nonce

背景 我们在使用以太坊相关的json-rpc借口发送交易时,往往会出现这种现象:交易已经发送出去,也获得了交易的hash值。dev模式的geth也在正常挖矿,可...

26910
来自专栏丑胖侠

以太坊客户端Ethereum Wallet与Geth区别简介

最近有不少朋友在搭建交易平台,在咨询和技术交流的过程中发现很多朋友不太清楚Ethereum Wallet和Geth区别。甚至有朋友使用Geth的API接口来调用...

5475
来自专栏祥云无界

imtoken钱包的使用教程

为了方便大家使用imtoken钱包,在这里将imtoken钱包使用教程详细的给大家展示出来。钱包使用很简单,但是需要大家多熟悉。还有文章中有红色字体提示的内容为...

3.1K31
来自专栏liuchengxu

用 Go 构建一个区块链 -- Part 7: 网络

翻译的系列文章我已经放到了 GitHub 上:blockchain-tutorial,后续如有更新都会在 GitHub 上,可能就不在这里同步了。如果想直接运行...

1133
来自专栏区块链大本营

10岁小表妹也能“吃透”Geth 客户端 !360秒,快速部署 ICO Token

接下来,你可以输入 geth –help 来检查 Geth 是否已安装成功。如果此时显示出一些帮助信息,你就可以进行下一步,创建一个新账户。

963
来自专栏区块链入门

【财务安全】如何使用imToken钱包进行离线签名

注: 使用你的联网手机是热钱包, 用来观察钱包, 未联网手机作为冷钱包用作离线签名授权

932
来自专栏华仔的技术笔记

一个eos dapp的区块链小游戏开发学习笔记

3.1K5
来自专栏华仔的技术笔记

如何在Spectrum公链上开发Dapp?

Spectrum光谱链是由Ethereum以太坊的链发展而来,所以是完全兼容以太坊。 但是又有不同,主要是共识机制不同,二级架构layer2不同,更加兼容移动...

1402

扫码关注云+社区

领取腾讯云代金券