VC编译调试比特币源码

当前位置:首页 > 币圈百科 > VC编译调试比特币源码

VC编译调试比特币源码

2022-12-18币圈百科311

目录

前言

第一节依赖库

OpenSSL库Boost库Berkeley DB库Qtqtqtqt VC插件库Protobuf

第二节创建VC项目

第三节添加代码文件

第四节设置项目属性

比特币工程bitcoin-qt,bit coin-Qt-test Engineering test _ bit coin[X]第六节调试建议

前言[X] [X]作为一个不擅长Linux开发的VC程序员我们得想办法用VC编译调试比特币源代码,除非你能花大量的时间和精力研究Linux开发(目前Linux开发

通过最近的努力,所有程序都编译成功,可以运行,但是同步块有问题,但是其他功能可以正常使用。 由于我的精力有限,剩下的问题以后再处理。如果会用VC调试BTC源代码的朋友知道问题,也请注明。

半小时后同步块不再同步。重启程序重建数据库索引后可以继续同步,耗时太长,后续的比特币收发无法调试。

编译、调试、修改比特币源代码是熟悉比特币源代码的好机会。如果能找到bug并提交给github,也是对比特币的贡献。

项目完成了,但是太大太依赖了。有些细节还需要整理,需要一段时间来分享。以“授人以鱼不如授人以渔”为目标,先发布文档,再共享项目。如果你和我一样,也是一个不擅长Linux开发的VC程序员,可以参考这个文档,用VC编译调试比特币源代码。

如果你对这个话题感兴趣,可以直接看你感兴趣的部分。我会说明哪些项目需要做这些操作,不在乎的可以跳过。比如你只关心比特币程序,就不需要看比特币-qt和相关测试程序。

这样做让我当了n次领导,感谢申屠的鼓励和支持,也感谢众多QQ、微博网友和laanwj。

首先说明一下我的电脑环境:Windows 8.1企业版64位,VC 2008 SP,VC 2010 SP1。

我于2014年5月8日18: 00在MAC上拿到了带有git的比特币源代码。如果您使用最新版本的BTC源代码,修改可能会有所不同。

我觉得我啰嗦,但是我怕我说不清楚!

第一节依赖库

用于下载和编译比特币源代码的依赖库。

比特币源代码依赖库包括OpenSSL、Berkeley DB、Boost、miniupnpc、QT等第三方依赖库。

特别说明:

只有在工程属性中添加了USE_UPNP的宏定义,才会启用库miniupnpc。我没有用miniupnpc库,后面会添加。snappy库包含在库LevelDB中,还需要定义一个SNAPPY宏才能启用。我没有启用snappy,后面会添加。

1。库OpenSSL

OpenSSL的编译依赖于Perl。首先,下载并安装Perl。下载地址是http://www.activestate.com/activeperl/downloads.你可以下载x86和x64版本。

下载库OpenSSL,下载地址:http://www.openssl.org/source/,下载openssl-1.0.1c.tar.gz文件,下载后解压。

打开VC2010的命令行窗口,参考安装中的说明。W32文件在openssl-1.0.1c目录下进行编译,并输入以下命令进行编译:

perl configure VC-win 32 no-ASM-prefix=c:/openssl ms \ do _ MSN make-f ms \ ntdll . maktestnmake-f ms \ ntdll . makinstall

编译完成后,在每个项目中添加OpenSSL的目录。头文件的路径是:c:\openssl\include,lib的路径是:c:\openssl\lib,lib库的名称是:Libay。

2。库Boost

下载地址:http://sourceforge.net/projects/boost/files/boost/1.50.0/.下载文件boost_1_50_0.zip并解压。

在VC2010的命令行窗口编译boost_1_50_0,输入以下命令:

bootstrap。\b2

编译完成后,在每个项目中添加Boost的目录。头文件的路径是:\boost_1_50_0,lib的路径是:\boost_1。

3。库Berkeley DB

下载地址:3358 www . Oracle . com/technetwork/database/database-technologies/Berkeley DB/downloads/index-082944 . html,下载文件db-4.8.30.NC.zip

用VC2008打开\db-4.8.30.NC\buildwindows目录下的Berkeley DB.sln,从VC2005项目转换到VC2008项目,然后生成解决方案。

编译完成后,在每个项目中添加Berkeley DB相关目录。头文件的路径是:build_windows,lib路径为:\ d b-4 . 8 . 30 . NC \ build _ windows \ win32 \ debug,lib库为libdb48d.lib,DLL库为libdb48d.lib,比特币的程序运行时需要libdb48d.lib,所以复制到比特币的程序的同一个目录下。

注:VC2010调用VC2008编译的库,不确定行不行。

4。库QT

这是比特币-qt和比特币-qt-test需要的蓑衣网小编2022。不在乎的可以跳过。

下载地址:http://download.qt-project.org/archive/qt/5.2/5.2.0/.

下载文件:Qt-windows-open source-5 . 2 . 0-msvc 2010 _ opengl-x86-offline.exe。

下载后安装。

QT项目的程序执行需要QT的DLL库,路径为:\Qt\Qt5.2.0\5.2.0\msvc2010\bin。将所需的DLL库复制到可执行程序的目录中。

5。QT的VC插件

这是比特币-qt和比特币-qt-test需要的,不在乎的可以跳过。

下载地址:http://download.qt-project.org/official _ releases/vsaddin/qt-vs-addin-1 . 2 . 3-open source . exe

蓑衣网小编2022

下载安装后,在VC2010中的菜单中增加了“QT5”,在“QT选项”中增加了Qt版本和路径。比如:

6,library Protobuf

这也是比特币-qt和比特币-qt-test需要的,不介意的可以跳过。

下载地址:http://code.google.com/p/protobuf/,下载文件:protobuf-2.5.0.tar.bz2,用VC2010打开,从VC2005项目转换到VC2010项目,编译两次。第一次编译后,有些项目失败,就重新编译一次(不需要重新编译)。adfa

Protobuf库用于生成相应的。h和。paymentrequest.proto文件中的cc文件。

编译完成后,在与QT相关的Bitcoin-QT和bitcoin-qt-Test项目中添加Protobuf的相关目录。头文件路径为:\protobuf-2.5.0\src,lib路径为:\ proto buf-2 . 5 . 0 \ vs projects \ debug。

第二节创建VC项目

分析比特币的源代码,归纳为三个程序和两个测试程序。这三个程序对应于BTC钱包中的三个程序。分别是:

比特币-ClibitCoin-QT,QT钱包。比特币-qt-test,qt钱包测试程序。Test_bitcoin,比特币核心单元测试程序。

VC中的工程结构如下图所示:

为了保持BTC的文件目录结构,Bitcoin.sln、bitcoin-cli.vcxproj和bitcoind.vcxproj在src目录,bitcoin-qt.vcxproj在src\qt目录。Bitcoin-qt-test.vcxproj位于src\qt est目录,test_bitcoin.vcxproj位于src est目录。

描述:

比特币-cli、比特币和test_bitcoin都是控制台类型。比特币-qt是qt的应用类型,依赖于QT的QT Core、QtGui、QtNetwork和QtWidgets。Coin-QT-test是QT控制台应用类型,依赖于QT的QtCore、QtGui、QtNetwork、QtWidgets和QtTest。

第三节添加代码文件

23现在开始给各个项目添加相关的代码文件。

因为src目录下的文件在所有项目中都要用到,所以先在bitcoin-cli项目中新建一个文件夹(在资源管理器中新建一个过滤器),为每个项目添加一个公共文件夹,然后复制到其他项目中。目录结构如下:

注意:

头文件和源文件只包含src目录下的代码文件,不包含子目录下的代码文件,bitcoind.cpp、bitcoin-cli.cpp和资源文件不包含在内。Common包含src\json目录中的文件。Common包含src\leveldb下的目录和文件,但不包含xxx_test格式的文件和\leveldb\port\portposix.cc文件。

在比特币-cli项目中添加比特币-cli.cpp和资源文件比特币-cli-res.rc。项目的结构如下:

在比特币项目中添加bitcoind.cpp和资源文件bitcoind-res.rc。项目结构如下:333

在test_bitcoin项目中src est目录下添加代码文件,data包含src est\data目录下的文件。 结构如下:

31在比特币-qt中添加src\qt中的目录和文件。不包含测试目录中的文件。结构如下:

Forms包含src\qt\forms下的文件,locale包含src\qt\locale下的文件,res包含src\qt\res下的目录和文件,资源文件包含bitcoin.qrc 322

The。h和。Proto下的cc文件由工具Protobuf生成,后面会介绍。

在比特币-qt-test项目的src\qt est目录下添加文件。添加比特币-qt的代码文件。项目的结构如下:

33333

第四节设置项目属性

设置项目属性,除了设置前面介绍的依赖库和lib库的相关路径,还有一些特殊的设置,这里特别介绍。4

1、比特币-cli、比特币、test _比特币项目的字符集由UNICODE改为多字符集。

2。为所有项目设置与leveldb相关的头文件路径,包括三个,分别是:

\ Level DB \ Level DB \ Include \ Level DB \ Helpers \ memenv

3。为项目添加预处理定义:

预处理定义由所有项目定义,single

5先说所有项目都需要一个众所周知的预处理定义:

_WIN32_WINDOWS:代码需要定义_WIN32_WINNT或_WIN32_WINDOWS,我定义了_WIN32_WINDOWS。HAVE_WORKING_BOOST_SLEEP:在src目录下util.h文件的MilliSleep函数中,根据宏定义调用不同的BOOST函数。不知道要调用哪个BOOST函数,就随便选了HAVE_WORKING_BOOST_SLEEP。这个定义决定调用boost:this_thread:sleep函数。Level DB _ Platform _ windows:Level DB编译支持Windows平台。OS _ win:level db所必需的,包括windows相关的头文件。ENABLE_WALLET:表示钱包是否启用,因为代码不完善。不要取消ENABLE_WALLET的定义并添加参数“-disablewallet”来禁用WALLET。如果取消ENABLE_WALLET的定义,编译将会失败。_CRT_SECURE_NO_WARNINGS:大家都懂,去掉警告就行了,可以省去。Bitcoin-qt和bitcoin-qt-test项目定义为WIN32_LEAN_AND_MEAN,很多winsock错误的编译和报告都没有超时。

4。为所有项目添加链接库lib库:Shlwapi.lib

Section 5。代码

一个一个修改,但是改动很小。

1。工程比特币-cli,比特币

(1)编译发布版文件main.cpp时报错“没有断言无法编译比特币”。注释掉这段代码,添加#include,并将assert宏定义为空语句。

(2)添加#define?在文件net.h __func__?__FUNCTION__,__func__是GCC的,__FUNCTION__是VC的。

(3)addr man . h文件中类似CAddrM的an中的IMPLEMENT_SERIALIZE因为括号不对,编译报错,不用IMPLEMENT_SERIALIZE宏,把宏IMPLEMENT_SERIALIZE定义的3个函数函数GetSerializeSize、Serialize、Unserialize中的‘{statements} ’替换为IMPLEMENT_SERIALIZE中的参数。

因为变量nVersion在函数参数中有定义,且局部变量中也有定义,重复定义,注释掉局部变量中的nVersion。

(4)把文件core.h中类CTxOutCompressor的IMPLEMENT_SERIALIZE宏展开,用实际代码替换,不用IMPLEMENT_SERIALIZE宏,用宏的参数替换宏定义中的{statements}字段。

(5)把文件serialize.h中ReadCompactSize函数中的0x100000000LLu改为(unsigned __int64)0×100000000。VC不支持LLu类型的数据。

(6)文件serialize.h中,类CDataStream的构造函数中: CDataStream(const std::vector& vchIn, int nTypeIn, int nVersionIn) : vch((char*)&vchIn.begin()[0], (char*)&vchIn.end()[0]),运行时报错,注释掉”[0]“。VC不允许数组大小为0。

(7)文件script.h中的CScriptCompressor中的Serialize函数、Unserialize函数中的数组越界了,且需要处理大小为0的数组,共4处。

Serialize函数中:

if(compr.size() > 0) s < 0) s << CFlatData(&script[0], &script[script.size()-1]);

