区块广播:
· 分析师:若BTC突破4200美金,应买“市值前50+低位滞涨+汇率突破”的币种
· Reserve首席执行官:许多稳定币人为地夸大了市值和交易量
· BTC挖矿难度下次预计上调6.21%
· 日本横滨地方法院将于27日宣判一起利用他人设备算力挖矿案件
· 今日比特币全网算力为45.66 EH/s
· BM:6月将会有新消息影响EOS,并将是自EOSIO面市以来的最大的新闻
· 数据显示:以太坊链上交易热情持续低迷
· 调查显示:社区普遍认为只有当关键协议出现漏洞、或受到威胁时才应该实施硬分叉
· 花旗银行近日在招聘区块链及加密货币领域相关职位
· 央财教授邓建鹏:区块链的投资风险与国际监管势在必行
· 中国人民大学宋华:仅仅依靠云计算或区块链等单独一项技术,不可能解决供应链金融的效率问题
· BM:ETH拥有更多的开发者是因为最初的方案设计过于复杂
· “末日博士”Nouriel Roubini:区块链与贪婪有关,加密货币导致财富集中
· 数据显示:市场流量缓慢回升,BTC交易量虽连续3日萎缩
· 应用程序Bitcoinmap.cash可列出支持BCH支付的商家位置
· 香港联交所认为环球通证的区块链业务与现有业务无关等,有必要暂停其股份买卖
· 美国CFTC前主席:虚拟货币应由政府制定法规加以规范
· 推特对账号@Bitcoin的限制陷入争议
· 台湾“国发会”主委:产业需要区块链等科技导入
· 伊朗或将在旅游业内推广整合加密货币
· 分析师:若BTC突破4200美金,应买“市值前50+低位滞涨+汇率突破”的币种
· Reserve首席执行官:许多稳定币人为地夸大了市值和交易量
· BTC挖矿难度下次预计上调6.21%
· 日本横滨地方法院将于27日宣判一起利用他人设备算力挖矿案件
· 今日比特币全网算力为45.66 EH/s
· BM:6月将会有新消息影响EOS,并将是自EOSIO面市以来的最大的新闻
· 数据显示:以太坊链上交易热情持续低迷
· 调查显示:社区普遍认为只有当关键协议出现漏洞、或受到威胁时才应该实施硬分叉
· 花旗银行近日在招聘区块链及加密货币领域相关职位
· 央财教授邓建鹏:区块链的投资风险与国际监管势在必行
· 中国人民大学宋华:仅仅依靠云计算或区块链等单独一项技术,不可能解决供应链金融的效率问题
· BM:ETH拥有更多的开发者是因为最初的方案设计过于复杂
· “末日博士”Nouriel Roubini:区块链与贪婪有关,加密货币导致财富集中
· 数据显示:市场流量缓慢回升,BTC交易量虽连续3日萎缩
· 应用程序Bitcoinmap.cash可列出支持BCH支付的商家位置
· 香港联交所认为环球通证的区块链业务与现有业务无关等,有必要暂停其股份买卖
· 美国CFTC前主席:虚拟货币应由政府制定法规加以规范
· 推特对账号@Bitcoin的限制陷入争议
· 台湾“国发会”主委:产业需要区块链等科技导入
· 伊朗或将在旅游业内推广整合加密货币
· 分析师:若BTC突破4200美金,应买“市值前50+低位滞涨+汇率突破”的币种
· Reserve首席执行官:许多稳定币人为地夸大了市值和交易量
· BTC挖矿难度下次预计上调6.21%
· 日本横滨地方法院将于27日宣判一起利用他人设备算力挖矿案件
· 今日比特币全网算力为45.66 EH/s
· BM:6月将会有新消息影响EOS,并将是自EOSIO面市以来的最大的新闻
· 数据显示:以太坊链上交易热情持续低迷
· 调查显示:社区普遍认为只有当关键协议出现漏洞、或受到威胁时才应该实施硬分叉
· 花旗银行近日在招聘区块链及加密货币领域相关职位
· 央财教授邓建鹏:区块链的投资风险与国际监管势在必行
· 中国人民大学宋华:仅仅依靠云计算或区块链等单独一项技术,不可能解决供应链金融的效率问题
· BM:ETH拥有更多的开发者是因为最初的方案设计过于复杂
· “末日博士”Nouriel Roubini:区块链与贪婪有关,加密货币导致财富集中
· 数据显示:市场流量缓慢回升,BTC交易量虽连续3日萎缩
· 应用程序Bitcoinmap.cash可列出支持BCH支付的商家位置
· 香港联交所认为环球通证的区块链业务与现有业务无关等,有必要暂停其股份买卖
· 美国CFTC前主席:虚拟货币应由政府制定法规加以规范
· 推特对账号@Bitcoin的限制陷入争议
· 台湾“国发会”主委:产业需要区块链等科技导入
· 伊朗或将在旅游业内推广整合加密货币

