美文网首页程序员
比特币源码解读十

比特币源码解读十

作者: ttblack | 来源:发表于2017-09-04 08:59 被阅读1758次

这篇我们看init.cpp中的AppInit2中的第八步:Step 8: load wallet 加载钱包。

加载钱包

上面这部分就是加载钱包的核心代码,首先通过判断fDisableWallet变量进行是否加载钱包的判断。这个变量在第三步(step 3参数传入内部标记)中获取的用户参数。

是否使用钱包

在这里我们需要说明一下zapwallettxes指令。这也是用户可选的参数。这个指令的意思是:清除钱包交易数据。我们已经知道一个交易的确认是要收交易手续费的。如果没有手续费或手续费过低。可能会造成这条交易数据在网络中游荡,不会被记录下来。所以我们可以通过清除自己的结点交易,并重新下载整个区块链来查找这条交易数据。所以这是一个供用户自己处理可选项。

我们可以看下钱包类的ZapWalletTx函数:

钱包类的清除交易函数

可以看到这个函数是通过CWalletDB类对象的ZapWalletTx()清除交易的。因为CWalletDB类是对钱包数据进行封装的操作类。而我们的钱包数据就存储在wallet.data中。CwalletDB类是继承自CDB类。CDB是对Berkeley 数据库操作的封装。

Berkeley DB是一个开源的文件数据库,介于关系数据库与内存数据库之间,使用方式与内存数据库类似,它提供的是一系列直接访问数据库的函数,而不是像关系数据库那样需要网络通讯、SQL解析等步骤。

CDB.h定义在db.h中,CWalletDB定义在walletdb.h中。大家可以自己去看下全体的代码。我们这里主要看下ZapWalletTx函数。

清除钱包的交易数据

可以看到此函数调用FindWalletTx函数查找此钱包的交易数据并存储在vTxHash中。最后调用EraseTx函数清除了所有的交易。

下面的代码又重新new 了个CWallet 钱包对象。并通过调用LoadWallet()下载钱包数据。当然LoadWallet最后也是调用的CWalletDB中的LoadWallet函数从数据库中重新加载数据。如果加载失败,则进行了相应的提示。

关于钱包就是我们创建交易的地方,这里存储了我们的密钥,和一些交易数据。这些内容就够我们分析好久的了。这里我们先了解一下。我们接着下面的代码进行分析。

升级钱包

这段代码通过判断用户是否使用upgradewallet命令进行钱包升级,具体逻辑是获取用户使用upgradewallet的版本参数也就是版本号进行判断,如果nMaxVersion为0(也就是没有输入要升级到的版本号,则使用CLIENT_VERSION系统定义的版本号。通过调用SetMinVersion进行升级。最后将当前版本设置为nMaxVersion.关于这个版本号我们有必要了解下。我们先看源码在version.h中。

版本号计算 clientversion.h中版本宏定义

通过源码可以看到CLIENT_VERSION是通过主版本号,次版本号,修订版本号和构建版本号共同构成。

我们接着看下面的代码:

生成钱包种子私钥

我在我的《比特币学习之钱包》中介绍过。比特币钱包是一堆包含私钥的地方。现在的钱包都是确定性钱包。所以需要一个种子私钥来生成后面的很多私钥。现在我们这个RandAddSeedPerfmon()就是生成种子私钥的。我们看下它的生成过程,在util.cpp中

种子私钥生成过程

这段代码是在WINDOWS系统中的生成过程。而且可以发现这个生成过程是很花费时间的。我们了解了种子私钥的过程,现在返回init.cpp中继续下面的代码可以看到pwalletMain钱包对象通过调用GetKeyFromPool从密钥池中得到一个公钥,并设置为默认的公钥,最后通过CPubkey对象的GetID()生成比特币地址并调用SetAddressBook()函数记录下来。我们知道比特币地址是通过哈希算法加密公钥生成的,现在我们看下代码的实现方式

生成比特币地址

可以看到比特币地址是使用Hash160加密算法得到的。这就是比特币地址的生成真面目了。关于理论基础可以看我之前写的《比特币学习之比特币地址》,此方法在key.h中。是我们所有密钥算法的源码实现的地方。Hash160就是我们平常说的双哈希也就是RIPEMD160(SHA256(K))这两个加密算法共同的实现。

我们看加载钱包最后的部分:

扫描钱包数据

第一部分RegisterWallet和我们在《比特币源码解读五》中的方式一样,是signal对象实现的对交易数据的各种侦听处理。具体大家可以自行阅读了。

注册钱包

下面的代码就是对钱包数据进行了一遍扫描处理。调用的具体函数是ScanForWalletTransactions()我们看下这个函数的具体实现,来了解下区块链的数据结构和遍历方式:

扫描钱包数据

通过这段代码我们可以看到所有的区块数据是存储在硬盘中的。而我们的chainActive是存储的区块的位置信息链,通过遍历位置链来获取相应的区块数据及交易数据。

好了。我们第八步的代码也就解析到这里。还是那句话,分析的可能不太准确,但是希望能带领自己和大家进入源码的世界,共同进步。

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

相关文章

  • 比特币源码解读十

    这篇我们看init.cpp中的AppInit2中的第八步:Step 8: load wallet 加载钱包。 上面...

  • 比特币源码研读

    forest21000版 比特币源码研读之一比特币源码研读之二比特币源码研读之三比特币源码研读之四比特币源码研读之...

  • 比特币源码研读之十一

    比特币源码研读系列已经发表了十篇了,通过这十篇源码研读系列让我对比特币源码及比特币运行原理有了进一步的理解,也让我...

  • 开始研读比特币1

    1,进入比特币源码目录,先读读编译doc/build-unix.md,查看比特币源码如何编译,了解比特币的依赖库,...

  • 比特币源码解读八

    现在我们接着看RegisterNodeSignals 的下一个连接函数。 InitializeNode 这个函数在...

  • 比特币源码解读四

    我们接着上篇继续,现在来看第五步。 第五步:verify wallet database integrity 确...

  • 比特币源码解读六

    上篇我们看了ProcessMessages函数,这个函数就是侦听网络中的不同的消息命令来处理相应的逻辑。在...

  • 比特币源码解读三

    这篇我们主要分析下AppInit2的代码,这个函数在init.cpp中。这个函数分了12步完成了初始化客户端的功能...

  • 比特币源码解读二

    上次我们把bitcoind.cpp的大概流程过了一下,我们今天说下细节的内容。我们打开bitcoind.cpp文件...

  • 比特币源码解读一

    上次在ubuntu系统中将比特处源码编译环境设置好了后,还没有具体分析里面的代码,今天我们就解读一下。源码...

网友评论

    本文标题:比特币源码解读十

    本文链接:https://www.haomeiwen.com/subject/sqibdxtx.html