Unserialize函数:

if(vch.size() > 0) s >> REF(CFlatData(&vch[0], &vch[vch.size()-1]));if(script.size() > 0) s >> REF(CFlatData(&script[0], &script[script.size()-1]));

这个问题我在github上提过,但laanwj有他的看法,有兴趣的可以看看。地址:https://github.com/bitcoin/bitcoin/pull/4239。

(8)文件script.h中类CScript中:

#ifndef _MSC_VERCScript(const unsigned char* pbegin, const unsigned char* pend) : std::vector(pbegin, pend) { }#endif

注释掉_MSC_VER的宏定义。

因为文件\qt\walletmodel.cpp中的WalletModel::prepareTransaction函数中的代码:

const unsigned char* scriptStr = (const unsigned char*)out.script().data();CScript scriptPubKey(scriptStr, scriptStr+out.script().size());

编译错误,scriptStr的类型转换失败。

(9)在文件key.cpp中,添加函数:

int CompareBigEndianEx(const unsigned char *c1, size_t c1len) { while (c1len > 0) { if (*c1) return 1; c1++; c1len--; } return 0;}

注释掉const unsigned char vchZero[0] = {};

函数CKey::Check、CKey::CheckSignatureElement中的CompareBigEndian(vch, len, vchZero, 0)改为CompareBigEndianEx(vch, 32)。