比特币源代码分析

Dr.Nefario船员发布在 BTC/比特币
 34171  11
bitcoin源码分析

Table of Contents

1 必读–如何阅读org文档
2 准备工作
2.1 1.产生调试信息
2.2 2.gdb里增加对stl的支持
3 开始分析
3.1 静态分析
3.1.1 配置文件、快链数据文件、索引文件及相关目录:
3.1.2 源代码文件说明:
3.2 动态分析
3.2.1 配置bitcoin.conf
3.2.2 开始调试
1 必读–如何阅读org文档

如何打开org文档
可以直接在github上打开org文档,但是为了方便的跳转到源代码,请使用Emacs编辑器打开org文档!Windows环境的下载链接,Linux下直接使用apt-get或者yum直接安装emacs即可;
如何使用TAB按键
在*和**、***以及更多星号开头的标题上敲击键盘上的Tab按键,可以展开和隐藏这个标题里的内容;
如何理解行首的冒号
行首的冒号(:)是方便org文档输出到HTML文档重点标注代码和命令,除了在#+BEGINEXAMPLE和#+ENDEXAMPLE里原样输出;
如何生成HTML文档
菜单栏里选择Org->Export/Publish,会调用导出HTML的选项;
如何链接到源代码
比如file:~/.bitcoin ,将光标移动到file开头的链接上,鼠标点击,就会自动跳转到源代码了,如果是目录,就会打开目录。
下载bitcoin源代码
从github网站上直接下载或者使用命令行工具:[code]git clone --branch v0.8.2 https://github.com/bitcoin/bitcoin.git[/code]注意将bitcoin源代码目录放在~目录下,目录名为bitcoin,以便迅速在Emacs编辑器中打开bitcoin源代码,Windows下的目录一般为:[code]C:\Documents and Settings\Administrator\Applicatin Data[/code]如果没有这个目录,可以用如下命令查看目录路径[code]set appdata[/code]2 准备工作

假设你已经对STL及gdb有了一些基本认识,熟悉C++编程。

2.1 1.产生调试信息

