├── CNAME ├── README.md ├── RPC-interface.adoc ├── _config.yml ├── addrman.h.adoc ├── alert.h.adoc ├── allocators.h.adoc ├── base58.h.adoc ├── bignum.h.adoc ├── bitcoinrpc.h.adoc ├── bloom.h.adoc ├── book.adoc ├── checkpoints.h.adoc ├── checkqueue.h.adoc ├── clientversion.h.adoc ├── compact.h.adoc ├── crypter.h.adoc ├── db.h.adoc ├── hash.h.adoc ├── images └── Q.jpg ├── init.h.adoc ├── key.h.adoc ├── keystore.h.adoc ├── leveldb.h.adoc ├── limitedmap.h.adoc ├── main.h.adoc ├── mruset.h.adoc ├── net.h.adoc ├── netbase.h.adoc ├── preface.adoc ├── protocol.h.adoc ├── script.h.adoc ├── serialize.h.adoc ├── source-structure.adoc ├── sync.h.adoc ├── threadsafety.h.adoc ├── txdb.h.adoc ├── ui_interface.h.adoc ├── uint256.h.adoc ├── util.h.adoc ├── version.h.adoc ├── wallet.h.adoc └── walletdb.h.adoc /CNAME: -------------------------------------------------------------------------------- 1 | zaobi.org -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bitcoin-notes 比特币源码分析 2 | 3 | 4 | 5 | ### 吐槽 6 | 7 | 比特币最大的问题是挖矿,算力的集中,与其去中心化的理想背道而驰. 8 | 9 | 这是对现实的折中,也使其有了被主流接受的可能. 10 | 11 | 如果去中心化最终成为主流,比特币将因此被淘汰. 12 | 13 | 14 | ### 简介 15 | 主要是对源码的注解,也有一些总结性的东西.***仅供参考,欢迎反馈*** 16 | 17 | 源码的注解重点是头文件(头文件明白了,cpp文件基本也没问题). 18 | 19 | 目前计划只包含核心的文件,不含qt界面的代码. 20 | 21 | 本项目主要针对**山寨币开发者**,各路大牛请绕道 22 | 23 | ### 文件目录 24 | 25 | 头文件 | 状态 26 | ------------ | ------------- 27 | [addrman.h](addrman.h.adoc) | :heavy_check_mark: 28 | [alert.h](alert.h.adoc) | :heavy_check_mark: 29 | [allocators.h](allocators.h.adoc) | :x: 30 | [base58.h](base58.h.adoc) | :heavy_check_mark: 31 | [bignum.h](bignum.h.adoc) | :heavy_check_mark: 32 | [bitcoinrpc.h](bitcoinrpc.h.adoc) | :heavy_check_mark: 33 | [bloom.h](bloom.h.adoc) | :heavy_check_mark: 34 | [checkpoints.h](checkpoints.h.adoc) | :heavy_check_mark: 35 | [checkqueue.h](checkqueue.h.adoc) | :clock1: 36 | [clientversion.h](clientversion.h.adoc) | :clock1: 37 | [compact.h](compact.h.adoc) | :heavy_check_mark: 38 | [crypter.h](crypter.h.adoc) | :heavy_check_mark: 39 | [db.h](db.h.adoc) | :heavy_check_mark: 40 | [hash.h](hash.h.adoc) | :heavy_check_mark: 41 | [init.h](init.h.adoc) | :clock1: 42 | [key.h](key.h.adoc) | :heavy_check_mark: 43 | [keystore.h](keystore.h.adoc) | :heavy_check_mark: 44 | [leveldb.h](leveldb.h.adoc) | :heavy_check_mark: 45 | [limitedmap.h](limitedmap.h.adoc) | :heavy_check_mark: 46 | [main.h](main.h.adoc) | :x: 47 | [mruset.h](mruset.h.adoc) | :heavy_check_mark: 48 | [netbase.h](netbase.h.adoc) | :heavy_check_mark: 49 | [net.h](net.h.adoc) |:x: 50 | [protocol.h](protocol.h.adoc) | :heavy_check_mark: 51 | [script.h](script.h.adoc) |:x: 52 | [ui_interface.h](ui_interface.h.adoc) |:x: 53 | [serialize.h](serialize.h.adoc) |:x: 54 | [sync.h](sync.h.adoc) |:x: 55 | [threadsafety.h](threadsafety.h.adoc) |:x: 56 | [txdb.h](txdb.h.adoc) |:x: 57 | [uint256.h](uint256.h.adoc) |:x: 58 | [util.h](util.h.adoc) |:x: 59 | [version.h](version.h.adoc) | :heavy_check_mark: 60 | [walletdb.h](walletdb.h.adoc) | :heavy_check_mark: 61 | [wallet.h](wallet.h.adoc) |:x: 62 | 63 | 64 | ### 前置知识 65 | 66 | * C++ 67 | * 密码学相关知识 68 | 69 | 70 | ### 欢迎Issue、PR 71 | 72 | ### 版本 73 | 74 | 源码的版本是0.8; 75 | 76 | 最新的比特币源码结构和0.8版本有所差异,但是核心内容是不变的. 77 | 78 | 0.8版本和大部分的山寨币的源码结构也是一样的。 79 | 80 | 81 | ### 目标 82 | 使阅读比特币源码,了解比特币原理与实现 **更方便,更快捷**. 83 | -------------------------------------------------------------------------------- /RPC-interface.adoc: -------------------------------------------------------------------------------- 1 | = 钱包RPC接口列表 2 | followtheart 3 | :doctype: article 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 10 | 11 | 12 | # 如何调用RPC 13 | 14 | 参考: 15 | https://zh-cn.bitcoin.it/wiki/API_reference_(JSON-RPC) 16 | 17 | # RPC列表 18 | 每个RPC的调用方法可以参考: 19 | https://bitcoin.org/en/developer-reference#rpcs 20 | 21 | ## addmultisigaddress <'["key","key"]'> [account] 22 | 向钱包添加了一个P2SH multisig地址。 23 | 24 | ## backupwallet 25 | 备份钱包到指定位置 26 | 27 | .格式 28 | backupwallet 29 | 30 | .参数 31 | [width="100%",options="header,footer"] 32 | |==================== 33 | | 名称 | 类型|存在|说明 34 | |destination | string|必须|备份钱包文件目的地址 35 | |==================== 36 | 37 | ## checkwallet 38 | 39 | .格式 40 | checkwallet 41 | 42 | 43 | ## createrawtransaction [{"txid":txid,"vout":n},...] {address:amount,...} 44 | 45 | 46 | ## decoderawtransaction 47 | 将交易序列化后的十六进制字符串解码为描述交易的JSON对象 48 | 49 | ## dumpprivkey 50 | 返回与地址对应的wallet-import-format(WIP)私钥。 (但不将其从钱包中删除。) 51 | 52 | ## encryptwallet 53 | 用密码加密钱包。这只是为了首次启用加密。启用加密后,您将需要输入密码以使用私钥。 54 | 55 | ## getaccount 56 | 返回与给定地址相关联的帐户的名称。 57 | 58 | ## getaccountaddress 59 | 返回当前账号的比特币地址,以及收到此帐户的付款 60 | 61 | ## getaddressesbyaccount 62 | 返回分配给特定帐户的每个地址的列表 63 | 64 | ## getbalance [account] [minconf=1] 65 | 获取钱包余额 66 | 67 | ## getblock [txinfo] 68 | ## getblock [txinfo] 69 | ## getblockcount 70 | 返回本地块链中的块数。 71 | 72 | ## getblockhash 73 | 返回在本地最佳区块链中给定高度的块的hash。 74 | 75 | 76 | ## getblocktemplate [params] 77 | ## getcheckpoint 78 | ## getconnectioncount 79 | 返回到其他节点的连接数。 80 | 81 | ## getdifficulty 82 | 返回当前难度 83 | 84 | ## getgenerate 85 | ## gethashespersec 86 | Deprecated. 87 | 88 | ## getinfo 89 | 输出关于节点和网络的各种信息 90 | 91 | ## getmininginfo 92 | 返回各种挖矿相关信息 93 | 94 | ## getnewaddress [account] 95 | 返回一个新的比特币地址来接收付款 96 | 97 | ## getnewpubkey [account] 98 | 99 | 100 | ## getpeerinfo 101 | 返回有关每个连接的网络节点的信息 102 | 103 | ## getrawmempool 104 | ## getrawtransaction [verbose=0] 105 | ## getreceivedbyaccount [minconf=1] 106 | ## getreceivedbyaddress [minconf=1] 107 | ## gettransaction 108 | ## getwork [data] 109 | ## getworkex [data, coinbase] 110 | ## help [command] 111 | 帮助 112 | 113 | ## importprivkey [label] 114 | ## keypoolrefill 115 | ## listaccounts [minconf=1] 116 | ## listaddressgroupings 117 | ## listreceivedbyaccount [minconf=1] [includeempty=false] 118 | ## listreceivedbyaddress [minconf=1] [includeempty=false] 119 | ## listsinceblock [blockhash] [target-confirmations] 120 | ## listtransactions [account] [count=10] [from=0] 121 | ## listunspent [minconf=1] [maxconf=9999999] ["address",...] 122 | ## makekeypair [prefix] 123 | ## move [minconf=1] [comment] 124 | ## repairwallet 125 | ## resendtx 126 | ## reservebalance [ [amount]] 127 | ## sendalert [cancelupto] 128 | ## sendfrom [minconf=1] [comment] [comment-to] 129 | ## sendmany {address:amount,...} [minconf=1] [comment] 130 | ## sendrawtransaction 131 | ## sendtoaddress [comment] [comment-to] 132 | ## setaccount 133 | ## setgenerate [genproclimit] 134 | ## settxfee 135 | ## signmessage 136 | ## signrawtransaction [{"txid":txid,"vout":n,"scriptPubKey":hex},...] [,...] [sighashtype="ALL"] 137 | ## stop 138 | ## submitblock [optional-params-obj] 139 | ## validateaddress 140 | ## validatepubkey 141 | ## verifymessage 142 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-architect 2 | 3 | plugins: 4 | - jemoji 5 | -------------------------------------------------------------------------------- /addrman.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析之钱包(IP)地址管理 2 | followtheart 3 | :doctype: article 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 随机钱包(IP)地址管理 10 | 11 | ## 随机(IP)地址管理器 12 | 13 | ### 设计目标 14 | 15 | * 仅保留有限数量的地址,以便addr.dat和内存要求不会无限制地增长。 16 | 17 | * 将地址表保存在内存中,并异步地将整个地址转储到addr.dat中。 18 | 19 | * 确保没有(本地化的)攻击者可以用他的节点/地址填充整个表格。 20 | 21 | ### 具体实现 22 | 23 | * 地址被组织成桶。 24 | 25 | * 尚未尝试的地址进入256个“新”桶。 26 | 27 |     * 根据信息来源的地址范围(IPv4的16位),随机选择32个存储桶 28 | 29 |       * 根据地址本身所在的范围,从其中一个中选择实际存储桶。 30 | 31 |       * 一个地址最多可以出现在4个不同的桶中,以增加频繁出现地址的选择机会。增加这种多样性的机会呈指数下降。 32 | 33 |       * 当一个新的地址添加到一个完整的存储桶中时,一个随机选择的条目(偏向于最近看不到的条目)将首先从其中删除。 34 | 35 |     * 已知可访问的节点地址进入64个“尝试过”的桶。 36 | 37 |       * 每个地址范围随机选择这些桶中的4个。 38 | 39 |       * 根据完整地址从实际存储桶中选择实际存储桶。 40 | 41 |       * 当一个新的好地址添加到一个完整的桶中时,一个随机选择的入口(偏向于最近尝试过的偏好)将被逐出它,回到“新”桶。 42 | 43 |     * 桶选择基于密码散列,使用随机生成的256位密钥,这不应该被对手观察到。 44 | 45 |     * 保持高性能的多个索引。定义DEBUG_ADDRMAN将为整个数据结构引入频繁(且昂贵)的一致性检查。 46 | -------------------------------------------------------------------------------- /alert.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析之升级通告 2 | followtheart 3 | :doctype: article 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 升级警告主要用于提醒用户版本升级 10 | 11 | ## 对山寨开发的重要性:一星 12 | 13 | 偶尔会有变态客户要求提供广播私钥 14 | 15 | ## 升级警告 16 | 警报用于通知旧版本钱包节点,如果它们过时并且需要升级。 17 | 18 | * 该消息显示在状态栏中。 19 | * 警报消息作为签名数据的向量(vector)广播。 20 | * 如果警报针对较新版本,则新版本无法反序列化读取整个缓冲区,但旧版本仍可以中继原始数据。 21 | 22 | 23 | ## CUnsignedAlert类--未签名通告 24 | 没有签名的通告 25 | 26 | ### 成员变量 27 | 28 | * nVersion;版本号 29 | * nRelayUntil; when newer nodes stop relaying to newer nodes 30 | * nExpiration; 31 | * nID; 32 | * nCancel; 33 | * std::set setCancel; 34 | * nMinVer; // lowest version inclusive 35 | * nMaxVer; // highest version inclusive 36 | * std::set setSubVer; // empty matches all 37 | * nPriority; 38 | 39 | // Actions 40 | * std::string strComment; 41 | * std::string strStatusBar; 42 | * std::string strReserved; 43 | 44 | ### 成员函数 45 | 46 | [width="100%",options="header,footer"] 47 | |==================== 48 | | 方法名 | 说明 49 | | void SetNull()|清空,重置数据为null 50 | | std::string ToString() const|... 51 | | void print() const|... 52 | |==================== 53 | 54 | 55 | ## CAlert类--通告类 56 | 通告类CAlert是序列化的CUnsignedAlert类和签名的组合。 57 | 58 | ### 成员变量 59 | 60 | * vchMsg;//序列化的未签名通告类CUnsignedAlert 61 | * vchSig;//签名 62 | 63 | ### 成员函数 64 | 65 | [width="100%",options="header,footer"] 66 | |==================== 67 | | 方法名 | 说明 68 | |void SetNull();|... 69 | |bool IsNull() const;|... 70 | |uint256 GetHash() const;|... 71 | |bool IsInEffect() const;|... 72 | |bool Cancels(const CAlert& alert) const;|... 73 | |bool AppliesTo(int nVersion, std::string strSubVerIn) const;|... 74 | |bool AppliesToMe() const;|... 75 | |bool RelayTo(CNode* pnode) const;|... 76 | |bool CheckSignature() const;|... 77 | |bool ProcessAlert(bool fThread = true);|... 78 | |==================== 79 | -------------------------------------------------------------------------------- /allocators.h.adoc: -------------------------------------------------------------------------------- 1 | = allocator.h 2 | 3 | Author Name 4 | :doctype: article 5 | :encoding: utf-8 6 | :lang: en 7 | :toc: left 8 | :numbered: 9 | -------------------------------------------------------------------------------- /base58.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析之钱包地址和base58编码 2 | followtheart 3 | :doctype: article 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 比特币地址有两种:公钥地址和脚本地址.两种地址都使用base58编码,两种地址版本号不同. 10 | 11 | ## 对山寨开发的重要性:五星 12 | 13 | 基本上每个客户都会要求修改钱包地址首字母 14 | 15 | ## 关于Base58 16 | 17 | Base58编码是从Base64编码演化而来,但是没有base64中的0,I,O,l,+,/等6个字符. 18 | 比特币中base58的字符集(有序)如下: 19 | "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" 20 | 21 | 从数和数制的角度来看,Base58可以看做为58进制. 22 | 类似的,base2即二进制,base10十进制,base16十六进制,base64六十四进制;当然,我们常用的7位ASCII码表即128进制/base128,扩展的8位ascii码表亦可看做256进制/base256. 23 | 24 | 从数和数制的角度来看,base58的编码和解码,是不同数制间的转换.整数的数制转换常用短除法,比特币源码中也是使用这种方法.(是时候翻一翻以前的课本或者百度百科了^_^) 25 | 26 | ## Base58编码解码函数 27 | 28 | 29 | [width="100%",options="header,footer"] 30 | |==================== 31 | | 函数名称 | 释义 32 | | std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) | 正常base58编码 33 | | std::string EncodeBase58(const std::vector& vch) | 正常base58编码 34 | | bool DecodeBase58(const char* psz, std::vector& vchRet) | 正常base58解码 35 | | bool DecodeBase58(const std::string& str, std::vector& vchRet) | 正常base58解码 36 | | std::string EncodeBase58Check(const std::vector& vchIn) | cell 37 | | bool DecodeBase58Check(const char* psz, std::vector& vchRet) | cell 38 | | bool DecodeBase58Check(const std::string& str, std::vector& vchRet)| 39 | |==================== 40 | 41 | 42 | ## CBase58Data类 43 | base58编码数据的基类 44 | 45 | ### 成员变量 46 | 47 | * nVersion,版本号 48 | * vchData,被base58编码的数据. 49 | 50 | ### 成员函数 51 | 52 | [width="100%",options="header,footer"] 53 | |==================== 54 | | 方法名 | 说明 55 | | SetData(int nVersionIn, const void* pdata, size_t nSize) | 设置vchData 56 | | SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend) | 设置vchData 57 | | SetString(const char* psz) | 设置vchData 58 | | SetString(const std::string& str) | 设置vchData 59 | | ToString() | 返回base58check编码的数据(vchData). 比特币地址用本方法生成 60 | | CompareTo(const CBase58Data& b58)|比较两个数据是否一样 61 | |==================== 62 | ## CBitcoinAddress比特币地址类 63 | CBitcoinAddress可以看做给定版本号的CBase58Data. 64 | base58编码的比特币地址有两种: 65 | 66 | [width="100%",options="header,footer"] 67 | |==================== 68 | | 名称| 版本号|生成方法 69 | | 公共密钥哈希地址 | 版本0(或111测试网络)|数据向量包含RIPEMD160(SHA256(pubkey)),其中pubkey是序列化的公钥 70 | | 脚本哈希地址 |具有版本5(或196 testnet) | 数据向量包含RIPEMD160(SHA256(cscript))其中cscript是序列化的兑换脚本. 71 | |==================== 72 | 73 | 74 | ## CBitcoinSecret Base58编码的私钥 75 | -------------------------------------------------------------------------------- /bignum.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析之大数类CBigNum 2 | followtheart 3 | :doctype: article 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :toc-title: 目录 8 | :numbered: 9 | 10 | ## 对山寨开发的重要性:五星 11 | 12 | 理解挖矿难度计算细节的基础 13 | 14 | ## 什么是大数? 15 | * 大数在日常生活中用不上,多用于科学计算,如素数分解。 16 | * 比特币中的大数表示主要通过CBigNum来实现。 17 | CBigNum类实现了对Openssl库中大数BIGNUM的封装. 18 | 19 | ## Compact 格式 20 | 21 | * “Compact”格式是一个256位数字的一种表示形式 22 | * 数字N使用类似于无符号32位数浮点格式 23 | * 最高有效8位是基数为256的无符号指数。 24 | * 该指数可以被认为是“N的有效字节数”.比如0x11的有效位数为8位,即有效字节数为1,则compact形式的最高八位应该是0x01,对应的compact形式为0x01000011 25 | * 较低的23位是尾数。 26 | * 位数24(0x800000)表示N的符号。 27 | * N =(-1 ^ sign)*尾数* 256 ^(指数-3) 28 | * Satoshi的原始实现使用BN_bn2mpi()和BN_mpi2bn()。 29 | * MPI使用第一个字节的最高有效位作为符号。 30 | * 因此0x1234560000的紧凑型式为(0x05123456)其中0x05123456,最高8位05表示整个数有效位数为5个字节,40位. 31 | * 0xc0de000000是紧凑的(0x0600c0de)注意紧凑形式的(0x05c0de00)将为-0x40de000000,24位表示符号 32 | * CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);如果认为有效位为256-32=224=28(0x1c个字节)*8,则取最高24位为尾数即ffffff(24位为符号位,不方便表示符号),如果认为有效位为256-24=232=29(0x1d个字节)*8,则取最高24位为尾数即00ffff,则compact形式为0x1d00ffff(比特币基因块的目标难度位) 33 | 34 | ### [0x20-0x1d(紧凑形式最高8位)]*8+2(尾数高位0字节个数)*4=32(右移尾数,计算出来hash值0的个最少个数) 35 | 36 | * 比特币只使用这种“Compact”格式来编码难度目标,无符号256位数量。 所以,所有的符号位的复杂度和使用256的大概可能是一个实施意外。 37 | 38 | ## CBigNum类 39 | 40 | [cols="1,2", options="header"] 41 | .CBigNum 42 | |=== 43 | | 函数/变量 | 描述 44 | 45 | |void setulong(unsigned long n) | 46 | |unsigned long getulong() const | 47 | |unsigned int getuint() const| 48 | |int getint() const| 将一个大数转换为int类型 49 | |void setint64(int64 sn)| 50 | |uint64 getuint64()| 51 | |void setuint64(uint64 n)| 52 | |void setuint256(uint256 n)| 53 | |uint256 getuint256()| 54 | |void setvch(const std::vector& vch)| 55 | |std::vector getvch() | 56 | |CBigNum& SetCompact(unsigned int nCompact)| 57 | |unsigned int GetCompact()| 58 | 59 | |void SetHex(const std::string& str) 60 | |将16进制字符串转换为大数 61 | 62 | |std::string ToString(int nBase=10) 63 | |将大数转换为数字字符串,nBase指定数字的进制数 64 | 65 | |std::string GetHex() 66 | |将大数转换为16进制字符串 67 | 68 | |unsigned int GetSerializeSize(int nType=0, int nVersion=PROTOCOL_VERSION)| 69 | |template void Serialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION)| 70 | |template void Unserialize(Stream& s, int nType=0, int nVersion=PROTOCOL_VERSION)| 71 | 72 | |=== 73 | -------------------------------------------------------------------------------- /bitcoinrpc.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析之通用RPC接口的实现 2 | followtheart 3 | :doctype: article 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | ## 对山寨开发的重要性:三星 10 | 11 | 二次开发的客户通常会问到rpc接口,自定义接口也需要用到 12 | 13 | ## HTTPStatusCode--HTTP状态码 14 | 15 | [width="100%",options="header,footer"] 16 | |==================== 17 | | 状态码 | 说明 18 | | HTTP_OK = 200| ... 19 | | HTTP_BAD_REQUEST = 400| ... 20 | | HTTP_UNAUTHORIZED = 401| ... 21 | | HTTP_FORBIDDEN = 403| ... 22 | | HTTP_NOT_FOUND = 404| ... 23 | | HTTP_INTERNAL_SERVER_ERROR = 500| ... 24 | |==================== 25 | 26 | 27 | 28 | ## RPCErrorCode--比特币RPC错误码 29 | 30 | ### Standard JSON-RPC 2.0 errors--标准RPC错误 31 | [width="100%",options="header,footer"] 32 | |==================== 33 | | 状态码 | 说明 34 | | RPC_INVALID_REQUEST = -32600| ... 35 | | RPC_METHOD_NOT_FOUND = -32601| ... 36 | | RPC_INVALID_PARAMS = -32602| ... 37 | | RPC_INTERNAL_ERROR = -32603| ... 38 | | RPC_PARSE_ERROR = -32700| ... 39 | |==================== 40 | 41 | 42 | ### General application defined errors---一般程序定义错误 43 | [width="100%",options="header,footer"] 44 | |==================== 45 | | 状态码 | 说明 46 | |RPC_MISC_ERROR = -1| std::exception thrown in command handling 47 | |RPC_FORBIDDEN_BY_SAFE_MODE = -2| Server is in safe mode, and command is not allowed in safe mode 48 | |RPC_TYPE_ERROR = -3| Unexpected type was passed as parameter 49 | |RPC_INVALID_ADDRESS_OR_KEY = -5| Invalid address or key 50 | |RPC_OUT_OF_MEMORY = -7| Ran out of memory during operation 51 | |RPC_INVALID_PARAMETER = -8| Invalid, missing or duplicate parameter 52 | |RPC_DATABASE_ERROR = -20| Database error 53 | |RPC_DESERIALIZATION_ERROR = -22| Error parsing or validating structure in raw format 54 | |==================== 55 | 56 | ### P2P client errors--P2P客户端错误 57 | [width="100%",options="header,footer"] 58 | |==================== 59 | | 状态码 | 说明 60 | |RPC_CLIENT_NOT_CONNECTED = -9| Bitcoin is not connected 61 | |RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10| Still downloading initial blocks 62 | |==================== 63 | 64 | ### Wallet errors--钱包错误 65 | [width="100%",options="header,footer"] 66 | |==================== 67 | | 状态码 | 说明 68 | |RPC_WALLET_ERROR = -4| Unspecified problem with wallet (key not found etc.) 69 | |RPC_WALLET_INSUFFICIENT_FUNDS = -6| Not enough funds in wallet or account 70 | |RPC_WALLET_INVALID_ACCOUNT_NAME = -11| Invalid account name 71 | |RPC_WALLET_KEYPOOL_RAN_OUT = -12| Keypool ran out, call keypoolrefill first 72 | |RPC_WALLET_UNLOCK_NEEDED = -13| Enter the wallet passphrase with walletpassphrase first 73 | |RPC_WALLET_PASSPHRASE_INCORRECT = -14| The wallet passphrase entered was incorrect 74 | |RPC_WALLET_WRONG_ENC_STATE = -15| Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.) 75 | |RPC_WALLET_ENCRYPTION_FAILED = -16| Failed to encrypt the wallet 76 | |RPC_WALLET_ALREADY_UNLOCKED = -17| Wallet is already unlocked 77 | |==================== 78 | 79 | 80 | 81 | ## 重要函数 82 | 83 | [width="100%",options="header,footer"] 84 | |==================== 85 | | 函数名 | 说明 86 | | void StartRPCThreads();| 87 | | void StopRPCThreads();| 88 | | int CommandLineRPC(int argc, char *argv[]);| 89 | | json_spirit::Array RPCConvertValues(const std::string &strMethod, const std::vector &strParams);| Convert parameter values for RPC call from strings to command-specific JSON objects 90 | | void RPCTypeCheck(const json_spirit::Array& params, 91 | const std::list& typesExpected, bool fAllowNull=false);| 92 | Type-check arguments; throws JSONRPCError if wrong type given. Does not check that 93 | the right number of arguments are passed, just that any passed are the correct type. 94 | Use like: RPCTypeCheck(params, boost::assign::list_of(str_type)(int_type)(obj_type)); 95 | | void RPCTypeCheck(const json_spirit::Object& o, 96 | const std::map& typesExpected, bool fAllowNull=false);| Check for expected keys/value types in an Object. 97 | Use like: RPCTypeCheck(object, boost::assign::map_list_of("name", str_type)("value", int_type)); 98 | | typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool fHelp); 99 | |==================== 100 | 101 | ## CRPCCommand--RPC命令 102 | RPC命令 103 | 104 | ### 成员变量 105 | 106 | * std::string name; 107 | * rpcfn_type actor; 108 | * bool okSafeMode; 109 | * bool threadSafe; 110 | -------------------------------------------------------------------------------- /bloom.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析之布隆过滤器 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | * Bloom filter是由Howard Bloom在1970年提出的二进制向量数据结构,用来检测一个元素是不是集合中的一个成员。 10 | 如果检测结果为是,该元素不一定在集合中;但如果检测结果为否,该元素一定不在集合中 11 | * Bloom filter是为SPV客户端提供的概率过滤器,以便可以过滤我们发送的交易。这可以显着提高交易和块下载的效率。 12 | * 因为布隆过滤器是概率性的,所以SPV节点可以增加假阳性率,使我们向他们发送实际上并不是他们自己的交易,允许客户通过混淆他们拥有的密钥来交易更多带宽以获得更多隐私。 13 | 14 | 15 | ## 对山寨开发的重要性:一星 16 | 17 | 基本上没有客户会问到这个 18 | 19 | ## CBloomFilter类--布隆过滤器 20 | 21 | 22 | ### 成员变量 23 | * vData 24 | * isFull 25 | * isEmpty 26 | * nHashFuncs 27 | * nTweak 28 | * nFlags 29 | 30 | ### 成员函数 31 | 32 | [width="100%",options="header,footer"] 33 | |==================== 34 | | 方法名 | 说明 35 | | CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweak, unsigned char nFlagsIn)| 创建一个新的布隆过滤器,它将在填充给定数量的元素时提供给定的fp速率 36 | 请注意,如果给定的参数将导致超出协议限制范围的过滤器,则创建的过滤器将在协议限制范围内尽可能接近给定参数。 37 | 如果nFPRate非常低或nElements不合理地高,这将适用。 38 | nTweak是一个添加到传递给散列函数的种子值的常量 39 | 它通常应该是一个随机值(并且主要仅用于单元测试) 40 | nFlags应该是BLOOM_UPDATE_ *枚举之一(不是_MASK) 41 | | CBloomFilter() : isFull(true) {}|... 42 | | void insert(const std::vector& vKey);|... 43 | | void insert(const COutPoint& outpoint);|... 44 | | void insert(const uint256& hash);|... 45 | 46 | | bool contains(const std::vector& vKey) const;|... 47 | | bool contains(const COutPoint& outpoint) const;|... 48 | | bool contains(const uint256& hash) const;|... 49 | 50 | | bool IsWithinSizeConstraints() const;|True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash functions is <= MAX_HASH_FUNCS 51 | // (catch a filter which was just deserialized which was too big) 52 | 53 | | bool IsRelevantAndUpdate(const CTransaction& tx, const uint256& hash);| 54 | 55 | | void UpdateEmptyFull();| 检查空的和满的过滤器,以避免浪费cpu 56 | 57 | |==================== 58 | -------------------------------------------------------------------------------- /book.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | ## 山寨开发关注度:五星 10 | 11 | 基本上每个客户都会要求修改钱包地址首字母 12 | 13 | ## CBase58Data类 14 | base58编码数据的基类 15 | 16 | ### 成员变量 17 | 18 | * nVersion,版本号 19 | * vchData,被base58编码的数据. 20 | 21 | ### 成员函数 22 | 23 | [width="100%",options="header,footer"] 24 | |==================== 25 | | 方法名 | 说明 26 | |*****|***** 27 | |==================== 28 | -------------------------------------------------------------------------------- /checkpoints.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | Checkpoint将在编译完成后进行区块链完整性检查。 10 | 它们每更新一次或三次更新。 11 | 12 | ## 对山寨开发的重要性:五星 13 | 14 | 必须修改,否则钱包无法正确运行 15 | 16 | ## 几个函数 17 | 18 | [width="100%",options="header,footer"] 19 | |==================== 20 | | 方法名 | 说明 21 | | bool CheckBlock(int nHeight, const uint256& hash);|Returns true if block passes checkpoint checks 22 | | int GetTotalBlocksEstimate()|Return conservative estimate of total number of blocks, 0 if unknown 23 | | CBlockIndex* GetLastCheckpoint(const std::map& mapBlockIndex); | // Returns last CBlockIndex* in mapBlockIndex that is a checkpoint | 24 | | double GuessVerificationProgress(CBlockIndex *pindex);|...| 25 | |==================== 26 | -------------------------------------------------------------------------------- /checkqueue.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | ## 对山寨开发的重要性:五星 10 | 11 | 基本上每个客户都会要求修改钱包地址首字母 12 | 13 | ## CBase58Data类 14 | base58编码数据的基类 15 | 16 | ### 成员变量 17 | 18 | * nVersion,版本号 19 | * vchData,被base58编码的数据. 20 | 21 | ### 成员函数 22 | 23 | [width="100%",options="header,footer"] 24 | |==================== 25 | | 方法名 | 说明 26 | |*****|***** 27 | |==================== 28 | -------------------------------------------------------------------------------- /clientversion.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析之客户端版本信息 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | ## 对山寨开发的重要性:二星 10 | 11 | 大部分客户都会要求修改版本信息 12 | 13 | ## CBase58Data 14 | 15 | ## 版本号 16 | 17 | [width="100%",options="header,footer"] 18 | |==================== 19 | | 方法名 | 说明 20 | | #define CLIENT_VERSION_MAJOR 0|... 21 | | #define CLIENT_VERSION_MINOR 8|... 22 | | #define CLIENT_VERSION_REVISION 6|... 23 | | #define CLIENT_VERSION_BUILD 0|... 24 | | #define COPYRIGHT_YEAR 2013| 版权截至年份 | 25 | |==================== 26 | -------------------------------------------------------------------------------- /compact.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 为跨平台定义了一些宏,封装了closesocket 10 | 11 | ## 山寨开发关注度:零星 12 | 13 | 从来没人问及此处 14 | 15 | 16 | ## myclosesocket函数 17 | 实现了一个跨平台的closesocket函数 18 | -------------------------------------------------------------------------------- /crypter.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析之钱包加密 2 | thelastwolf 3 | :doctype: article 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 钱包加密核心内容主要在crypter.h和crypter.cpp中实现 10 | 11 | 从密码学的角度,每个比特币地址都有对应的一个私钥。从私钥可以推导出公钥,得到地址。 12 | 私钥代表了地址的所有权,钱包的加密实际上是对私钥的加密。 13 | 14 | 钱包私钥加密使用aes-256-cbc算法, 15 | aes-256-cbc需要2个参数,IV和key,其中: 16 | IV:使用私钥对应公钥经过双重sha256生成 17 | Key:使用CMasterKey中的Key。 18 | 19 | CMasterKey中的key是随机产生的(wallet.cpp h231), 20 | 使用我们输入的密码加密后写入文件 21 | 22 | 存储到文件中是加密后的key,即vchCryptedKey, 23 | 24 | CMasterKey中的key也使用aes-256-cbc加密, 25 | 加密所使用的参数(IV和key),是从我们输入的密码, 26 | 以及CMasterKey中nDerivationMethod,nDeriveIterations,salt等参数推导出来的 27 | 28 | 29 | 30 | 简要的说: 31 | 1. 随机生成一个秘钥MasterKey,作为参数用于加密钱包私钥WalletPriKey 32 | 2. 输入一个密码Pass,用于加密MasterKey 33 | 3. 输入的Pass不是直接加密MasterKey,而是用来获取加密Masterkey所需的参数 34 | 4. 加密后的MasterKey和加密后的钱包私钥都会写入钱包文件 -------------------------------------------------------------------------------- /db.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析之数据库操作 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 实现了对berkleydb的封装 10 | 11 | ## 山寨开发关注度:零星 12 | 13 | 相对底层的东西 , 客户从没提起过 14 | 15 | ## 全局函数 16 | 17 | [width="100%",options="header,footer"] 18 | |==================== 19 | | 方法名 | 说明 20 | |void ThreadFlushWalletDB(const std::string& strWalletFile);|... 21 | |bool BackupWallet(const CWallet& wallet, const std::string& strDest);|钱包备份 22 | |==================== 23 | 24 | ## CDBEnv类--berkleydb上下文 25 | 封装了一个berkleydb的上下文环境DbEnv类以及相关操作 26 | 27 | ### 成员变量 28 | * fDbEnvInit; 29 | * fMockDb; 30 | * path; 31 | * cs_db; 32 | * dbenv,数据库环境,berkleydb的DbEnv 数据库环境 33 | * mapFileUseCount; 34 | * mapDb; 35 | 36 | ### 成员函数 37 | 38 | [width="100%",options="header,footer"] 39 | |==================== 40 | | 方法名 | 说明 41 | | void EnvShutdown();|关闭数据库环境 42 | | void MakeMock();| 43 | | bool IsMock() | 44 | | VerifyResult Verify(std::string strFile, bool (*recoverFunc)(CDBEnv& dbenv, std::string strFile)); | 45 | | bool Salvage(std::string strFile, bool fAggressive, std::vector& vResult); | 46 | 从没有通过verify的文件中提取数据 47 | | bool Open(const boost::filesystem::path &path);|... 48 | | void Close();|... 49 | | void Flush(bool fShutdown);|... 50 | | void CheckpointLSN(std::string strFile);|... 51 | | void CloseDb(const std::string& strFile);|... 52 | | bool RemoveDb(const std::string& strFile);|... 53 | | DbTxn *TxnBegin(int flags=DB_TXN_WRITE_NOSYNC)|... 54 | |==================== 55 | 56 | ## CDB 类--berkleydb的RAII封装 57 | 58 | ### 成员变量 59 | * pdb; 60 | * std::string strFile; 61 | * DbTxn *activeTxn; 62 | * bool fReadOnly; 63 | 64 | ### 成员函数 65 | [width="100%",options="header,footer"] 66 | |==================== 67 | | 方法名 | 说明 68 | | explicit CDB(const char* pszFile, const char* pszMode="r+");|... 69 | | void Flush();|... 70 | | void Close();|... 71 | | bool Read(const K& key, T& value) |读 72 | | bool Write(const K& key, const T& value, bool fOverwrite=true) | 写 73 | | bool Erase(const K& key) | 擦除 74 | | bool Exists(const K& key) | 是否存在 75 | | Dbc* GetCursor() | 获取光标 76 | | int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT) | 77 | | bool TxnBegin() | 78 | | bool TxnCommit() | 79 | | bool TxnAbort() | 80 | | bool ReadVersion(int& nVersion) | 81 | | bool WriteVersion(int nVersion) | 82 | | bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL); | 83 | |==================== 84 | -------------------------------------------------------------------------------- /hash.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析 之HASH函数 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | ## 山寨开发关注度:五星 10 | 11 | 使用什么hash函数关系到币的种类,是客户最关心的问题之一 12 | 13 | ## 全局函数 14 | 15 | 16 | [width="100%",options="header,footer"] 17 | |==================== 18 | | 方法名 | 说明 19 | |inline uint256 Hash(const T1 pbegin, const T1 pend)|sha256 20 | |uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION) |Hash序列化 21 | |inline uint160 Hash160(const std::vector& vch) |RIPEMD160(Hash256(text)) 22 | |unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector& vDataToHash); | MurmurHash3 23 | |==================== 24 | -------------------------------------------------------------------------------- /images/Q.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/followtheart/bitcoin-notes/1191ebafaa4bc862647de8d3e387711eca8ece58/images/Q.jpg -------------------------------------------------------------------------------- /init.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 定义了一些函数 10 | 11 | ## 山寨开发关注度:1星 12 | 13 | 几乎无人过问此处 14 | 15 | ## 全局函数 16 | 17 | [width="100%",options="header,footer"] 18 | |==================== 19 | | 方法名 | 说明 20 | | void StartShutdown();| 21 | | bool ShutdownRequested();| 22 | | void Shutdown();| 23 | | bool AppInit2(boost::thread_group& threadGroup);| 主程序流程入口,main()->appinit()->AppInit2() 24 | | std::string HelpMessage();| 显示UI和守护进程之间共享的的选项 25 | |==================== 26 | -------------------------------------------------------------------------------- /key.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析之秘钥 2 | followtheart 3 | :doctype: article 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 10 | 这里的秘钥是指椭圆加密算法的秘钥. 11 | (椭圆曲线加密算法类似于RSA,是非对称加密的一种,也是比特币地址使用的算法) 12 | 秘钥包含公钥和私钥.私钥可以推出公钥,公钥不能推出私钥. 13 | 14 | 在比特币钱包中,我们最常见的34字符钱包地址(如:1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX), 15 | 就是秘钥(CKey)的公钥(CPubKey)的引用(CKeyID),经过base58编码得到的. 16 | 17 | 18 | 19 | key.h和key.cpp主要实现了秘钥相关类:CKey,CKeyID,CPubKey. 20 | 21 | 22 | == CKey 秘钥类 23 | 秘钥主要实现在CKey类。 24 | CKey类包含了对OpenSSL的椭圆曲线秘钥EC_KEY的封装,以及一些签名和校验等操作. 25 | 26 | 27 | .CKey 类变量 28 | [width="100%",options="header,footer"] 29 | |==================== 30 | | 重要变量 | 解释 31 | | EC_KEY *pkey | CKey类的主要数据是pKey 32 | | fSet | 只要设置了公钥或者私钥,fSet都会设置为true.当然私钥可以推导出公钥. 33 | | fCompressedPubKey | 公钥是否被压缩 34 | |==================== 35 | 36 | 37 | 38 | .CKey 主要方法 39 | |==================== 40 | | 方法名称 |解释 41 | | void MakeNewKey(bool fCompressed) | 随机产生新的秘钥.参数fCompressed 是否压缩公钥 42 | | bool SetPrivKey(const CPrivKey& vchPrivKey) | 设置私钥为参数给定私钥 43 | | bool SetSecret(const CSecret& vchSecret, bool fCompressed = false) | 根据参数vchSecret生成秘钥, 44 | 45 | 类似于脑钱包的功能 46 | 47 | | CSecret GetSecret(bool &fCompressed) const | 获取私钥对应的参数 48 | | CPrivKey GetPrivKey() const | 获取私钥 49 | | bool SetPubKey(const CPubKey& vchPubKey)| 设置公钥 50 | | CPubKey GetPubKey() const|获取公钥 51 | |bool Sign(uint256 hash, std::vector& vchSig)|对hash进行ECDSA签名,结果为vchSig 52 | | bool SignCompact(uint256 hash, std::vector& vchSig)|紧缩签名,相对于上面的签名,改签名可以重建所使用的公钥 53 | |bool SetCompactSignature(uint256 hash, const std::vector& vchSig)|从紧缩签名重建公钥 54 | |bool Verify(uint256 hash, const std::vector& vchSig)|验证签名 55 | |bool VerifyCompact(uint256 hash, const std::vector& vchSig)|验证紧缩签名 56 | |==================== 57 | 58 | 59 | 60 | == CPubKey 公钥类 61 | CPubKey实现了对公钥的封装 62 | 63 | 64 | == CKeyID类 65 | CKeyID是对CKey类的引用 66 | 具体实现是: 67 | 首先,序列化CKey的公钥; 68 | 然后,用HASH160计算一次散列值作为CKeyID 69 | 70 | == CScriptID 71 | 类似于CKeyID. 72 | CKey是钱包地址的一种,CScript是地址的另一种. 73 | todo .... -------------------------------------------------------------------------------- /keystore.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析之(钱包地址对应)密钥存储 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 实现了钱包地址对应私钥(包括加密和不加密)存储 10 | 11 | ## 山寨开发关注度:三星 12 | 13 | 一般不会有客户要求定制此处 14 | 15 | ## CKeyStore类 16 | 密钥存储的虚拟基类 17 | 18 | ### 成员变量 19 | 20 | * cs_KeyStore 21 | 22 | ### 成员函数 23 | 24 | [width="100%",options="header,footer"] 25 | |==================== 26 | | 方法名 | 说明 27 | | virtual bool AddKey(const CKey& key) =0;|// Add a key to the store. 28 | | virtual bool HaveKey(const CKeyID &address) const =0;| // Check whether a key corresponding to a given address is present in the store. 29 | | virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0;|.. 30 | | virtual void GetKeys(std::set &setAddress) const =0;|... 31 | | virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;|... 32 | | virtual bool AddCScript(const CScript& redeemScript) =0;| Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013 33 | | virtual bool HaveCScript(const CScriptID &hash) const =0;|... 34 | | virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const =0;|... 35 | | virtual bool GetSecret(const CKeyID &address, CSecret& vchSecret, bool &fCompressed) const|... 36 | |==================== 37 | 38 | ## CBasicKeyStore 类-- 基础(未加密)密钥存储类 39 | 40 | 基本密钥存储, 使用 地址->私钥映射 的形式 41 | 42 | ### 成员变量 43 | * KeyMap mapKeys; 44 | * ScriptMap mapScripts; 45 | 46 | ### 成员函数 47 | 48 | [width="100%",options="header,footer"] 49 | |==================== 50 | | 方法名 | 说明 51 | | virtual bool AddKey(const CKey& key) =0;|// Add a key to the store. 52 | | virtual bool HaveKey(const CKeyID &address) const =0;| // Check whether a key corresponding to a given address is present in the store. 53 | | virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0;|.. 54 | | virtual void GetKeys(std::set &setAddress) const =0;|... 55 | | virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;|... 56 | | virtual bool AddCScript(const CScript& redeemScript) =0;| Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013 57 | | virtual bool HaveCScript(const CScriptID &hash) const =0;|... 58 | | virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const =0;|... 59 | | virtual bool GetSecret(const CKeyID &address, CSecret& vchSecret, bool &fCompressed) const|... 60 | |==================== 61 | 62 | ## CCryptoKeyStore -- 加密密钥存储类 63 | 64 | 存储加密的地址密钥,如果加密未被激活,则和CBasicKeyStore一样 65 | 66 | ### 成员变量 67 | 68 | * CryptedKeyMap mapCryptedKeys; 69 | * CKeyingMaterial vMasterKey; 70 | * bool fUseCrypto;// if fUseCrypto is true, mapKeys must be empty . 71 | if fUseCrypto is false, vMasterKey must be empty 72 | 73 | ### 成员函数 74 | 75 | [width="100%",options="header,footer"] 76 | |==================== 77 | | 方法名 | 说明 78 | | bool SetCrypted();|... 79 | | bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);| // will encrypt previously unencrypted keys 80 | | bool Unlock(const CKeyingMaterial& vMasterKeyIn);| 81 | | bool IsCrypted() const |... 82 | | bool IsLocked() const | ... 83 | | bool Lock() | 84 | | virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret); | 85 | 86 | | virtual bool AddKey(const CKey& key) =0;|// Add a key to the store. 87 | | virtual bool HaveKey(const CKeyID &address) const =0;| // Check whether a key corresponding to a given address is present in the store. 88 | | virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0;|.. 89 | | virtual void GetKeys(std::set &setAddress) const =0;|... 90 | | virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;|... 91 | | virtual bool AddCScript(const CScript& redeemScript) =0;| Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013 92 | | virtual bool HaveCScript(const CScriptID &hash) const =0;|... 93 | | virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const =0;|... 94 | | virtual bool GetSecret(const CKeyID &address, CSecret& vchSecret, bool &fCompressed) const|... 95 | |==================== 96 | -------------------------------------------------------------------------------- /leveldb.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析之leveldb 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 实现了对leveldb的封装 10 | 11 | ## 山寨开发关注度:五星 12 | 基本上每个客户都会要求修改钱包地址首字母 13 | 14 | ## CLevelDBBatch类 15 | 批量排队写入CLevelDB的更改 16 | 17 | ### 成员变量 18 | 19 | * batch 20 | 21 | ### 成员函数 22 | 23 | [width="100%",options="header,footer"] 24 | |==================== 25 | | 方法名 | 说明 26 | | template void Write(const K& key, const V& value)| 写入 27 | | template void Erase(const K& key) | 擦除 28 | |==================== 29 | 30 | ## CLevelDB类 31 | CLevelDB 32 | 33 | ### 成员变量 34 | 35 | * leveldb::Env *penv;此数据库正在使用的自定义环境(在默认环境下可能为NULL) 36 | 37 | * leveldb::Options options;//使用的数据库选项 38 | 39 | * leveldb::ReadOptions readoptions;//从数据库读取时使用的选项 40 | 41 | * leveldb::ReadOptions iteroptions;//遍历数据库值时使用的选项 42 | 43 | * leveldb::WriteOptions writeoptions;//写入数据库时使用的选项 44 | 45 | * leveldb::WriteOptions syncoptions;//同步写入数据库时使用的选项 46 | 47 | * leveldb::DB *pdb;//数据库本身 48 | 49 | ### 成员函数 50 | 51 | [width="100%",options="header,footer"] 52 | |==================== 53 | | 方法名 | 说明 54 | | template bool Read(const K& key, V& value)| 55 | | template bool Write(const K& key, const V& value, bool fSync = false)| 56 | | template bool Exists(const K& key) | 57 | | template bool Erase(const K& key, bool fSync = false) | 58 | | bool WriteBatch(CLevelDBBatch &batch, bool fSync = false) | 59 | | bool Flush() |//不可用于LevelDB; 提供与BDB的兼容性 60 | | bool Sync() | 61 | | leveldb::Iterator *NewIterator() | 不完全干净的封装,但它现在是最简单的 62 | |==================== 63 | -------------------------------------------------------------------------------- /limitedmap.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析之limitedmap 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 类似STL的映射容器只保留具有最高值的N个元素。 10 | 11 | ## 山寨开发关注度:1星 12 | 一般不会有客户要求定制此处 13 | 14 | ## limitedmap 15 | 类似STL的映射容器只保留具有最高值的N个元素。 16 | 17 | ### 成员变量 18 | 19 | * key_type; 20 | * mapped_type; 21 | * value_type; 22 | * const_iterator; 23 | * size_type; 24 | 25 | ### 成员函数 26 | 27 | [width="100%",options="header,footer"] 28 | |==================== 29 | | 方法名 | 说明 30 | | limitedmap(size_type nMaxSizeIn = 0)| 31 | | const_iterator begin()| 32 | | const_iterator end() | 33 | | size_type size() | 34 | | bool empty() | 35 | | const_iterator find(const key_type& k) | 36 | | size_type count(const key_type& k) | 37 | | void insert(const value_type& x) | 38 | | void erase(const key_type& k) | 39 | | void update(const_iterator itIn, const mapped_type& v) | 40 | | size_type max_size() | 41 | | size_type max_size(size_type s) | 42 | |==================== 43 | -------------------------------------------------------------------------------- /main.h.adoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/followtheart/bitcoin-notes/1191ebafaa4bc862647de8d3e387711eca8ece58/main.h.adoc -------------------------------------------------------------------------------- /mruset.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析之mruset 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 类似STL的集合容器只保留最近的N个元素。 10 | 11 | ## 山寨开发关注度:1星 12 | 一般不会有客户要求定制此处 13 | 14 | ## limitedmap 15 | 类似STL的映射容器只保留最近的N个元素。 16 | 17 | ### 成员变量 18 | 19 | * key_type; 20 | * mapped_type; 21 | * value_type; 22 | * const_iterator; 23 | * size_type; 24 | 25 | ### 成员函数 26 | 27 | [width="100%",options="header,footer"] 28 | |==================== 29 | | 方法名 | 说明 30 | | mruset(size_type nMaxSizeIn = 0)| 31 | | const_iterator begin()| 32 | | const_iterator end() | 33 | | size_type size() | 34 | | bool empty() | 35 | | const_iterator find(const key_type& k) | 36 | | size_type count(const key_type& k) | 37 | | void insert(const value_type& x) | 38 | | size_type max_size() | 39 | | size_type max_size(size_type s) | 40 | |==================== 41 | -------------------------------------------------------------------------------- /net.h.adoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/followtheart/bitcoin-notes/1191ebafaa4bc862647de8d3e387711eca8ece58/net.h.adoc -------------------------------------------------------------------------------- /netbase.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 基础网络功能 10 | 11 | ## 山寨开发关注度:1星 12 | 13 | 基本上每个客户都会要求修改钱包地址首字母 14 | 15 | ## 全局函数 16 | 17 | [width="100%",options="header,footer"] 18 | |==================== 19 | | 方法名 | 说明 20 | | enum Network ParseNetwork(std::string net);|... 21 | | void SplitHostPort(std::string in, int &portOut, std::string &hostOut);|... 22 | | bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion = 5);|... 23 | | bool GetProxy(enum Network net, proxyType &proxyInfoOut);|... 24 | | bool IsProxy(const CNetAddr &addr);|... 25 | | bool SetNameProxy(CService addrProxy, int nSocksVersion = 5);|... 26 | | bool HaveNameProxy();|... 27 | | bool LookupHost(const char *pszName, std::vector& vIP, unsigned int nMaxSolutions = 0, bool fAllowLookup = true);|... 28 | | bool LookupHostNumeric(const char *pszName, std::vector& vIP, unsigned int nMaxSolutions = 0);|... 29 | | bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true);|... 30 | | bool Lookup(const char *pszName, std::vector& vAddr, int portDefault = 0, bool fAllowLookup = true, unsigned int nMaxSolutions = 0);|... 31 | | bool LookupNumeric(const char *pszName, CService& addr, int portDefault = 0);|... 32 | | bool ConnectSocket(const CService &addr, SOCKET& hSocketRet, int nTimeout = nConnectTimeout);|... 33 | | bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest, int portDefault = 0, int nTimeout = nConnectTimeout);|... 34 | |==================== 35 | 36 | ## CNetAddr类 37 | IP地址 (使用映射IPv6范围( FFFF:0:0/96)的IPv6或IPv4)) 38 | 39 | ### 成员变量 40 | 41 | * unsigned char ip[16] 42 | 43 | ### 成员函数 44 | 45 | [width="100%",options="header,footer"] 46 | |==================== 47 | | 方法名 | 说明 48 | | CNetAddr();| 49 | | CNetAddr(const struct in_addr& ipv4Addr);| 50 | | explicit CNetAddr(const char *pszIp, bool fAllowLookup = false);| 51 | | explicit CNetAddr(const std::string &strIp, bool fAllowLookup = false);| 52 | | void Init();| 53 | | void SetIP(const CNetAddr& ip);| 54 | | bool SetSpecial(const std::string &strName); // for Tor addresses| 55 | | bool IsIPv4() const; | // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0) 56 | | bool IsIPv6() const; | // IPv6 address (not mapped IPv4, not Tor) 57 | | bool IsRFC1918() const; | // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12) 58 | | bool IsRFC3849() const; | // IPv6 documentation address (2001:0DB8::/32) 59 | | bool IsRFC3927() const; | // IPv4 autoconfig (169.254.0.0/16) 60 | | bool IsRFC3964() const; | // IPv6 6to4 tunnelling (2002::/16) 61 | | bool IsRFC4193() const; | // IPv6 unique local (FC00::/15) 62 | | bool IsRFC4380() const; | // IPv6 Teredo tunnelling (2001::/32) 63 | | bool IsRFC4843() const; | // IPv6 ORCHID (2001:10::/28) 64 | | bool IsRFC4862() const; | // IPv6 autoconfig (FE80::/64) 65 | | bool IsRFC6052() const; | // IPv6 well-known prefix (64:FF9B::/96) 66 | | bool IsRFC6145() const; | // IPv6 IPv4-translated address (::FFFF:0:0:0/96) 67 | | bool IsTor() const;| 68 | | bool IsLocal() const;| 69 | | bool IsRoutable() const;| 70 | | bool IsValid() const;| 71 | | bool IsMulticast() const;| 72 | | enum Network GetNetwork() const;| 73 | | std::string ToString() const;| 74 | | std::string ToStringIP() const;| 75 | | unsigned int GetByte(int n) const;| 76 | | uint64 GetHash() const;| 77 | | bool GetInAddr(struct in_addr* pipv4Addr) const;| 78 | | std::vector GetGroup() const;| 79 | | int GetReachabilityFrom(const CNetAddr *paddrPartner = NULL) const;| 80 | | void print() const;| 81 | |==================== 82 | 83 | ## CService类 84 | 网络地址(CNetAddr)和(TCP)端口的组合 85 | 86 | ### 成员变量 87 | 88 | * unsigned short port; // 主机端口 89 | 90 | ### 成员函数 91 | 92 | [width="100%",options="header,footer"] 93 | |==================== 94 | | 方法名 | 说明 95 | | CService();| 96 | | CService(const CNetAddr& ip, unsigned short port);| 97 | | CService(const struct in_addr& ipv4Addr, unsigned short port);| 98 | | CService(const struct sockaddr_in& addr);| 99 | | explicit CService(const char *pszIpPort, int portDefault, bool fAllowLookup = false);| 100 | | explicit CService(const char *pszIpPort, bool fAllowLookup = false);| 101 | | explicit CService(const std::string& strIpPort, int portDefault, bool fAllowLookup = false);| 102 | | explicit CService(const std::string& strIpPort, bool fAllowLookup = false);| 103 | | void Init();| 104 | | void SetPort(unsigned short portIn);| 105 | | unsigned short GetPort() const;| 106 | | bool GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const;| 107 | | bool SetSockAddr(const struct sockaddr* paddr);| 108 | | friend bool operator==(const CService& a, const CService& b);| 109 | | friend bool operator!=(const CService& a, const CService& b);| 110 | | friend bool operator<(const CService& a, const CService& b);| 111 | | std::vector GetKey() const;| 112 | | std::string ToString() const;| 113 | | std::string ToStringPort() const;| 114 | | std::string ToStringIPPort() const;| 115 | | void print() const;| 116 | |==================== 117 | -------------------------------------------------------------------------------- /preface.adoc: -------------------------------------------------------------------------------- 1 | = 前言 2 | followtheart 3 | :doctype: article 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 10 | * 本文档的阅读对象是有一定编程基础的技术人员 11 | * 希望实现的目标是帮助读者快速了解比特币整套系统技术上是如何实现的 12 | * 主要分析头文件以及重要的cpp文件 13 | * 重点是比特币整套系统如何协作,编程tips不是本文档的目标 -------------------------------------------------------------------------------- /protocol.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | ## 山寨开发关注度:五星 10 | 11 | 基本上每个客户都会要求修改钱包地址首字母 12 | 13 | ## 全局函数 14 | 15 | [width="100%",options="header,footer"] 16 | |==================== 17 | | 方法名 | 说明 18 | |static inline unsigned short GetDefaultPort(const bool testnet = fTestNet)| 19 | |==================== 20 | 21 | 22 | ## CMessageHeader类 23 | base58编码数据的基类 24 | 25 | ### 成员变量 26 | 27 | * pchMessageStart[MESSAGE_START_SIZE]; (4) message start. 28 | * pchCommand[COMMAND_SIZE]; (12) command. 29 | * nMessageSize; (4) size. 30 | * nChecksum; (4) checksum. 31 | 32 | ### 成员函数 33 | 34 | [width="100%",options="header,footer"] 35 | |==================== 36 | | 方法名 | 说明 37 | | CMessageHeader();| 38 | | CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn);| 39 | | std::string GetCommand() const;| 40 | | bool IsValid() const;| 41 | |==================== 42 | 43 | ## CAddress类 44 | CService 附带作为peer的相关信息 45 | 46 | ### 成员变量 47 | 48 | * nServices; 49 | * unsigned int nTime;//disk and network only 50 | * int64 nLastTry;// memory only 51 | 52 | ### 成员函数 53 | 54 | [width="100%",options="header,footer"] 55 | |==================== 56 | | 方法名 | 说明 57 | | CAddress();|... 58 | | explicit CAddress(CService ipIn, uint64 nServicesIn=NODE_NETWORK);|... 59 | | void Init();|... 60 | | void print() const;|... 61 | |==================== 62 | 63 | ## CInv类 64 | inv message data 65 | 66 | ### 成员变量 67 | 68 | * int type; 69 | * uint256 hash; 70 | 71 | ### 成员函数 72 | 73 | [width="100%",options="header,footer"] 74 | |==================== 75 | | 方法名 | 说明 76 | | bool IsKnownType() const;| 77 | | const char* GetCommand() const;| 78 | | std::string ToString() const;| 79 | | void print() const;| 80 | |==================== 81 | -------------------------------------------------------------------------------- /script.h.adoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/followtheart/bitcoin-notes/1191ebafaa4bc862647de8d3e387711eca8ece58/script.h.adoc -------------------------------------------------------------------------------- /serialize.h.adoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/followtheart/bitcoin-notes/1191ebafaa4bc862647de8d3e387711eca8ece58/serialize.h.adoc -------------------------------------------------------------------------------- /source-structure.adoc: -------------------------------------------------------------------------------- 1 | = 源码目录 2 | Author Name 3 | :doctype: article 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 10 | -------------------------------------------------------------------------------- /sync.h.adoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/followtheart/bitcoin-notes/1191ebafaa4bc862647de8d3e387711eca8ece58/sync.h.adoc -------------------------------------------------------------------------------- /threadsafety.h.adoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/followtheart/bitcoin-notes/1191ebafaa4bc862647de8d3e387711eca8ece58/threadsafety.h.adoc -------------------------------------------------------------------------------- /txdb.h.adoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/followtheart/bitcoin-notes/1191ebafaa4bc862647de8d3e387711eca8ece58/txdb.h.adoc -------------------------------------------------------------------------------- /ui_interface.h.adoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/followtheart/bitcoin-notes/1191ebafaa4bc862647de8d3e387711eca8ece58/ui_interface.h.adoc -------------------------------------------------------------------------------- /uint256.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析之uint256 2 | followtheart 3 | :doctype: article 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | uint256即无符号256位整数 10 | -------------------------------------------------------------------------------- /util.h.adoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/followtheart/bitcoin-notes/1191ebafaa4bc862647de8d3e387711eca8ece58/util.h.adoc -------------------------------------------------------------------------------- /version.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 定义了各种客户端版本相关信息 10 | 11 | ## 山寨开发关注度:五星 12 | 13 | 基本上每个客户都会要求修改钱包地址首字母 14 | 15 | ## 全局变量 16 | 17 | [width="100%",options="header,footer"] 18 | |==================== 19 | | 方法名 | 说明 20 | | CLIENT_VERSION | 客户端版本, 21 | + 1000000 * CLIENT_VERSION_MAJOR 22 | + 10000 * CLIENT_VERSION_MINOR 23 | + 100 * CLIENT_VERSION_REVISION 24 | + 1 * CLIENT_VERSION_BUILD;|... 25 | | CLIENT_NAME |... 26 | | CLIENT_BUILD |... 27 | | CLIENT_DATE |... 28 | | PROTOCOL_VERSION | 网络协议版本 29 | | MIN_PROTO_VERSION = 209 |从2012年2月起,不支持早期版本,并断开连接 30 | | CADDR_TIME_VERSION = 31402 | nTime字段添加到CAddress,从此版本开始;如果可能的话,避免请求比此更早的地址节点 31 | | NOBLKS_VERSION_START = 32000| 仅请求来自此范围之外的节点的块 32 | | NOBLKS_VERSION_END = 32400| 仅请求来自此范围之外的节点的块 33 | | BIP0031_VERSION = 60000;|// BIP 0031,pong消息,在此之后的所有版本中都已启用 34 | | MEMPOOL_GD_VERSION = 60002;|//“mempool”命令,增强的“getdata”行为从此版本开始: 35 | |==================== 36 | -------------------------------------------------------------------------------- /wallet.h.adoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/followtheart/bitcoin-notes/1191ebafaa4bc862647de8d3e387711eca8ece58/wallet.h.adoc -------------------------------------------------------------------------------- /walletdb.h.adoc: -------------------------------------------------------------------------------- 1 | = 比特币源码分析 2 | followtheart 3 | :doctype: book 4 | :encoding: utf-8 5 | :lang: en 6 | :toc: left 7 | :numbered: 8 | 9 | 实现了访问钱包数据库wallet.dat 10 | 11 | ## 山寨开发关注度:五星 12 | 13 | 基本上每个客户都会要求修改钱包地址首字母 14 | 15 | ## 全局变量 16 | 17 | ### DBErrors-- 钱包数据库的错误状态 18 | 19 | * DB_LOAD_OK, 20 | * DB_CORRUPT, 21 | * DB_NONCRITICAL_ERROR, 22 | * DB_TOO_NEW, 23 | * DB_LOAD_FAIL, 24 | * DB_NEED_REWRITE 25 | 26 | ## CWalletDB类 27 | 访问钱包数据库,继承CDB 28 | 29 | ### 成员变量 30 | 31 | * nVersion,版本号 32 | * vchData,被base58编码的数据. 33 | 34 | ### 成员函数 35 | 36 | [width="100%",options="header,footer"] 37 | |==================== 38 | | 方法名 | 说明 39 | | CWalletDB(std::string strFilename, const char* pszMode="r+") |... 40 | | bool WriteName(const std::string& strAddress, const std::string& strName);|... 41 | | bool EraseName(const std::string& strAddress);|... 42 | | bool WriteTx(uint256 hash, const CWalletTx& wtx) |... 43 | | bool EraseTx(uint256 hash) |... 44 | | bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey)|... 45 | | bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector& vchCryptedSecret, bool fEraseUnencryptedKey = true)|... 46 | | bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)|... 47 | | bool WriteCScript(const uint160& hash, const CScript& redeemScript)|... 48 | | bool WriteBestBlock(const CBlockLocator& locator)|... 49 | | bool ReadBestBlock(CBlockLocator& locator)|... 50 | | bool WriteOrderPosNext(int64 nOrderPosNext)|... 51 | | bool WriteDefaultKey(const CPubKey& vchPubKey)|... 52 | | bool ReadPool(int64 nPool, CKeyPool& keypool)|... 53 | | bool WritePool(int64 nPool, const CKeyPool& keypool)|... 54 | | bool ErasePool(int64 nPool)|... 55 | | bool ReadSetting(const std::string& strKey, T& value)|... 56 | | bool WriteSetting(const std::string& strKey, const T& value)|... 57 | | bool EraseSetting(const std::string& strKey)|... 58 | | bool WriteMinVersion(int nVersion)|... 59 | | bool ReadAccount(const std::string& strAccount, CAccount& account);|... 60 | | bool WriteAccount(const std::string& strAccount, const CAccount& account);|... 61 | | bool WriteAccountingEntry(const uint64 nAccEntryNum, const CAccountingEntry& acentry);|... 62 | | bool WriteAccountingEntry(const CAccountingEntry& acentry);|... 63 | | int64 GetAccountCreditDebit(const std::string& strAccount);|... 64 | | void ListAccountCreditDebit(const std::string& strAccount, std::list& acentries);|... 65 | | DBErrors ReorderTransactions(CWallet*);|... 66 | | DBErrors LoadWallet(CWallet* pwallet);|... 67 | | static bool Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys);|... 68 | | static bool Recover(CDBEnv& dbenv, std::string filename);|... 69 | |==================== 70 | --------------------------------------------------------------------------------