GCC允许数组大小为0,但VC不允许。

(10)文件addrman.cpp中的CAddrMan::Select_函数中的代码:

double nCorTried = sqrt(nTried) * (100.0 - nUnkBias);double nCorNew = sqrt(nNew) * nUnkBias;

改为:

double nCorTried = sqrt((double)nTried) * (100.0 - nUnkBias);double nCorNew = sqrt((double)nNew) * nUnkBias;

在sqrt函数的参数加入(double)强制类型转换,VC支持3个sqrt函数,参数类型不同,这里增加强制类型转换。

(11)文件init.cpp中的AppInit2函数中的Setvbuf的最后一个参数0改为INT_MAX。

setvbuf(stdout, NULL, _IOLBF, INT_MAX /*0*/);

VC不允许最后一个参数为0。

(12)把文件db.h中类CDB的部分代码注释掉,分别是:

Read函数中的free(datValue.get_data());ReadAtCursor函数中的free(datKey.getdata());free(datValue.getdata());

Free地址时报错,我跟踪过,在数据库的pdb->get函数中确实调用了malloc函数申请内存,按理说free此地址没问题,但报错,这个问题暂时解决不了,后续解决。

(13)文件db.cpp中,类CDBEnv的CloseDb函数,delete pdb;时报错,解决不了,暂时注释掉,可能会产生数据库操作错误。