在configure.ac文件里增加2行代码(注意:行首有冒号):[code]AC_INIT([Bitcoin]...
: ${CFLAGS="-g -ggdb"}
: ${CXXFLAGS="-g -ggdb"}[/code]按照doc/build-unix.md文件里的的要求重新配置并编译:[code]./autogen.sh
./configure
make -B //如果是第一次编译,不需要-B[/code]这样在输出的.o文件及elf文件里就会包含有调试信息,否则默认会使用-O2优化选项。

2.2 2.gdb里增加对stl的支持

bitcoin里大量使用了stl,方便在Linux、Windows、Mac间移植。 7.0以后的gdb已经增加了对Python的支持,通过Python,增加gdb对STL的支持: http://sourceware.org/gdb/wiki/STLSupport

3 开始分析

3.1 静态分析

3.1.1 配置文件、快链数据文件、索引文件及相关目录:

在root下有一个目录.bitcoin,首先介绍下几个文件: file:~/.bitcoin

bitcoin.conf
配置文件,bitcoind启动的时候会读取这个文件
debug.log
调试信息输出到这个文件里
peers.dat
存储的其他peer的信息
wallet.dat
钱包文件
blocks
快链(block chain)存储的地方
chainstate
快链的状态
testnet3
用于测试的快链,有一个不同的起始块(genesis block),testnet1中的起始块,就是目前大家在交易的块链。

3.1.2 源代码文件说明:

.h文件及.cpp文件中类的定义及说明: Doxygen自动产生的说明

3.2 动态分析

3.2.1 配置bitcoin.conf[code]testnet=1[/code]使用测试网络,详见bitcoin.conf的详细配置

3.2.2 开始调试[code]gdb bitcoind[/code]好了,从bitcoind里读取symbol的时间可能会稍微长点:

Reading symbols from bitcoin/src/bitcoind...done.

开始调试:[code]b main
run[/code][code]int main(int argc, char* argv[])
{
bool fRet = false;

// Connect bitcoind signal handlers
noui_connect();

fRet = AppInit(argc, argv);

if (fRet && fDaemon)
return 0;

return (fRet ? 0 : 1);
}[/code]main()函数的重点是AppInit(),nouiconnect()是用来链接前端Qt的初始化程序,图形界面我们就不分析了,直接进入到AppInit()[code]1. bool AppInit(int argc, char* argv[])
2. {
3. boost::thread_group threadGroup;//使用boost的多线程,使得前端Qt程序运行流畅
4. boost::thread* detectShutdownThread = NULL;//在程序启动期间,如果按了Ctrl-C键退出,则让多线程处理完后退出

5. bool fRet = false;
6. try
7. {
8. //
9. // Parameters
10. //
11. // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
12. ParseParameters(argc, argv);
13. if (!boost::filesystem::is_directory(GetDataDir(false)))
14. {
15. fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str());
16. return false;
17. }
18. ReadConfigFile(mapArgs, mapMultiArgs);
19. // Check for -testnet or -regtest parameter (TestNet() calls are only valid after this clause)
20. if (!SelectParamsFromCommandLine()) {
21. fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
22. return false;
23. }

24. if (mapArgs.count("-?") || mapArgs.count("--help"))
25. {
26. // First part of help message is specific to bitcoind / RPC client
27. std::string strUsage = _("Bitcoin Core Daemon") + " " + _("version") + " " + FormatFullVersion() + "\n\n" +
28. _("Usage:") + "\n" +
29. " bitcoind [options] " + _("Start Bitcoin server") + "\n" +
30. _("Usage (deprecated, use bitcoin-cli):") + "\n" +
31. " bitcoind [options] [params] " + _("Send command to Bitcoin server") + "\n" +
32. " bitcoind [options] help " + _("List commands") + "\n" +
33. " bitcoind [options] help " + _("Get help for a command") + "\n";

34. strUsage += "\n" + HelpMessage(HMM_BITCOIND);
35. strUsage += "\n" + HelpMessageCli(false);

36. fprintf(stdout, "%s", strUsage.c_str());
37. return false;
38. }

39. // Command-line RPC
40. bool fCommandLine = false;
41. for (int i = 1; i < argc; i++)
42. if (!IsSwitchChar(argv[0]) && !boost::algorithm::istarts_with(argv, "bitcoin:"))
43. fCommandLine = true;

44. if (fCommandLine)
45. {
46. int ret = CommandLineRPC(argc, argv);
47. exit(ret);
48. }
49. #ifndef WIN32
50. fDaemon = GetBoolArg("-daemon", false);
51. if (fDaemon)
52. {
53. fprintf(stdout, "Bitcoin server starting\n");

54. // Daemonize
55. pid_t pid = fork();
56. if (pid < 0)
57. {
58. fprintf(stderr, "Error: fork() returned %d errno %d\n", pid, errno);
59. return false;
60. }
61. if (pid > 0) // Parent process, pid is child process id
62. {
63. CreatePidFile(GetPidFile(), pid);
64. return true;
65. }
66. // Child process falls through to rest of initialization

67. pid_t sid = setsid();
68. if (sid < 0)
69. fprintf(stderr, "Error: setsid() returned %d errno %d\n", sid, errno);
70. }
71. #endif
72. SoftSetBoolArg("-server", true);

73. detectShutdownThread = new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup));
74. fRet = AppInit2(threadGroup);
75. }
76. catch (std::exception& e) {
77. PrintExceptionContinue(&e, "AppInit()");
78. } catch (...) {
79. PrintExceptionContinue(NULL, "AppInit()");
80. }[/code]代码里增加了一些中文注释,作为对英文注释的补充。

