比特币源码研读之七
源码研读系列从第4期开始到现在已有3期在介绍参数处理部分,可见这部分内容对于比特币后台进程来说是很重要的,因为其运行的状态是根据用户输入的参数来决定的,所以这部分的介绍相对会多些,我将在本期完成该部分源码的研读。话不多说,我们继续参数处理剩余部分源码的研读。

本文主要涉及的源码文件包括:
src/bitcond.cpp、src/util.h、src/util.cpp、src/init.h、src/init.cpp
一、RPC命令行判断
RPC为远程过程调用,其在后台进程中RPC调用方式的参数正确设置形式如下:
bitcoind -daemon //后台运行
bitcoind -stop//停止daemon进程
以下为RPC命令行参数设置正确性判断过程:
// Command-line RPC
bool fCommandLine = false;
for (int i = 1; i < argc; i++)
if (!IsSwitchChar(argv[i][0]) &&!boost::algorithm::istarts_with(argv[i], "bitcoin:"))
fCommandLine= true;
if(fCommandLine)
{
fprintf(stderr, "Error: There is no RPC client functionality inbitcoind anymore. Use the bitcoin-cli utility instead.\n");
exit(EXIT_FAILURE);
}
上述代码对输入的参数逐个判断,首先通过IsSwitchCahr函数(src/util.h)判断参数是否有'-'或'/',并且不包含'bitcoin:',bitcoin:URI是用于转账的,所以应该排除这种情况:bitcoin://1F2EUzKR1XsLRCtEnsnpDQZ13XJgS6P3ZK?amount=0.001&message=donation,如果出现上述情况则在终端中输出错误提示信息,并且退出程序。其显示效果如图所示。

通过其输出信息我们可以知道,对于不含'-'或'/'的参数和bitcoin:URI只能在bitcoin-cli客户端工具中使用,bitcoind中是无法处理的,会导致程序异常退出。
参考文章:http://blog.sina.com.cn/s/blog_14ed0b9990102wp7p.html
二、服务参数设置
服务参数设置代码实现是通过SoftSetBoolArg("-server", true);完成的。其注释如下:
// -server defaults to true for bitcoindbut not for the GUI so do this here
通过该注释我们可以知道bitcoind默认是服务端,其参数-server是true,但是对于GUI(即图形界面程序)则不然,需要显示设置,因此在此处添加该行代码。该函数的实现代码以及其调用的函数均在src/util.cpp中,其代码实现也比较简单,具体如下:
bool SoftSetBoolArg(const std::string&strArg, bool fValue)
{
if (fValue)
return SoftSetArg(strArg, std::string("1"));
else
return SoftSetArg(strArg, std::string("0"));
}
bool SoftSetArg(const std::string&strArg, const std::string& strValue)
{
LOCK(cs_args);
if (mapArgs.count(strArg))
return false;
mapArgs[strArg] = strValue;
return true;
}
其实现思路为:首先判断mapArgs(该参数的解释在第4篇研读分析中)中是否存在server参数,如果存在则无需设置,不存在则根据SoftSetBoolArg传入的fValue进行设置相应值。具体服务参数设置就这么简单,大家只要看了之前的源码研读分析文章,该函数的解读很容易理解。
三、初始化日志

接下来我们将进入日志打印内容基础框架设置部分,在该部分主要对日志打印的内容根据参数进行解析,确定后续运行过程中需打印的信息,其具体实现代码也很简单,具体如下:
Src/init.cpp
//日志打印
void InitLogging()
{
fPrintToConsole = GetBoolArg("-printtoconsole", false);
fLogTimestamps =GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS);
fLogTimeMicros = GetBoolArg("-logtimemicros",DEFAULT_LOGTIMEMICROS);
fLogIPs = GetBoolArg("-logips", DEFAULT_LOGIPS);
LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
LogPrintf("Bitcoin version %s\n", FormatFullVersion());
}
日志文件的默认位置为我们设置的数据目录中,其名称为debug.log,在ubuntu系统中其默认目录位置为~/.bitcoin。

我们接下来逐个分析其参数含义:
(1)printtoconsole
日志信息是否发送跟踪/调试信息到控制台而不是debug.log文件。我们看到其默认为false,即不打印至控制台或终端上,反之则打印。
(2)logtimestamps
该参数的含义为在日志中打印时间戳,该参数的默认值定义为静态常量DEFAULT_LOGTIMESTAMPS,该常量在src/util.h中定义,与该常量一起定义的还有本函数中使用到的另两个常量,这3个常量分别给作为函数中3个参数的默认值,其分别是:
static const bool DEFAULT_LOGTIMEMICROS = false;//按微秒格式打印日志时间
static const bool DEFAULT_LOGIPS= false; //日志打印中包含IP地址
static const bool DEFAULT_LOGTIMESTAMPS = true;//打印日志时间戳
通过名字我们可以很明显看出它们的对应关系。分别为:
Logtimestamps -------> DEFAULT_LOGTIMESTAMPS
fLogTimeMicros -------> DEFAULT_LOGTIMEMICROS
DEFAULT_LOGIPS-------> DEFAULT_LOGIPS
从DEFAULT_LOGTIMESTAMPS的定义可以看出,日志打印中是默认打印时间戳的。
(3)logtimemicros
从DEFAULT_LOGTIMEMICROS的定义可以看出,日志打印中日志时间是按微秒格式打印的。
(4)DEFAULT_LOGIPS
从DEFAULT_LOGIPS的定义可以看出,日志打印中是默认不打印IP地址的。
在ubuntu系统中打开~/.bitcoin下的日志文件debug.log,我们可以看到其具体的日志打印输出内容如图所示。

到此我们完成了AppInit函数中集中处理传入参数的源码,在这个参数解析过程中,我知道了区块链的3个链,那就是第6篇中讲到的私有链、测试链以及公有链;知道了比特币帮助信息输出的代码实现方法;知道了参数存储变量mapArgs与_mapMultiArgs。当然还有很多小的知识点,这里就不一一列举了,相信通过后续的源码研读我将会收获更多,也欢迎更多的朋友一起加入源码研读行动,更多地了解比特币!
作者:区块链研习社比特币源码研读班 菜菜子
以下是广告:
我们区块链研习社已创建“区块链研习社币圈交流”小密圈”,在小密圈中,我们将带领大家一起学习区块链的原理与投资,还将提供区块链基本原理解答、交易所注册与交易操作、ICO交易与操作、投资分析、风险分析等内容。
目前入圈价格初始定价50元,50人调整一次价格,每次调整幅度为50元!