同步区块半小时后不在同步,这个问题可以跟与数据库的这2个修改相关,尚未确定。

(14)BTC源码中有2个bloom文件,分别是bloom.cpp、\leveldb\util\bloom.cc,编译时生成的bloom.obj冲突,把其中1个文件改名即可,把bloom.cc改名为bloomdb.cc。

(15)BTC源码中有2个hash文件,分别是hash.cpp、\leveldb\util\hash.cc,编译时生成的hash.obj冲突,把其中1个文件改名即可,把hash.cc改名为hashdb.cc。

(16)把文件\leveldb\util\env_win.cc中的CreateDirInner函数中的GetFileAttributes改为GetFileAttributesA,CreateDirectory改为CreateDirectoryA,强制使用ASCI函数。

(17)注释掉\leveldb\db\dbbench.cc、\leveldb\db\leveldbmain.cc中的main函数,冲突了。

(18)在文件netbase.cpp、\leveldb\db\dbiter.cc中添加语句:”typedef signed int ssizet;”,VC中没有定义ssize_t数据类型。

(19)注释掉文件\leveldb\db\c.cc中的#include ,这是linux的头文件。

(20)函数min()、max()在windef.h、stl中有不同的定义,需要把std::numericlimits::max()改为(std::numericlimits::max)(),否则编译时max()参数报错。

需要改的地方包括:

文件serialize.h中的GetSizeOfCompactSize函数script.h文件中的类CScriptNum中的减号重载、加等于、减等于、getint()函数,WriteCompactSize函数文件core.h中的类CTxIn的3个构造函数,、IsFinal()函数\Qt\Qt5.2.0\5.2.0\msvc2010\include\QtCore\qdatetime.h中的类QDate中的nullJd函数