try..catch{}方式处理这段代码,因为这里涉及大量磁盘读取,有可能碰到无法打开文件,磁盘空间满等其他问题。
ParseParameters()及ReadConfigFile()都是在读取一些参数,需要注意的是,命令行参数的优先级高于配置文件,比如执行了如下语句[code]bitcoind -testnet=0[/code]则在bitcoin.conf中配置的testnet则无效了。

参数最终储存在mapArgs及mapMultiArgs中,定义如下:[code]map mapArgs;
map > mapMultiArgs;[/code]使用了STL的map定义的,后面会经常使用这几个函数GetBoolArg()、GetArg()来查看参数设置,如:[code]bool GetBoolArg(const std::string& strArg, bool fDefault)
{
if (mapArgs.count(strArg))
{
if (mapArgs[strArg].empty())
return true;
return (atoi(mapArgs[strArg]) != 0);
}
return fDefault;
}[/code]经常会看到这样调用GetBoolArg():

GetBoolArg("-daemon", false)
如果没有找到相关设置,则返回假。

24行到38行是打印帮助提示。
介绍下面的内容前,先介绍下RPC(远程过程调用),命令行方式下RPC的使用方法:
bitcoind -daemon //后台运行
bitcoind getinfo //获取状态信息
bitcoind -stop//停止daemon进程
39行到48行判断是否是上面第二行(getinfo)的语句:首先判断参数是否有'-'或'/',并且不包含'bitcoin:',则执行RPC(使用的是JSON-RPC调用协议)
bitcoin:URI是用于请款的,所以应该排除这种情况: bitcoin://1F2EUzKR1XsLRCtEnsnpDQZ13XJgS6P3ZK?amount=0.001&message=donation

接着执行CommandLineRPC(),具体执行RPC(远程过程调用).

49行到71行是处理-daemon参数,假设这样运行bitcond
bitcoind -daemon
通过fork()创建一个子进程,创建成功,父进程则在64行的时候返回,子进程接着执行下面的初始化,包括AppInit2()。 在.bitcoin目录下创建了一个bitcoind.pid的文件,记录了子进程的PID。

file:~/bitcoin/src/init.cpp::bool AppInit2 boost threadgroup threadGroup[code]/** Initialize bitcoin.
* @pre Parameters should be parsed and config file should be read.
*/
bool AppInit2(boost::thread_group& threadGroup)
{
// ****************** Step 1: setup 设置
...
// ****************** Step 2: parameter interactions 参数互动(主要是一些参数设置)
...
// ****************** Step 3: parameter-to-internal-flags 参数传入内部标记(bool型变量)
...
// ****************** Step 4: application initialization: dir lock, daemonize, pidfile, debug log 应用初始化:锁定目录,后台运行,调试信息
...
// ****************** Step 5: verify wallet database integrity 确认钱包数据库的完整性
...
// ****************** Step 6: network initialization 网络初始化
...
// ****************** Step 7: load block chain 加载块链
...
// ****************** Step 8: load wallet 加载钱包
...
// ****************** Step 9: import blocks 导入块数据
...
// ****************** Step 10: load peers 导入peers
...
// ****************** Step 11: start node 开始节点(挖矿程序在这里)
...
// ****************** Step 12: finished 完成
...
}[/code]AppInit2里包含了bitcoin的大部分初始程序,包括读取'块索引'、加载块链、加载100个预产生的keys,导入peers.dat中的信息,以及初始化其他线程。
未完待续,Contact me:

BitMessage:BM-2cVh8hpF9jcvDtFJCDddx518EEs76SvTUE
BTC:1F2EUzKR1XsLRCtEnsnpDQZ13XJgS6P3ZK

2014-01-19 星期日
Author: root <root@localhost.localdomain>

Date: 2014-02-12 12:57:23 CST

HTML generated by org-mode 6.33x in emacs 23


  • 正序
  • 最新
只看帖主楼层直达
登录 账号发表你的看法,还没有账号?立即免费 注册
推荐节点 更多
热帖榜 本周最热本月最热