主页 > token.im > 如何接入比特币网络及其原理解析——从零开始学习区块链技术(二)

如何接入比特币网络及其原理解析——从零开始学习区块链技术(二)

token.im 2023-11-24 05:10:59

1、如何连接比特币网络?

实际上,连接比特币网络非常简单。我说你千万不要相信,启动比特币客户端吧:

在命令行终端输入启动命令:./src/bitcoind -testnet

输入后会有一个与网络同步数据的过程,你会看到:

数据同步

数据同步

这个过程需要一段时间。数据同步完成后,连接到比特币网络。

2、启动过程鸟瞰

虽然单条命令就可以搞定,但代码操作背后的逻辑并不简单~

来,我给你分析一下

当你在命令行终端输入启动命令:./src/bitcoind -testnet,操作系统会在这个文件中找到main函数并启动比特币客户端。 .

对于所有 C++ 代码,整个程序都是从主函数执行的。 bitcoind的main函数位于src/bitcoind.cpp,main函数在代码末尾。

比特币技术原理

main函数本身并没有很多东西,主要是调用3个函数来执行,它们的主要作用是设置环境变量,设置信号处理和启动系统。

具体代码如下:

int main(int argc, char* argv[])
{
    SetupEnvironment();
    // Connect bitcoind signal handlers
    noui_connect();
    return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);
}

这段代码简述如下:

SetupEnvironment 函数,主要用于设置系统环境变量,包括:malloc 内存分配行为、Locale、文件路径的locale 设置等。 noui_connect 函数,设置连接到 bitcoind 的信号的处理。 AppInit 函数来启动系统。

让我们关注AppInit函数的执行

调用 SetupServerArgs 函数来设置系统可接受的所有命令行参数。然后开始解析命令行传递的各种参数。

系统执行中的一个重要步骤是设置可以接收的参数,并解析用户在启动时传递的各种参数。 SetupServerArgs 函数就是为了完成这个目的。我们来看看这个函数的执行流程。

如果是测试网络,则生成一个 CTestNetParams 对象进行初始化。 (用于开发完成后的测试。)

如果是回归测试网络,会生成一个CRegTestParams对象进行初始化。 (用于开发期间的连接使用。)

比特币技术原理

对于这两个测试网络,处理与主网络基本相同,只是一些参数不同。

上面提到的三个对象CMainParams CTestNetParams CRegTestParams的定义都在chainparams.cpp文件中。有兴趣的同学可以进一步探索源码。

接下来比特币技术原理,设置系统可以接收的所有参数。

部分参数解释如下:

以上是一些常用的参数,会影响Bitcoin Core的命令。应用程序开发人员更关心 RPC 相关的设置。通过 RPC 接口,我们调用 Bitcoin Core 提供的各种服务。这些命令通常在配置文件中设置,不需要在命令行中指定。

接下来,检查用户指定的命令参数是否正确。

 if (!gArgs.ParseParameters(argc, argv, error)) {
     fprintf(stderr, "Error parsing command line arguments: %s\n", error.c_str());
     return false;
 }

如果传递了帮助和版本参数,则显示帮助或版本信息并退出。

检查数据目录(可选或默认)是否存在。如果不是,则打印错误消息并退出。

 if (!fs::is_directory(GetDataDir(false)))
 {
     fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str());
     return false;
 }

比特币技术原理

GetDataDir方法中,根据用户是否在命令行中提供datadir参数来确定默认数据目录还是用户指定数据目录。

读取并解析配置文件,检查指定的数据目录是否存在。如果任何步骤失败,打印错误消息并退出。

 if (!gArgs.ReadConfigFiles(error, true)) {
     fprintf(stderr, "Error reading configuration file: %s\n", error.c_str());
     return false;
 }

ReadConfigFiles方法的具体处理如下:

调用SelectParams(gArgs.GetChainName())函数生成一个全局区块链参数,并设置系统的网络类型。如果有错误,打印错误,然后退出。

gArgs.GetChainName() 方法返回当前使用的网络。对于主网络,返回字符串 main;对于测试网络,返回字符串 test;对于回归测试网络,返回字符串 regtest。

SelectParams 方法的实现如下:

void SelectParams(const std::string& network)
{
   SelectBaseParams(network);
   globalChainParams = CreateChainParams(network);
}

SelectBaseParams 方法会根据指定的网络参数生成一个CBaseChainParams 对象并保存在globalChainBaseParams 变量中,并将网络类型(m_network 属性)存储在指定的gArgs 对象中。 CBaseChainParams 对象只保存了系统的数据目录和运行的端口,所以称为区块链基础参数对象。

CreateChainParams方法会根据不同的网络参数生成CChainParams类的子对象,可能是以下三种:CMainParams、CTestNetParams、CRegTestParams。 CChainParams 对象包含了区块链对象的所有重要信息,例如:共识规则、部署状态、检查点、创世块等。

比特币技术原理

检查所有命令行参数,如果有错误则打印错误,然后退出。

默认设置参数-server为true。

bitcoind 守护进程默认 server 为 true。

调用InitLogging函数初始化系统使用的日志,打印系统的版本信息。

具体代码如下比特币技术原理,根据是否指定debuglogfile、printtoconsole等来判断日志是打印到文件还是控制台。

void InitLogging()
{
   g_logger->m_print_to_file = !gArgs.IsArgNegated("-debuglogfile");
   g_logger->m_file_path = AbsPathForConfigVal(gArgs.GetArg("-debuglogfile", DEFAULT_DEBUGLOGFILE));
   LogPrintf("\n\n\n\n\n");
   g_logger->m_print_to_console = gArgs.GetBoolArg("-printtoconsole", !gArgs.GetBoolArg("-daemon", false));
   g_logger->m_log_timestamps = gArgs.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS);
   g_logger->m_log_time_micros = gArgs.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS);
   fLogIPs = gArgs.GetBoolArg("-logips", DEFAULT_LOGIPS);
   std::string version_string = FormatFullVersion();
   LogPrintf(PACKAGE_NAME " version %s\n", version_string);
}

调用InitParameterInteraction函数,根据参数之间的关系检查所有的交互参数。

调用 AppInitBasicSetup 函数进行基本设置。如果有错误,打印错误,然后退出。

经过长时间的检查和设置,我终于开始应用基本设置了。详情见第二部分。

调用AppInitSanityChecks函数处理底层加密函数的内容。

比特币技术原理

具体解释见第二部分。

调用AppInitLockDataDirectory函数检查并锁定数据目录。

具体解释见第二部分。

调用AppInitMain函数,比特币的主要启动过程。

具体解释见第二部分。

如果应用初始化main函数出错,调用Interrupt函数终止,否则调用WaitForShutdown函数等待系统结束。

WaitForShutdown 函数是一个无限循环函数。

我是欧小白,区块链开发者,区块链技术爱好者,深入研究比特币、以太坊、EOS Dash、Rsk、Java、Nodejs、PHP、Python、C++ Ulord全球社区联盟(优德)核心开发者社区)。

希望能聚集更多的区块链开发者一起学习,共同进步。

敬请期待下一篇:访问比特币网络的关键步骤、创建比特币钱包、重要的rpc指令

如果您在学习过程中遇到任何问题,如果您想了解更多,请补充

QQ群:253968045