美文网首页区块链虚拟币开发
比特币源码研读之二C++预备知识

比特币源码研读之二C++预备知识

作者: 韬声依旧在路上 | 来源:发表于2018-05-07 12:30 被阅读283次

本文由【区块链研习社】优质内容计划支持,更多关于区块链的深度好文,请点击【区块链研习社

本文作者:区块链研习比特币源码研读班 韬声依旧在路上

从读经典开始 - 图片来自网络

在正式为大家分享比特币源码研读之前,请允许我为大家介绍一下研读源码之前的最少C++预备知识,当然如果你对这些知识很熟悉的话,那么你可以忽略这篇文章,也可以继续关注我的文章。

编程步骤

  • 源代码
  • 编译器
  • 目标代码
  • 链接程序
    • 启动代码
    • 库代码
  • 可执行代码

宏定义

#define命令是C语言中的一个宏定义命令,它用来将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本。比如在种子生成文件bitcoin/src/random.h 中可以看到如下代码

#ifndef BITCOIN_RANDOM_H
#define BITCOIN_RANDOM_H

#include <crypto/chacha20.h>
#include <crypto/common.h>
#include <uint256.h>
** 省略部分代码 */
#endif // BITCOIN_RANDOM_H

从上面的代码可以看到宏定义的写法,比如#ifndef#define的使用,也就是说C++在编译期间就知道了程序引用了哪些库和函数。

简单的宏定义

#define <宏名> <字符串>

带参数的宏定义

#define <宏名> (<参数表>) <宏体>

一个标识符被宏定义后,该标识符便是一个宏名。这时,在程序中出现的是宏名,在该程序被编译前,先将宏名用被定义的字符串替换,这称为宏替换,替换后才进行编译,宏替换是简单的替换。

文件包含

文件包含格式如下:

#include <库名称>
#include "库名称"

第一种的写法是指从函数库从引入相关函数,而第二种写法一般用于引入自定义的函数。

类的声明

比如种子生成的bitcoin/src/random.h文件中FastRandomContext类的声明如下:

class FastRandomContext {
private:
    bool requires_seed;
    ChaCha20 rng;

    unsigned char bytebuf[64];
    int bytebuf_size;

    uint64_t bitbuf;
    int bitbuf_size;

    void RandomSeed();

    void FillByteBuffer()
    {
        if (requires_seed) {
            RandomSeed();
        }
        rng.Output(bytebuf, sizeof(bytebuf));
        bytebuf_size = sizeof(bytebuf);
    }

    void FillBitBuffer()
    {
        bitbuf = rand64();
        bitbuf_size = 64;
    }

public:
    explicit FastRandomContext(bool fDeterministic = false);

    /** Initialize with explicit seed (only for testing) */
    explicit FastRandomContext(const uint256& seed);

    /** Generate a random 64-bit integer. */
    uint64_t rand64()
    {
        if (bytebuf_size < 8) FillByteBuffer();
        uint64_t ret = ReadLE64(bytebuf + 64 - bytebuf_size);
        bytebuf_size -= 8;
        return ret;
    }

    /** Generate a random (bits)-bit integer. */
    uint64_t randbits(int bits) {
        if (bits == 0) {
            return 0;
        } else if (bits > 32) {
            return rand64() >> (64 - bits);
        } else {
            if (bitbuf_size < bits) FillBitBuffer();
            uint64_t ret = bitbuf & (~(uint64_t)0 >> (64 - bits));
            bitbuf >>= bits;
            bitbuf_size -= bits;
            return ret;
        }
    }

    /** Generate a random integer in the range [0..range). */
    uint64_t randrange(uint64_t range)
    {
        --range;
        int bits = CountBits(range);
        while (true) {
            uint64_t ret = randbits(bits);
            if (ret <= range) return ret;
        }
    }

    /** Generate random bytes. */
    std::vector<unsigned char> randbytes(size_t len);

    /** Generate a random 32-bit integer. */
    uint32_t rand32() { return randbits(32); }

    /** generate a random uint256. */
    uint256 rand256();

    /** Generate a random boolean. */
    bool randbool() { return randbits(1); }
};

这个类中使用private关键字声明了布尔类型的种子导入、ChaCha20类型的rng变量,也有填充字节缓冲的方法,也有使用public关键字的std::vector<unsigned char> randbytes(size_t len);方法,当然也少不了explicit关键字声明的构造方法。

第三方库的使用

使用方法

bitcoin/src/httprpc.cpp文件中我们看到使用了boost库,那么具体的写法可以参考如下代码。

#include <boost/algorithm/string.hpp> // boost::trim
static bool RPCAuthorized(const std::string& strAuth, std::string& strAuthUsernameOut)
{
    if (strRPCUserColonPass.empty()) // Belt-and-suspenders measure if InitRPCAuthentication was not called
        return false;
    if (strAuth.substr(0, 6) != "Basic ")
        return false;
    std::string strUserPass64 = strAuth.substr(6);
    boost::trim(strUserPass64);
    std::string strUserPass = DecodeBase64(strUserPass64);

    if (strUserPass.find(':') != std::string::npos)
        strAuthUsernameOut = strUserPass.substr(0, strUserPass.find(':'));

    //Check if authorized under single-user field
    if (TimingResistantEqual(strUserPass, strRPCUserColonPass)) {
        return true;
    }
    return multiUserAuthorized(strUserPass);
}

使用步骤

  • 引入库声明 - 使用#include指令
  • 调用库 - 使用库名称::方法名(参数列表)

总结

当然这些预备知识不足以应对比特币源码研读的需要,但是随着C++基础知识的不断强化和深入理解,我相信我会深刻了解C++作为比特币开发的基础语言的重要性和特殊地位,正是由于这些优秀的语言特性才使得比特币诞生这么多年以来没有出现过大的系统漏洞和安全事故,我也相信凭借互联网技术的不断发展,也会出现更多类型的编程语言来不断冲击C++的地位,我也知道C++不是一朝一夕就能学会的,我有耐心,我也希望和大家一起探索C++语言的奥秘,为接下来的源码研读注入更多的信心和力量。

相关文章

  • 比特币源码研读

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

  • 比特币源码研读之二C++预备知识

    本文由【区块链研习社】优质内容计划支持,更多关于区块链的深度好文,请点击【区块链研习社】 本文作者:区块链研习比特...

  • 比特币源码研读之十一

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

  • 比特币源码研读之一

    比特币源码研读之一——区块链研习社 《比特币源码研读班》 一看文件夹结构 和 github编译依赖,分析的依赖库 ...

  • 比特币源码研读之一

    作者:区块链研习比特币源码研读班 菜菜子 一、源码下载 本文比特币源码下载地址为:https://github.c...

  • 比特币源码研读之二十

    今天是2017年12月31日,即2017年的最后一天了,本应好好总结,对今年做个总结的,但想着自己身为源码研读班班...

  • 比特币源码研读之二

    区块链研习社比特币源码研读班今天研读第二,第三流程,SetupEnvironment和noui_connect函数...

  • 比特币源码研读之二

    上一篇文章我们大致分析了一下比特币源码src文件夹的目录结构以及数据目录结构,接下来我们将进入源码的分析。本篇涉及...

  • 比特币源码研读之二

    前一篇文章中已经完成了main函数运行过程的梳理,并且也绘制了其运行流程图,为了更清晰地记录每个过程的详细执行内容...

  • 01:比特币源码编译|比特币源码研读

    2018年8月报名了区块链研习社的「比特币源码研读班」(5期)。首先要准备比特币源码的编译,因为对这块几乎是小白水...

网友评论

    本文标题:比特币源码研读之二C++预备知识

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