目录
数字货币
云计算
编程
网络
其他
架构设计
密码学
bitcoin源代码分析
1.1 比特币网络
1.1.1 比特币P2P网络穿透
比特币网络是典型的P2P网络,其NAT穿透使用upnp协议,详见Net.cpp部分代码:
#ifdef USE_UPNP
#include <miniupnpc/miniupnpc.h>
#include <miniupnpc/miniwget.h>
#include <miniupnpc/upnpcommands.h>
#include <miniupnpc/upnperrors.h>
#endif
1.1.2 比特币网络发现
比特币客户端节点第一次启动后,并不知道任何活动的节点IP地址,他们会查询写在比特币内核中硬编码的DNS服务名称(叫做DNS种子),这些DNS服务会回复给他们最新的活跃节点IP地址,建立新的连接。
DNS种子是由比特币维护社区成员:他们中的一些人提供动态DNS种子服务器通过扫描网络自动获得IP地址的活跃节点;其他人提供静态DNS种子,手动更新,更有可能为非活动节点的IP地址。在这两种情况下,节点被添加到DNS种子如果他们运行在默认的比特币端口mainnet 8333或testnet 8333。1
DNS seed:
seed.bitcoin.sipa.be
dnsseed.bluematt.me
dnsseed.bitcoin.dashjr.org
seed.bitcoinstats.com
seed.bitcoinstats.com
seed.btc.petertodd.org
详见Chainparams.cpp代码CMainParams类中的这些DNS sead:
// Note that of those with the service bits flag, most only support a subset of possible options
vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be", true)); // Pieter Wuille, only supports x1, x5, x9, and xd
vSeeds.push_back(CDNSSeedData("bluematt.me", "dnsseed.bluematt.me", true)); // Matt Corallo, only supports x9
vSeeds.push_back(CDNSSeedData("dashjr.org", "dnsseed.bitcoin.dashjr.org")); // Luke Dashjr
vSeeds.push_back(CDNSSeedData("bitcoinstats.com", "seed.bitcoinstats.com", true)); // Christian Decker, supports x1 - xf
vSeeds.push_back(CDNSSeedData("bitcoin.jonasschnelli.ch", "seed.bitcoin.jonasschnelli.ch", true)); // Jonas Schnelli, only supports x1, x5, x9, and xd
vSeeds.push_back(CDNSSeedData("petertodd.org", "seed.btc.petertodd.org", true)); // Peter Todd, only supports x1, x5, x9, and xd
除了DNS种子发现网络节点,还有其他的方法,详见Satoshi Client Node Discovery:
- IRC (Internet Relay Chat)互联网中继聊天
- 自广播
- 命令行添加
1.1.3 比特币与洋葱网络(Tor)
洋葱网络不是p2p的必备组件,在比特币中主要是为了实现网络匿名和防止窃听。
1.2 bitcoin初始化与启动
比特币程序总入口main()在bitcoind.cpp代码中2:
int main(int argc, char* argv[])
{
//设置比特币客户端程序的本地运行环境
SetupEnvironment();
//链接消息处理
noui_connect();
//程序生命周期的消息循环
return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);
}
AppInit()函数:
- 解析命令行参数
- 打开数据库目录
- 读取配置文件
- 创建进程(如果是守护进程执行)
- 初始化应用程序AppInitMain(),在init.cpp中
AppInitMain()函数:
- 设置系统相关任务
- 参数解析交互
- 参数检查
- 启动RPC服务
- 验证钱包数据库完整性
- 网络初始化
- 加载区块链
- 加载钱包
- 维护数据目录
- 导入块
- 启动节点connman.Start(),在net.cpp
- 完成
Connman类是CNode类的友类,CConnman::Start()函数:
- 启动节点网络线程组
- thread (ThreadGetMyExternalIP)
- thread (ThreadMapPort)
- thread (ThreadIRCSeed)
- thread (ThreadSocketHandler)
- thread (ThreadOpenConnections)
- thread (ThreadMessageHandler)
- ThreadRPCServer() 3