区块链源码学习笔记1 - 前期知识库准备

学历区块链整整一年还没有看过比特币源码,我也是很惭愧,刚开始学的时候网上资源还很少,现在再搜索发现各种资料和学习视频已经琳琅满目。搜索过程中发现一位良心作者写了一系列超详细的学习源码的教程。决定跟着这位大神细细探索比特币源码中的奥妙,所以写下这几篇学习笔记,基本参考下面这位博主的教程。不同的是,很多实验我可能都是在Mac OS上做的测试。

地址:比特币源码解析教程,传送门

学习笔记步骤

  • Step1:看源码前补充基础知识库。
    • Boost:C++库
    • OpenSSL:安全套接字层库
    • Libevent:网络编程库
    • QT:GUI库
  • Step2:了解核心数据结构
    • 交易 CTransaction
    • 区块 CBlock
    • 交易池 CTxMemPool
    • 共识 Consensus
    • 脚本 CScript
  • Step3:分析可执行程序的代码(编译后7个可执行程序)
    • bench_bitcoin
    • bitcoin-cli
    • bitcoind
    • bitcoin-qt
    • bitcoin-tx
    • test_bitcoin
    • test_bitcoin-qt

1. Boost库

  • Boost是一套开放源代码、高度可移植的C++库,并且是除了STL外最常用的库,实现了很多基本操作,涉及数值计算、泛型编程、元编程、平台API,能让开发变得更加简单快捷。

1.1 Boost 安装 in Mac

  • 安装Homebrew,如果没有安装的话,直接看官网,一行命令就搞定安装。安装好之后可以用brew help检查是否安装完成。
  • 安装boost。任何在Mac上需要安装的库都可以先试试brew install ***来试一试。安装命令brew install boost

1.2 Boost中与比特币源码相关的库

  • Signals2、Bind、Thread、Chrono、Test、Program option

1.2.1 Signals2

  • 是什么
    • Signals2是基于Boost的另一个signals库,实现了线程安全的观察者模式。在Signals2中,所谓的观察者模式被称为信号/插槽(signals and slots)
    • 说白了,它是一种函数回调机制,定义signal类型数据,把执行代码放在单独放在函数中,美其名曰slot,一个signal可以关联多个slot,当signal发出的时候,所有关联他的slot都会被调用。
  • 为什么学
    • 比特币中涉及Qt编程,而Signals/slots机制是Qt编程的核心机制,要读懂Qt编程就必须对Signals/slots有所了解
  • 优点
    • 降低耦合性。Signals/slots 可以让各个对象只管处理自己的事情。响应事件和处理事件区分开来,使得对象的职责更加明确,减少了代码的耦合。
    • 打个比方,按钮事件 vs 按下后的处理函数,可以分开来写,而不用写在同一个函数里。按钮事件只负责通知,不负责处理。处理函数只负责处理,不负责通知。
    • UI使用这种设计的话,可以在更换响应代码的时候完全不用改UI层的代码。反之亦然。
  • 例程
// example1-signals2.cpp
#include <iostream>
#include "boost/signals2.hpp"
using namespace std;

void slot1(){
  cout << "solt1 call" << endl;
}

void slot2(){
  cout << "solt2 call" << endl;
}

int main(){
  boost::signals2::signal<void()> sig;  // 定义信号
  sig.connect(&slot1);  // 信号关联插槽,按顺序关联也会按顺序执行
  sig.connect(&slot2);
  sig();  // 出发信号
  return 0;
}

/*
Mac下安装完boost后,执行代码 g++ example1-signals2.cpp
编译后执行 ./a.out
打印结果
slot1 call
slot2 call
*/
  • 还有一个难度系数很低的复杂例程可以帮助进一步理解:模拟日常生活场景
  • 有一篇教程帖子可以加深理解对信号与插槽以及他们之间的联系。

1.2.2 Bind

  • 这个还是比较常见的,可以简单理解为下面这样,就是绑定函数和参数。灵活调用函数
cout << boost::bind(f, x, y)() << endl; //等价于 cout << f(x, y) << endl;
  • 其中占位符_1到_9的功能很强大,看两行代码就可以理解了