文件wallet.h中类CWallet的LoadMinVersion函数中的参数std::max加上小括号。

文件net.h中的类CNode的AskFor函数中的std::max加上小括号。

2、工程bitcoin-qt、bitcoin-qt-test

(1)在CMD中,运行\protobuf-2.5.0\vsprojects\Release目录下的protoc.exe,生成paymentrequest.proto文件对应的头文件、源文件,命令格式为:

protoc --proto_path=e:/bitcoin/qt --cpp_out=e:/bitcoin/qt e:/bitcoin/qt/paymentrequest.proto

把生成的.h、.cc文件添加到bitcoin-qt、bitcoin-qt-test工程中。

(2)对\qt\locale下的所有文件执行lrelease操作,在资源管理器中,在locale下的文件上点击右键,执行lrelease操作,生成文字的多国语言版本。

(3)在文件\qt\winshutdownmonitor.h中语句“#include // for HWND”前面添加#include 。因为编译时报错:1>c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winnt.h(6361): error C2146: syntax error : missing ‘;’ before identifier ‘ContextRecord’,多个错误。

(4)修改bitcoin-qt、bitcoin-qt-test工程中的某些cpp文件的编译方式,把Custom Build Tool改为C/C++ compiler。需要修改的文件为:rpcconsole.cpp、intro.cpp、overviewpage.cpp、bitcoin.cpp。

(5)注释掉文件\qt\test\test_main.cpp的第一行代码:#include “bitcoin-config.h”。我已经提交github修改此BUG,已通过,5月22日之后的代码没有这个问题,github上的修改BUG地址:https://github.com/bitcoin/bitcoin/pull/4212。有兴趣可以查看。

3、工程test_bitcoin

移除test_bitcoin工程中COMMON的源文件目录下的init.cpp,因为变量pwalletMain等重定义了,冲突。在文件\test\utiltests.cpp中添加代码:typedef signed int ssizet;在MAC系统下编译bitcoin,把\src\test\data目录下的所有h文件复制到相同目录中。(因为分析makefile,把json文件转换成h文件的方法是通过创建h文件,输出字符串,字符转换等完成的,需要新写程序来做,所以暂时使用MAC编译后的h文件。)

在src目录中的Makefile.include文件完成此操作,转换代码如下:

%.json.h: %.json @$(MKDIR_P) $(@D) @echo "namespace json_tests{" > $@ @echo "static unsigned const char $(*F)[] = {" >> $@ @$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $> $@ @echo "};};" >> $@ @echo "Generated $@"%.raw.h: %.raw @$(MKDIR_P) $(@D) @echo "namespace alert_tests{" > $@ @echo "static unsigned const char $(*F)[] = {" >> $@ @$(HEXDUMP) -v -e '8/1 "0x%02x, "' -e '"\n"' $> $@ @echo "};};" >> $@ @echo "Generated $@"

第六节 调试建议

各个程序编译通过,但尚未经过大量测试,只可用于研究技术,不可作为钱包以及比特币的发送、接收,我用bitcoin-qt调试比较多。

运行界面如下:

建议:

从bitcoin官网下载安装包,安装标准版。把注册表路径HKEY_CURRENT_USER\Software\Bitcoin\Bitcoin-Qt下的strDataDir的值改为别的路径,这样调试的bitcoin-qt采用新设置的路径。把注册表路径HKEY_CURRENT_USER\Software\Bitcoin\Bitcoin-Qt下的language改为en,bitcoin-qt的界面显示为英文,可以根据英文字符串定位代码。默认显示中文,中文是根据英文字符串翻译后的,用中文字符串不太容易定位代码。

——————–

作者: 龙少

新浪微博昵称: 007龙少

新浪微博地址: http://weibo.com/u/1064323301

BTC捐助地址: 1CeeGr858xjLJQB3a9uLawHAdZ2qWjzTGT

6PDF下载版:http://pan.baidu.com/s/1hqefNd6

VC编译调试比特币源码 | 分享给朋友: