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

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

一、编译

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 条评论
登录 后参与评论

相关文章

来自专栏以太坊开发

android和java程序员使用web3j进行区块链以太坊开发详解

如何使用web3j为Java应用或Android App增加以太坊区块链支持,教程内容即涉及以太坊中的核心概念,例如账户管理包括账户的创建、钱包创建、交易转账,...

3407
来自专栏极客编程

开发基于以太坊智能合约的DApp

最近要找个H5的前端写个简单的DApp,聊过几个H5的工程师,都被跟以太坊交互的部分吓住了。虽然网上有N多的教程,但是对于H5工程师来说,还是有些困难。分析其原...

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

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

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

1681
来自专栏区块链大本营

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

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

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

如何在Spectrum公链上开发Dapp?

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

1182
来自专栏区块链技术指北

区块链钱包开发

文/温国兵 本文由币乎社区(bihu.com)内容支持计划奖励。 这是「区块链技术指北」的第 21 篇文章。 如果对我感兴趣,想和我交流,我的微信号:Wenta...

8778
来自专栏liuchengxu

用 Parity 发送 ERC20 Token

Parity 是以太坊的 Rust 实现,它也内置了一个钱包。用过 Parity 的人都知道,用它发送 ETH 非常简单,点几下就行。但是可能不少人还不知道如何...

1174
来自专栏极客编程

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

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

831
来自专栏区块链入门

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

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

842
来自专栏丑胖侠

以太坊Geth几种同步模式

同步模式分类 –fast Enable fast syncing through state downloads –light Enable light cli...

4999

扫码关注云+社区