我超级懒的|向罪恶资本主义抗争的共产主义斗士 终于正式开始研究bitcoin源码了。 所谓看源码,根据各位elders的经验来看,最简单的方式就是根据git的记录找到初始版本,然后慢慢向上回溯,也可根据change log 慢慢添加。但是总之,从最原始的版本来学习才是最符合我们这些萌新的。 但是,根据github的git记录来看,最原始的版本并不是 神*中本聪 公布的最原始bitcoin源码。 可以看到在git记录中,最原始的tag是:
版本,初始commit似乎也不是原始版本。 本来根据这个版本也是可以学习的,但是毕竟不正宗(摔),那不正宗的都是邪教#手动滑稽 所以我们就寻找v0.1版本的代码吧。 (加粗/醒目)以下的行为都基于 win10 64bit & Visual Studio 2015 community 并且编译的 bitcoin 源码只编译 x86 的 debug 平台!! vs 2015 提供的是c++11 标准 一、下载 v0.1 版本的源码我v0.1版本的源码是从这个链接来的(需要翻墙) Who has the source code of the first version of Bitcoin (0.1), as released in February 2009? 里面提供了v0.1版本的链接 二、根据readme.txt中的要求配置好依赖库解压压缩包后,可以发现根目录下是一个已经编译好的bitcoin.exe文件,而源码全部在src/目录下。 在src/目录下有一个 readme.txt文件(是 src/readme.txt 不是根目录下的readme.txt),打开可以看到: Dependencies Libraries you need to obtain separately to build:default path download 由此可知,为了编译bitcoin需要先配置好这4个依赖库。 以下就是重点: 1. wxWidgets (3.1.0 版本)我采用的是 wxWidgets - v3.1.0 注意版本号!!! 这是个神坑。如果你和我一样采用v.3.1.0之后,你将会遇到无尽的困难!!! 这个请根据自己情况做出选择,或许采用 v2.8 以下的版本会好很多。我没有去查找2009年时wxWidgets时候的版本。如果为了避免问题,可以尝试选用 2009 年 二月份 之前所 release 的wxWidgets 版本。。。 如果你和我一样选择wxWidgets 3.1.0。。 呃 请做好接下来修改大量代码的准备。。
The simplest way to start working with the library is this(当然我只选择了为win 32 debug 进行编译,没有全部编译) ![]() 选择vs编译没有 unicode 开关
wxWidgets Tips: Compile wxWidgets 3.1.0 using Visual Studio 2015
Compiling wxWidgets with MinGW 2. openssl (1.0.1 版本) (注:似乎1.0.2后会出问题)openssl 要使用源码编译很麻烦。。要安装perl 有一个取巧的地方: 通过这种方法可以不需要编译就安装openssl库。注意,这里一定选择x86(32bit)版本,因为我们只编译32bit的源码。 如果要选择从源码编译,则除了安装perl后,在编译32bit版本的时候还会遇到汇编部分编译不通过的情况。这时候就只能再安装nasm汇编器进行编译(我没试过。。) 详情查阅这个链接 The simplest way to start working with the library is this: 注意!!! 选择这些直接编译好的二进制文件不清楚似乎有些版本有问题,在我使用python直接加载上面的那个链接下载的openssl中的dll后(1.0.2k 或者 1.0.2l),对于bitcoin使用的椭圆曲线会 概率性 的不能通过签名验证这个流程的,暂时不清楚其中的原因。对于这种问题,我采用其他编译的dll,但是这只是为了实验,如果是为了安全还是应该选择自己编译openssl (但是问题似乎在于1.0.2之后的版本会出现问题) 经过验证,在上面这个版本的二进制中,1.0.1g能够通过验证反而1.0.2以后不能通过,不能通过(我只验证了1.0.2 j~l 这几个版本) 3. Berkeley DB (4.8.30 版本)这tm就是个神坑,我后来在这里卡了好久。。。 Berkeley DB 现在归属 oracle (默默吐槽,oracle指染的东西每一个好用。。 这里我强烈建议不要使用最新版本的Berkeley db 进行构建。至少连现阶段的0.13.99版本的bitcoin都使用的是4.8版本的db。使用高版本不仅接口不对,很可能时候连环境都配不好(我瞎说的) 所以这里选择 Berkeley DB v4.8 版本。这里倒是有安装包,直接安装就好了,但是我要强烈黑他一下,因为我并不清楚我是不是个例。直接使用安装包提供的debug版本的 dll 会出问题!!! 在配置章节和下一篇会对这个问题有详细描述。 4. Boost (1.63.0 版本)这个是最简单的 因为Boost完全不需要配置:介绍及下载链接 Nothing to Build? 但只可惜因为c++11的关系,要剔除Boost是最容易的。。。而且在bitcoin源码中几乎没有什么存在感 使用vs的从“源码导入” 导入bitcoin源码这里我们把 src/ 目录当作根目录。 新建立一个目录,比如叫做bitcoin什么的随便好啦。然后把src/目录下的所有文件都拷贝到这个新的目录下。我们现在把这个新的目录当做 / 。之后的描述都针对 / 作为根目录进行。 打开vs
此时就已经新创建了项目,并导入的源码。 三、配置这步是很关键的第一步 现在我们先假设把刚才配置好的4个依赖库都设置成环境变量(如果不设置环境变量也行,那么等会在配置项目的依赖的时候就填写全路径就好了。) 回到桌面->对“此电脑”右键->属性->高级系统设置->环境变量->在系统变量的部分开始创建环境变量 点击新建: 举例: wsWidgets => 那么就在变量名写上 WXWidgetsPath ,然后变量值填写刚才安装(解压)widgets的根目录 其他3个依赖库同理,则总共配置了4个环境变量:
当然上面这4个环境变量的名字是我乱取的,并没有什么约定,你可以根据自己想象取想取的名字。这里取这4个变量等会我们就会在项目的配置中引用这4个变量,自己取的名字等会就换成自己取的就好了。 此时先关闭刚才创建的项目,然后再重新启动(这个是为了让vs加载刚才取的环境变量,如果没配置环境变量用不着重启vs) 在解决方案中右键刚才创建的项目,选择属性。 1. 设置unicode 字符集注意,这步的配置不是必须,如果你的wxWidgets是老版本(似乎是小于2.8?)或者你在编译wxWidgets库的时候选择关闭unicode开关,编译除了非unicode的wxWidgets的库时,可以直接跳过这步,不设置unicode字符集。否则在等会启动编译的时候会出现wxWidgets的setup.h找不到路径。 如果你是vs编译的,那么一定要设置unicode字符集。 在 配置属性-常规 中 找到 项目默认值 - 字符集 点击下拉框,选择 使用 Unicode 字符集 2. 设置VC++依赖在 配置属性-VC++目录 下找到 包含目录 和 库目录,点击 包含目录,填写
(注意这里的WXWidgetsPath就是刚才配置的环境变量,如果没有配置,就直接填写wxWidgets的全路径加上include路径,以下同理) 这样就引入了 wxWidgets 库的 头文件路径 以及 lib 路径。 注:因为wxWidgets库是和windows应用程序绑定的,不是普通的c++依赖库,所以必须在VC++的部分设置,否则,wxWidgets会不能通过编译。 3. 设置C++依赖在 配置属性 - c/c++ - 常规 中 找到 “附加包含目录”,点击编辑,填写:
这样就引入了 boost,openssl, bdb的头文件路径 在 配置属性 - 链接器 -常规 中找到 “附加库目录”,点击编辑,填写:
(加粗|醒目) oracle神坑的地方在这里就体现出来了。$(BDBPath)\lib指代的 bdb 的 libs 的路径,但是!因为我们编译的是 debug 项目,所以等会只能引入 debug 的dll(lib) (如果正常应该是可以引入release的lib的,但是对于bdb来说,debug项目使用release的dll 在运行free()的时候会崩溃。。。)。 但是引入debug后,源安装包中的 debug的dll似乎是有问题的(加粗),会直接引起程序崩溃!!(不清楚我是不是个例。如果出现了这个问题,请重新在自己的电脑上编译debug版本的bdb,把$(BDBPath)\lib换成新的路径,参考下一篇文章) 在 配置属性 - 链接器 -输入 中找到 “附加依赖项”,点击编辑,填写:
然后打开资源管理器(就是点我的电脑。。),找到这个项目的目录,在本项目根目录 / 下创建 libs/ 目录,拷贝 $(OpenSSLPath) 目录下的 libeay32.dll 和 $(BDBPath)\bin\debug 目录下的libdb48d.dll 进入 libs 目录。 注意,刚才描述的问题的dll就是这个 libdb48d.dll, 如果出问题了,很可能需要替换成自己编译的dll 然后回到 VS 的项目配置中 在 配置属性 - 生成事件 - 后期生成事件 中找到 “命令行” 填写上:
这个command的 libs 就是 刚才在项目的根目录下创建的 libs/ 目录。所以这句话的意思就是 把 libs/ 目录下的所有 dll 都拷贝到输出目录中(这里指代的就是 Debug 目录) 四、修改源码错误1. headers.h vc6++ 与 vc9以上平台冲突 因为源码应该是在vc6++的平台下编译完成的,所有首先要先移除对于winnt的预定义,否则会产生兼容性问题。 找到headers.h文件,在第10行发现:
将这4行全部都注释掉,或者删除。 windows.h 与 winsokc2.h 顺序 找到headers.h文件第23行发现:
移动windows.h得到
或者引入一个宏也可以解决windows.h头文件引入的问题:
之后找到 net.cpp 文件,第5行交换头文件引入
2. c++11 与现存代码冲突 net.h/net.c boost::array 与 c++11 的 std::array 冲突 找到 net.h 文件,在第419行发现
找到 net.c 文件,第26行进行同样更改
winsock.h 的 bind 函数 与 std::bind 冲突 找到 net.c 文件, 第937行
3. serialize.h insert函数 const char*想要强制转换为const_iterator 找到serialize.h 文件,在第 808 行发现一个根据宏的定义
修改为
4. 似乎是关于MSVC8 allocator的兼容问题(不确定) 文件serialize.h 第699行
同时因为 vector_type的typedef已经等同于vector<char>,所以对于CDataStream类的构造函数也要更改 文件 serialize.h第741行, 删除或着注释掉这个构造函数
文件key.h 第40行
5. unicode 字符的替换 ps: 若使用低版本的wxwidgets,总之就是没有开启unicode宏的话不需要替换 util.cpp文件的第74行
第173行
第272行
util.h 文件的第274行
6. ui.cpp / ui.h 错误 ui.cpp 第254行,关于wsString的迭代器填充构造函数无法自动转化的问题 (或许当 wxWidgets版本低的时候不会出现这个问题)
类似的 第2650, wsString 到 std::string的转换
ui.cpp 第1245行,字符缺少引号 ps: 强调!这里缺少引号,是因为本来源码中这里是个十分奇怪的字符,在导入vs后打开的时候就被转义了。所以这里的?实际上是代表原来的一个字符。但是这个函数并没什么鸟用,所以这里随便改正就好,不用还原原来的意思。
2890行,宽字符
2913行,同上
3148行,对于3.0以上的wxWidgets版本来说 AddPendingEvent()函数已废弃,需要依靠eventhandler才能调用。
7. 去除因跨平台带来的兼容问题 文件util.h 第161行
8. berkeley db 版本为6.2+后的修改兼容 (使用4.7或4.8版本则无需考虑) 文件db.cpp 第18行
警告源码中出现的警告多半是因为符号隐式转换的问题,这个根据自己需要修改就行。 六、运行以上的部分只是解决在编译期出现的问题,真正的大头是需要让bitcoin能够运行起来(惨····) |
|