比特币源码研读之六

本文将继续参数处理其他部分源码的研读。

本文主要涉及的源码文件包括:

src/bitcond.cpp、src/util.h、src/util.cpp、src/init.h、src/init.cpp、src/chainparamsbase.h、src/chainparamsbase.cpp、src/chainparams.h、src/chainparams.cpp

一、比特币网络

比特币网络分为主网、测试网以及私有网三种网络,其中主网就是我们现在使用的正式运行的可进行实际交易的网络,在其上我们可以实现物品的交易与服务;测试网顾名思义即为公共测试网络,因为其实测试网,所以,其上的信息是可以重设的;私有网的难度很低,很容易产生块,所以开发者一般在私有网中开展应用的开发与自测试。三个网络的的英文名分别为:

主网:Main network

测试网:Testnet (v3)

私有网:Regression test

二、选择比特币网络

介绍完比特币网络的三种类型后,我们来看如下代码:

//Check for -testnet or -regtest parameter (Params() calls are only valid afterthis clause)

try{

SelectParams(ChainNameFromCommandLine());

} catch (const std::exception&e) {

fprintf(stderr,"Error: %s\n", e.what());

returnfalse;

}

首先我们来看代码注释,其注释的含义为检测-testnet或者-regtest参数。那么这两个参数是什么意思呢?它们分别是我们前面介绍的测试网和私有网。

知道了后面代码的具体功能后,我们就继续对代码进行深入剖析。注释后面的代码通过try catch异常捕捉机制实现比特币网络设置工作。在try代码块中,SelectParams函数以ChainNameFromCommandLine()返回值作为参数,SelectParams函数的声明位于src/chainparams.h中,其参数为字符串类型。那ChainNameFromCommandLine()的返回值是什么呢?

(1)获取网络名称

要知道ChainNameFromCommandLine()的返回值需进入src/chainparamsbase.cpp一看究竟。其函数实现如下:

std::string ChainNameFromCommandLine()

{

boolfRegTest = GetBoolArg("-regtest", false);

boolfTestNet = GetBoolArg("-testnet", false);

if(fTestNet && fRegTest)

throwstd::runtime_error("Invalid combination of -regtest and -testnet.");

if(fRegTest)

returnCBaseChainParams::REGTEST;

if(fTestNet)

returnCBaseChainParams::TESTNET;

returnCBaseChainParams::MAIN;

}

ChainNameFromCommandLine()函数从其名称可以看出,该函数将从命令行中获取链路的名称。其实现流程如图所示。

1)该函数首先获取"-regtest"与"-testnet"参数设置情况;

2)如果两个参数都设置了,因为一个比特币程序不可能同时存在两个网络,所以,程序将异常退出,同时抛出异常错误,由之前的try catch模块处理,打印异常错误提示信息;

3)如果只设置了回归测试,则返回CBaseChainParams::REGTEST,REGTEST为静态字符串常量,代表的是回归测试,与其并行的另两个网络描述字符串也为静态字符串常量,他们均在src/chainparamsbase.h中声明,也同时在src/chainparamsbase.cpp中定义。其声明与定义如下:

声明:

定义:

const std::string CBaseChainParams::MAIN = "main"; //主网

const std::string CBaseChainParams::TESTNET = "test"; //测试网

const std::string CBaseChainParams::REGTEST = "regtest"; //私有网

4)如果只设置了测试网络,,则返回CBaseChainParams::TESTNET;

5)如果都没有设置,则返回,则返回CBaseChainParams::MAIN。

(2)网络基本参数设置

在获得网络名称后,我们将其传给SelectParams函数,该函数的实现位于chainparams.cpp中,其函数实现如下:

void SelectParams(conststd::string& network)

{

SelectBaseParams(network);

pCurrentParams = &Params(network);

}

在该函数中首先调用SelectBaseParams函数,该函数的实现位于chainparamsbase.cpp中,其函数实现内容如下:

void SelectBaseParams(conststd::string& chain)

{

pCurrentBaseParams = &BaseParams(chain);

}

在该函数中,实现了对链参数对象pCurrentBaseParams的赋值,pCurrentBaseParams的类型为CBaseChainParams指针,其定义位于src/chainparams.cpp中,从定义可以看出pCurrentBaseParams为静态全局变量。

static CBaseChainParams* pCurrentBaseParams = 0;

CBaseChainParams类为前面提到的3种区块链基本参数的基类,3种区块链基本参数设置类分别为:CBaseMainParams、CBaseTestNetParams、CBaseRegTestParams,其定义位于src/chainparamsbase.cpp中,具体定义代码如下:

/**

*Main network主网

*/

class CBaseMainParams : publicCBaseChainParams

{

public:

CBaseMainParams()

{

nRPCPort = 8332;

}

};

static CBaseMainParams mainParams;

/**

*Testnet (v3)测试网

*/

class CBaseTestNetParams : publicCBaseChainParams

{

public:

CBaseTestNetParams()

{

nRPCPort = 18332;

strDataDir = "testnet3";

}

};

static CBaseTestNetParams testNetParams;

/*

*Regression test私有链

*/

class CBaseRegTestParams : publicCBaseChainParams

{

public:

CBaseRegTestParams()

{

nRPCPort = 18332;

strDataDir = "regtest";

}

};

static CBaseRegTestParams regTestParams;

