比特币源码研读之一
本人15年毕业后一直从事Java电商平台的开发工作,2017年4月开始接触区块链技术,随后慢慢自学了《精通比特币》,谈谈区块链,以太坊,Solidity等相关内容。前不久开始阅读bitcoin的源码,在网上找资料的过程中,发现并加入了区块链研习社。随后在编译比特币源码的过程中与菜菜子进行了一系列的技术交流。刚好比特币源码班二期开班,随后报名加入该班级,开启了比特币源码的研读之旅。源码的阅读相对枯燥无味,希望自己能在坚持下去。好了,废话不多说,Let’s get started.
本系列文章基于bitcoin-0.15, 下载地址: https://github.com/bitcoin/bitcoin. 我们先从宏观上看下源码的目录结构以及数据目录的结构。项目源码的目录结构如下:
接下来我们简要分析下src目录下几个关键的模块,后续随着我们对源码的不断研究将详细分析各个模块的内容。
./:网络处理模块,块的产生,初始化模块,链的操作模块等
compact:处理文件兼容性相关的细节,较为low level
consensus:交易/块的验证,merkle tree相关的计算,一些共识参数的定义
crypto:加密HASH函数,SHA256、RIPEMD160等
leveldb:bitcoin使用level db存储block、tx、utxo等内容(文章后面有相关描述)https://github.com/google/leveldb
policy:与consensus相反,用户可以根据自身的需求定义不同的policy,例如是否转发大小为100k以上的交易等
primitives:块和交易相关的基本数据类型定义
qt:桌面客户端源程序
rpc:远程过程调用接口的相关实现
script:脚本引擎,定义了操作码,交易签名的生成与验证等
secp256k1:椭圆曲线函数库
univalue:univalue库https://github.com/jgarzik/univalue
wallet:钱包相关操作,地址的管理,交易的生成等
zmq:zmq是一个高性能的异步消息库
接下来,我们来看一下数据目录结构并简要分析下一些主要的文件:
¬ blocks/blk*.dat:所有的区块数据,这部分数据只有在钱包需要重新扫描丢失的交易,重组链以及向其他节点提供区块数据等情况时被使用。
¬ blocks/rev*.dat:这些文件可以理解为“撤销”(undo)文件。区块链在某一种程度上可以看做是一个状态机,每一种状态我们叫做chain state(UTXOs),每当接收到了一个块,经过一系列的处理(状态转换函数)变成了另一个chain state。所以我们可以把一个块当作是某个chain state的一个补丁(patch),同时把这些“撤销”文件当作是回退(reverse)操作的patch。当发生区块链重组(reorganization)的时候,这些数据可以方便快捷的回滚chain state.
¬ blocks/index/*:该目录下是level db的存储文件,记录了该节点上所有块的元数据信息以及怎样在磁盘中找到块的具体数据。如果没有这部分数据,查找一个块将会非常的慢。
¬ chainstate/*:该目录下是UTXO的level db存储文件以及相关的一些meta信息,可以用于验证块和交易的有效性。这部分数据也可以通过参数-reindex根据blocks重新生成。如果没有这部分数据,需要扫描所有的块进行区块和交易的验证将会非常耗时。
¬ wallet.data:最为重要的钱包文件,该文件中存储着钱包中所有的密钥信息。我们常说的备份bitcoin core钱包,就是备份该文件。只要有了该文件,把文件放到对应的钱包数据目录下,你可以在任何其他任何bitcoin core节点操作你的钱包。
¬ debug.log:该文件记录的程序运行的各种提示信息。在遇到问题时,可以通过查看该文件获得具体的信息提示。启动bitcoind时,可以通过参数-debug设置日志级别。
本篇文章简要分析了比特币源码的目录结构以及数据存储目录结构,接下来的文章我们将进入源码的阅读。