cout << boost::bind(f, _1, _2, _3)(x, y, z) << endl;  //等价于  cout << f(x, y, z) << endl;
cout << boost::bind(f, y, _3, _2)(x, y, z) << endl;  //等价于  cout << f(y, z, y) << endl;
  • 有篇博客对于boost::bind的使用和原理讲述的很全面,例程也丰富。包括绑定普通函数、成员函数、成员变量、函数对象、ref库,以及嵌套绑定(实现类似f(g(x))的形式,最好不要超过两层嵌套)。
  • 另一篇博客给出了boost::bind四种经典应用场景的例子。

1.2.3 Thread

  • 线程,跟操作系统相关了
  • 一般都会涉及多线程,而多线程中最经典的问题就是同步访问共享资源
  • boost和其他语言一样提供互斥锁来解决,特别的是boost还提供了互斥类。
  • 和Bitcoin源码的关系是,bitcoin core中多线程处理rpc请求的代码中有很多涉及Thread库,详见这篇博客

1.2.4 Chrono

  • Chrono是Boost库中用于时间处理的库,主要包含三个概念时间段(duration),时间点(time_point)和时钟(clock)。
// durations 表示一段时间间隔
typedef boost::chrono::hours hours;
typedef boost::chrono::minutes minutes;
typedef boost::chrono::seconds seconds;
typedef boost::chrono::milliseconds milliseconds;
typedef boost::chrono::microseconds microseconds;
typedef boost::chrono::nanoseconds nanoseconds;

// clock 表示当前时间,是在不断的变化
typedef boost::chrono::system_clock system_clock;
typedef boost::chrono::steady_clock steady_clock;
typedef boost::chrono::high_resolution_clock high_resolution_clock;

// time point 表示某一个具体的时间点
typedef system_clock::time_point sys_tp;

1.2.5 Test

  • 用来给代码做单元测试,白盒测试。
  • 实际过程:给定输入,得到输出,判断是否和预期的输出相同
BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
  • 依照教程动手试一下代码就能很容易的理解用法

1.2.6 Program_options

  • 用来处理那些,带参数的命令。 cmd -option
  • 编写命令行程序的时候,经常会碰到一个问题,有一些带参数的命令比较难解析参数。而boost::program_options模块就是用来处理命令行传入的参数,统一放到一个数组中方便处理。
  • 可以看这篇博客对这个模块的图文理解。

1.3 OpenSSL

  • OpenSSL 是一个安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。
  • 是一个开源项目,主要包括三个组件
    • openssl:多用途的命令行工具
    • libcryto:加密算法库
    • libssl:加密模块应用库
  • 功能:OpenSSL可以实现:秘钥证书管理、对称秘钥和非对称秘钥。直接调用库函数即可。
  • 详细用法参考这篇博客,主要包括:
    • 对称加密openssl enc
    • 单向加密openssl dgst
    • 生成密码openssl passwd
    • 生成随机数openssl rand
    • 生成秘钥对openssl genrsa
    • 创建CA和申请证书
      • 创建自签证书
      • 颁发证书
      • 吊销证书

1.4 libevent

  • 一个轻量级的开源的高性能的事件触发网络库
  • 支持多种I/O多路复用技术(epoll、poll、dev/poll、select和kqueue)
  • 用途
    • 事件通知:当文件描述符可读可写时将执行回调函数。
    • Io缓存:缓存事件提供了输入输出缓存,能自动的读入和写入,用户不必直接操作io。
    • 定时器:libevent提供了定时器的机制,能够在一定的时间间隔之后调用回调函数。
    • 信号:触发信号,执行回调。
    • 异步的dns解析:libevent提供了异步解析dns服务器的dns解析函数集。
    • 事件驱动的http服务器:libevent提供了一个简单的,可集成到应用程序中的HTTP服务器。
    • RPC客户端服务器框架:libevent为创建RPC服务器和客户端创建了一个RPC框架,能自动的封装和解封数据结构。
  • 详细说明和例程可以看这篇博客

1.5 Qt

  • Qt更多的是作为一个GUI库为大家所知,但是其实它是一个著名的C++应用程序框架,十分庞大,而不仅仅有GUI组件。内置了STL、XML解析、数据库连接、访问网络等等的各种第三方库。
  • 比特币源码中,QT是用来编写钱包的图形界面。
  • 一篇很全面也很丰富的Qt介绍教程,作者用了四年的时间编写的,令人敬佩。

以上就是Bitcoin源码阅读前需要了解的技术基础,不需要深究,知道怎么用,有什么样的表现形式即可,后面阅读源码的时候可以返回来,知道再哪里查看。

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

推荐阅读更多精彩内容