从上述定义我们可以看到每个类的构造函数中定义了主链、测试链以及私有链使用的端口与数据目录,其端口分别为8332、18332以及18332。

在完成3种链的定义后,我们再来看BaseParams函数的实现就很容易明白其返回值的意义了:

CBaseChainParams& BaseParams(conststd::string& chain)

{

if (chain == CBaseChainParams::MAIN)

return mainParams;

else if (chain == CBaseChainParams::TESTNET)

return testNetParams;

else if (chain == CBaseChainParams::REGTEST)

return regTestParams;

else

throw std::runtime_error(strprintf("%s: Unknown chain %s.",__func__, chain));

}

BaseParams将返回对应链的基本参数对象,并赋值给pCurrentBaseParams。

3)主要参数设置

我们最后再来看SelectParams中的pCurrentParams = &Params(network);代码。其实现与我们刚看到的BaseParams有点类似,只不过其少了Base单词而已,我们可以这样理解,在执行完链的基本参数设置后,比特币程序将设置相应链的主要参数了。从Params函数实现我们可以看到,其实现与BaseParams是一样的,都是根据链名称获取相应的链参数对象,只不过此处的链路参数类中包含的参数信息更详细些。主链、测试链以及私有链对应的类分别为CMainParamsCTestNetParamsCRegTestParamsstatic,这3个类的定义位于src/chainparams.cpp中,它们均继承了CChainParams类,通过CChainParams可知链参数类主要实现共识参数、CDNSSeedData种子数据、默认端口、创世块信息以及链交易数据等参数的设置。

这里要着重讲解的是共识参数与创世块信息参数,它们分别为:

Consensus::Params consensus;

CBlock genesis;

因为我们主要使用主网,因此以主网中的参数内容来说明我们经常听到的区块奖励减半、出块时间、创世块奖励等参数是如何设置的。

区块奖励减半间隔:consensus.nSubsidyHalvingInterval = 210000;

算力极限值:consensus.powLimit =uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");

算力修改间隔:consensus.nPowTargetSpacing = 10 * 60;即10分钟

创世块genesis = CreateGenesisBlock(1231006505, 2083236893,0x1d00ffff, 1, 50 * COIN);第一个块的奖励为50个比特币

以上这些参数都是我们经常听到的名词,如果我们想创建自己命名的数字货币,只需简单修改这些参数即可,比如把区块奖励减半间隔修改为420000或其他数,创世块中比特币奖励的50该为100或其他数。所以要创建一个自己的数字货币并不难,关键在于看其是否有应用价值。

程序在每个类的定义之后,程序也定义了对应的静态链参数对象。

static CMainParamsmainParams;

staticCTestNetParams testNetParams;

staticCRegTestParams regTestParams;

Params将根据用户设置的链参数名称,将对应的链参数返回给pCurrentParams,从而完成链基本参数与主要参数的实现任务。

至此,程序根据用户输入的网络类型参数完成了比特币运行网络的设置。在这段代码中,我知道了私有网络,以前听得最多的是主网和测试网,而私有网或私有链基本很少听到,在这段代码中我知道了私有链是开发团队在开发时使用的网络,因为其挖矿难度很低,很容易进行程序的调试与功能试验。进而让我明白了一些区块链项目为什么会说在XX时刻要进入测试网阶段,然后再是最终的主网运行阶段。因此区块链开发过程应该是这样的:

以上就是本文的源码研读过程,通过源码的研读确实让我更好地理解区块链网络的运转过程,也让我清晰地明白市场上每个区块链的具体进程,这样可以让我更好地判断每个区块链产品的价值,对我投资区块链资产也有很大的帮助。

我是区块链研习社的菜菜子,我将继续深入研究比特币源码,源码研读系列也将继续更新,敬请期待!

作者:区块链研习社比特币源码研读班 菜菜子


以下是广告:

我们区块链研习社已创建“区块链研习社币圈交流”小密圈”,在小密圈中,我们将带领大家一起学习区块链的原理与投资,还将提供区块链基本原理解答、交易所注册与交易操作、ICO交易与操作、投资分析、风险分析等内容。

目前入圈价格初始定价50元,50人调整一次价格,每次调整幅度为50元!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,513评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,312评论 1 305
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,124评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,529评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,937评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,913评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,084评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,816评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,593评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,788评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,267评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,601评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,265评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,158评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,953评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,066评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,852评论 2 277

推荐阅读更多精彩内容

  • 原文地址 https://mbinary.coding.me/introduction-to-bitcoin.ht...
    mbinary阅读 4,945评论 0 4
  • 以前,我经常听人说:“好孩子是夸出来的”,我不愿苟同,颇有微词。但最近的一件事让我彻底改变了看法。 ...
    7710b5521df3阅读 200评论 0 3
  • 周二,国庆节,家。 天气晴。 1.有时候爱一个人,就是把无聊的事情拿出来跟她分享。 你会发现,明明很无聊的一件事,...
    蘑菇菌阅读 83评论 0 1
  • 【标 题】短暂之旅,烙印之深 【作 者】烈焰二连 迷谷 【正文字数】1389 同一个剽悍,不同的你我,...
    zhen_5ac6阅读 181评论 0 0
  • 1月12日,晴,忙晕。 阅读书目:《日本的八个审美意识》 作者:黑川雅之毕业于日本著名的早稻田大学,他是日本少有的...
    陈陈_19b4阅读 623评论 0 3