BTC 笔记

主要脉络为精通比特币(第二版)bitoin源码

比特币原理

2.1交易,块,挖矿和区块链

2.2.1交易输入输出

  • 交易就像复式记账法账簿中的行。简单来说,每一笔交易包含一个或多个“输入”,输入是针对一个比特币账号的负债

2.2.3交易链

  • 一(多)笔交易输出就是另一(多)笔交易的输入

2.2.4找零

  • 重要的是,找零地址不必与输入时提供的地址相同,出于隐私的原因,通常是所有者钱包中的新地址
  • 比特币交易建立和签名时不用连接比特币网络。只有在执行交易时才需要将交易发送到网络。

2.3 交易的构建

比特币交易建立和签名时不用连接比特币网络。只有在执行交易时才需要将交易发送到网络。

2.3.1 获取正确的输入

  • 完整客户端含有整个区块链中所有交易的所有未消费输出副本。这使得钱包既能拿这些输出构建交易,又能在收到新交易时很快地验证其输入是否正确。然而,完整客户端占太大的硬盘空间,所以大多数钱包使用轻量级的客户端,只保存用户自己的未消费输出。 可交给后端处理

2.3.2 创建交易输出

  • 交易的输出会被创建成为一个包含这笔数额的脚本的形式,只能被引入这个脚本的一个解答后才能兑换。使用私钥签名

2.4 比特币挖矿

▷ 挖矿节点通过参考比特币的共识规则验证所有交易。 因此,挖矿通过拒绝无效或畸形交易来提供比特币交易的安全性。

▷ 挖矿在构建区块时会创造新的比特币,和一个中央银行印发新的纸币很类似。每个区块创造的比特币数量是固定的, 随时间会渐渐减少。

2.5 区块中的挖矿交易记录

这些交易被加进新区块时,以交易费用高的优先以及其它的一些规则进行排序。矿工一旦从网络上收到一个新区块时, 会意识到在这个区块上的解题竞赛已经输掉了,会马上开始下一个新区块的挖掘工作。它会立刻将一些交易和这个新区块的数字指纹放在一起开始构建下一个新区块,并开始给它计算工作量证明。每个矿工会在他的区块中包含一个特殊的交易,将新生成的比特币(当前每区块为12.5比特币)作为报酬支付到他自己的比特币地址,再加上块中所有交易的交易费用的总和作为自己的报酬。

2.6 消费这笔交易

轻量级客户端通过确认一个交易在区块链中且在它后面有几个新区块来确认一个支付的合法性。这种方式叫做简易支付验证

3 btc core

下载核心源码< cpp >

git clone https://github.com/bitcoin/bitcoin.git

主要分级 enter image description here

4 密钥与地址

大多数比特币交易都需要一个有效的签名才会被存储在区块链。只有有效的密钥才能产生有效的数字签名,因此拥有~密钥副本就拥有了对该帐户的比特币的控制权。用于支出资金的数字签名也称为见证(witness),密码术中使用的术语。 比特币交易中的见证数据证明了所用资金的真正归谁所有。

密钥是成对出现的,由一个私钥和一个公钥所组成。公钥就像银行的帐号,而私钥就像控制账户的PIN码或支票的签名。比特币的用户很少会直接看到数字密钥。一般情况下,它们被存储在钱包文件内,由比特币钱包软件进行管理。

4.1.1 公钥加密和加密货币 信任基石

支付比特币时,比特币的当前所有者需要在交易中提交其公钥和签名(每次交易的签名都不同,但均从同一个私钥生 成)。比特币网络中的所有人都可以通过所提交的公钥和签名进行验证,并确认该交易是否有效,即确认支付者在该时刻对所交易的比特币拥有所有权。

4.1.2 私钥和公钥

一个比特币钱包中包含一系列的密钥对,每个密钥对包括一个私钥和一个公钥。私钥(k)是一个数字,通常是随机选出的。有了私钥,我们就可以使用椭圆曲线乘法这个单向加密函数产生一个公钥(K)。有了公钥(K),我们就可以使 用一个单向加密哈希函数生成比特币地址(A)。私钥、公钥和比特币地址之间的关系如下图所示 enter image description here

4.1.3 私钥

  • 从一个随机数生成私钥 生成密钥的第一步也是最重要的一步,是要找到足够安全的熵源,即随机性来源。 32字节的强随机数 bitcoin core random line 318
...
    // First source: OpenSSL's RNg 使用openssl rng获取随机数
    RandAddSeedPerfmon();
    GetRandBytes(buf, 32);
    hasher.Write(buf, 32);

    // Second source: OS RNG 使用操作系统 rng获取随机数
    GetOSRand(buf);
    hasher.Write(buf, 32);

    // Third source: HW RNG, if available.  使用hw rng获取随机数
    if (GetHWRand(buf)) {
        hasher.Write(buf, 32);
    }

    // Combine with and update state 生成hash 
    {
        std::unique_lock<std::mutex> lock(cs_rng_state);
        hasher.Write(rng_state, sizeof(rng_state));
        hasher.Write((const unsigned char*)&rng_counter, sizeof(rng_counter));
        ++rng_counter;
        hasher.Finalize(buf);
        memcpy(rng_state, buf + 32, 32);
    }

    // Produce output  输出结果 清理内存
    memcpy(out, buf, num);
    memory_cleanse(buf, 64);

生成私钥后会使用secp256k1库验证此私钥是否符合规则 ,如不符合则继续生成

// return  int 1为验证成功 0为失败
int secp256k1_ec_seckey_verify(const secp256k1_context* ctx, const unsigned char *seckey) {
    secp256k1_scalar sec;
    int ret;
    int overflow;
    VERIFY_CHECK(ctx != NULL);
    ARG_CHECK(seckey != NULL);

    secp256k1_scalar_set_b32(&sec, seckey, &overflow);
    ret = !overflow && !secp256k1_scalar_is_zero(&sec);
    secp256k1_scalar_clear(&sec);
    return ret;
}

4.1.4 公钥

公钥共65字节, 其中一个字节是0x04,其中32个字节是X坐标,另外32个字节是Y坐标

CPubKey CKey::GetPubKey() const {
    assert(fValid);
    secp256k1_pubkey pubkey;
    size_t clen = CPubKey::PUBLIC_KEY_SIZE;
    CPubKey result;
    // 使用secp256k1生成公钥
    int ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &pubkey, begin());
    assert(ret);
      // 使用secp256k1 序列化公钥
    secp256k1_ec_pubkey_serialize(secp256k1_context_sign, (unsigned char*)result.begin(), &clen, &pubkey, fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
    assert(result.size() == clen);
    assert(result.IsValid());
    return result;
}

4.1.5 椭圆曲线(ecc)密码学

使用AES的ecc加密算法生成公钥 不使用更常见的RSA,DSA是因为加密所采用的素数生成器可能存在后门且有极大可能性被破解 enter image description here

4.1.6 生成公钥

以一个随机生成的私钥k为起点,我们将其与曲线上预定的生成点G相乘以获得曲线上的另一点,也就是相应的公钥 K。生成点是secp256k1标准的一部分,比特币密钥的生成点都是相同的:

{K = k * G}

其中k是私钥,G是生成点,在该曲线上所得的点K是公钥。因为所有比特币用户的生成点是相同的,一个私钥k乘以G将 得到相同的公钥K。k和K之间的关系是固定的,但只能单向运算,即从k得到K。这就是可以把比特币地址(K的衍生) 与任何人共享而不会泄露私钥(k)的原因。

提示 因为其中的数学运算是单向的,所以私钥可以转换为公钥,但公钥不能转换回私钥。

为实现椭圆曲线乘法,我们 以之前产生的私钥k和与生成点G相乘得到公钥K:

K = 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD * G

公钥K 被定义为一个点 K = (x, y):

K = (x, y)

其中,

x = F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A y = 07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2E505BDB

为了展示整数点的乘法,我们将使用较为简单的实数范围的椭圆曲线。请记住,其中的数学原理是相同的。我们的目标是找到生成点G的倍数kG。也就是将G相加k次。在椭圆曲线中,点的相加等同于从该点画切线找到与曲线相交的另一 点,然后翻折到x轴。

下图显示了在曲线上得到 G、2G、4G 的几何操作。 enter image description here

4.2 比特币地址

提示比特币地址与公钥不同。比特币地址是由公钥经过单向的哈希函数生成的。 经过2次hash 和一次base58的变换保证单向不可逆退

  • 本质上和比特币地址并不是储存比特币的地址 而是可以用于验证比特币交易的标示 so
  • 一个私钥可以用于多个地址的签名 也就是 一个私钥根据协议不同可以生成多种不同形式的地址 enter image description here 大体生成过程 Alt text

4.2.2 密钥的格式

  • 公钥和私钥的都可以有多种格式。一个密钥被不同的格式编码后,虽然结果看起来可能不同,但是密钥所编码数字并没有改变。这些不同的编码格式主要是用来方便人们无误地使用和识别密钥
4.2.2.1私钥的格式

私钥可以以许多不同的格式表示,所有这些都对应于相同的256位的数字。表4-2展示了私钥的三种常见格式。不同的格式用在不同的场景下。十六进制和原始的二进制格式用在软件的内部,很少展示给用户看。WIF格式用在钱包之间密钥的输入和输出,也用于代表私钥的二维码 enter image description here

4.2.3.1公钥的格式

公钥也可以用多种不同格式来表示,最重要的是它们分为非压缩格式或压缩格式公钥这两种形式。

我们从前文可知,公钥是在椭圆曲线上的一个点,由一对坐标(x,y)组成。公钥通常表示为前缀04紧接着两个256比特的数字。其中一个256比特数字是公钥的x坐标,另一个256比特数字是y坐标。前缀04是用来区分非压缩格式公钥, 压缩格式公钥是以02或者03开头。

4.2.3.2压缩格式公钥
  • 目的 引入压缩格式公钥是为了减少比特币交易的字节数,从而可以节省那些运行区块链数据库的节点磁盘空间。
  • 压缩方法 未压缩格式公钥使用04作为前缀,而压缩格式公钥是以02或03作为前缀。需要这两种不同前缀的原因是:因为椭圆曲 线加密的公式的左边是y2 ,也就是说y的解是来自于一个平方根,可能是正值也可能是负值。更形象地说,y坐标可能在 x坐标轴的上面或者下面。从图4-2的椭圆曲线图中可以看出,曲线是对称的,从x轴看就像对称的镜子两面。因此,如果我们略去y坐标,就必须储存y的符号(正值或者负值)。换句话说,对于给定的x值,我们需要知道y值在x轴的上面还是下面,因为它们代表椭圆曲线上不同的点,即不同的公钥。当我们在素数p阶的有限域上使用二进制算术计算椭圆曲线的时候,y坐标可能是奇数或者偶数,分别对应前面所讲的y值的正负符号。因此,为了区分y坐标的两种可能值,我们在生成压缩格式公钥时,如果y是偶数,则使用02作为前缀;如果y是奇数,则使用03作为前缀。这样就可以根据公钥中给定的x值,正确推导出对应的y坐标,从而将公钥解压缩为在椭圆曲线上的完整的点坐标。下图阐释了公钥压缩: enter image description here
4.2.3.3压缩格式私钥
  • 请注意,十六进制压缩私钥格式在末尾有一个额外的字节(十六进制为01)。
  • 要注意的是,这些格式并不是可互换使用的。在实现了压缩格式公钥的较新的钱包中,私钥只能且永远被导出为WIF压 缩格式(以K或L为前缀)。对于较老的没有实现压缩格式公钥的钱包,私钥将只能被导出为WIF格式(以5为前缀)导 出。这样做的目的就是为了给导入这些私钥的钱包一个信号:是否钱包必须搜索区块链寻找压缩或非压缩公钥和地址。
  • “压缩格式私钥”是一个不当用词!私钥不是压缩的。WIF压缩格式的私钥只是用来表明他们只能被生成压缩的公钥和对应的比特币地址。相反地,“WIF压缩”编码的私钥还多出一个字节,因为这种私钥多了后缀“01”。该后缀是用来区分“非压缩格式”私钥和“压缩格式”私钥。

4.4 高级密钥和地址

4.4.1 加密私钥(BIP0038)

  • BIP0038加密方案是:输入一个比特币私钥,通常使用WIF编码过,base58chek字符串的前缀“5”。此外BIP0038加密方案需要一个长密码作为口令,通常由多个单词或一段复杂的数字字母字符串组成。BIP0038加密方案的结果是一个由 base58check编码过的加密私钥,前缀为6P。如果你看到一个6P开头的的密钥,这就意味着该密钥是被加密过,并需要一个口令来转换(解码)该密钥回到可被用在任何钱包WIF格式的私钥(前缀为5)。

4.4.2 P2SH (Pay-to-Script Hash)和多重签名地址

  • 正如我们所知,传统的比特币地址从数字1开头,来源于公钥,而公钥来源于私钥。虽然任何人都可以将比特币发送到 一个1开头的地址,但比特币只能在通过相应的私钥签名和公钥哈希值后才能消费。

  • 以数字3开头的比特币地址是P2SH地址,有时被错误的称谓多重签名或多重签名地址。他们指定比特币交易中受益人为哈希的脚本,而不是公钥的所有者。这个特性在2012年1月由BIP0016引进,目前因为BIP0016提供了增加功能到地址本身的机会而被广泛的采纳。不同于P2PKH交易发送资金到传统1开头的比特币地址,资金被发送到3开头的地址时,需要的不仅仅是一个公钥的哈希值和一个私钥签名作为所有者证明。在创建地址的时候,这些要求会被指定在脚本中,所有对地址的输入都会被这些要求阻隔。

  • 一个P2SH地址从交易脚本中创建,它定义谁能消耗这个交易输出。

4.4.2.1 多重签名地址和P2SH

  • 目前,P2SH函数最常见的实现是多重签名地址脚本。顾名思义,底层脚本需要多个签名来证明所有权,此后才能消费资金。设计比特币多重签名特性是需要从总共N个密钥中需要M个签名(也被称为“阈值”),被称为M-N多签名,其 中M是等于或小于N。

5.1钱包技术概述

一个常见误解是,比特币钱包里含有比特币。 事实上,钱包里只含有钥匙。 “钱币”被记录在比特币网络的区块链中。 用户通过钱包中的密钥签名交易,从而来控制网络上的钱币。 在某种意义上,比特币钱包是密钥链。

5.1.1非确定性(随机)钱包 旧版本

非确定性钱包,其含有的随机密钥是个松散的集合 enter image description here

5.1.2 确定性(种子)钱包

确定性,或者“种子”钱包包含通过使用单项离散函数而可从公共的种子生成的私钥。种子是随机生成的数字。这个数字也含有比如索引号码或者可生成私钥的“链码”

5.1.3 分层确定性钱包(HD Wallets (BIP-32/BIP-44))

确定性钱包被开发成更容易从单个“种子”中生成许多密钥。确定性钱包的最高级形式是通过BIP0032标准定义的HD钱包。HD钱包包含以树状结构衍生的密钥,使得父密钥可以衍生一系列子密钥,每个子密钥又可以衍生出一系列孙密钥,以此类推,无限衍生 enter image description here 相比较随机(不确定性)密钥,HD钱包有两个主要的优势。第一,树状结构可以被用来表达额外的组织含义 HD钱包的第二个好处就是它可以允许使用者去建立一个公共密钥的序列而不需要访问相对应的私钥。这可允许HD钱包在不安全的服务器中在每笔交易中发行不同的公钥。公钥不需要被预先加载或者提前衍生,而在服务器中不需要 可用来支付的私钥。

5.1.4种子和助记词(BIP-39)

HD钱包具有管理多个密钥和地址的强大机制。由一系列英文单词生成种子是个标准化的方法,这样易于在钱包中转移、导出和导入,如果HD钱包与这种方法相结合,将会更加有用。 这些英文单词被称为助记词,标准由BIP-39定义。 今天,大多数比特币钱包(以及其他加密货币的钱包)使用此标准,并可以使用可互操作的助记词导入和导出种子进行备份和恢复。

5.1.5钱包最佳实践

由于比特币钱包技术已经成熟,出现了一些常见的行业标准,使得比特币钱包具备广泛互操作,易于使用,安全和灵活的特性。这些常用的标准是:

助记码,基于BIP-39

HD钱包,基于BIP-32

多用途HD钱包结构,基于BIP-43

多币种和多帐户钱包,基于BIP-44

5.2钱包技术细节

5.2.1助记码词汇(BIP-39)

  • 助记码词汇是英文单词序列代表(编码)用作种子对应所确定性钱包的随机数。
  • 单词的顺序就是钱包的备份。它也可以被用来恢复以及重新创造应用程序相同或者兼容的钱包的密钥。助记码词汇可以让使用者复制钱包更容易一些,因为相比较随机数字顺序来说,它们更容易地被阅读和正确抄写。

5.2.2创建助记词

助记词是由钱包使用BIP-39中定义的标准化过程自动生成的。 钱包从熵源开始,增加校验和,然后将熵映射到单词列表:

1、创建一个128到256位的随机序列(熵)。

2、提出SHA256哈希前几位(熵长/ 32),就可以创造一个随机序列的校验和。

3、将校验和添加到随机序列的末尾。

4、将序列划分为包含11位的不同部分。

5、将每个包含11位部分的值与一个已经预先定义2048个单词的字典做对应。

6、生成的有顺序的单词组就是助记词。 enter image description here 了熵数据的大小和助记词的长度之间的关系。 enter image description here

5.2.3从助记词生成种子

  • 助记词表示长度为128至256位的熵。 通过使用密钥延伸函数PBKDF2,熵被用于导出较长的(512位)种子。将所得的种子用于构建确定性钱包并得到其密钥。

  • 密钥延伸函数有两个参数:助记词和盐。其中盐的目的是增加构建能够进行暴力攻击的查找表的困难度。 在BIP-39标准中,盐具有另一目的,它允许引入密码短语(passphrase),作为保护种子的附加安全因素。

7、PBKDF2密钥延伸函数的第一个参数是从步骤6生成的助记词。

8、PBKDF2密钥延伸函数的第二个参数是盐。 由字符串常数“助记词”与可选的用户提供的密码字符串连接组成。

9、PBKDF2使用HMAC-SHA512算法,使用2048次哈希来延伸助记符和盐参数,产生一个512位的值作为其最终输出。 这个512位的值就是种子。 enter image description here

5.2.4BIP-39中的可选密码短语

  • BIP-39标准允许在推导种子时使用可选的密码短语。 如果没有使用密码短语,助记词是用由常量字符串“助记词”构成的盐进行延伸,从任何给定的助记词产生一个特定的512位种子。 如果使用密码短语,密钥延伸函数使用同样的助记词也会产生不同的种子。事实上,给予一个单一的助记词,每一个可能的密码短语都会导致不同的种子。 基本上没有“错误”的密码短语, 所有密码短语都是有效的,它们都会导致不同的种子,形成一大批可能未初始化的钱包。 这批钱包非常之大(2^512),使用暴力破解或随机猜测基本不可能。

5.3从种子中创造HD钱包

HD钱包从单个根种子(root seed)中创建,为128到256位的随机数。最常见的是,这个种子是从助记词产生的. HD钱包的所有的确定性都衍生自这个根种子。 任何兼容HD 钱包的根种子也可重新创造整个HD钱包。所以简单的转移HD钱包的根种子就让HD钱包中所包含的成千上百万的密钥被复制,储存导出以及导入 enter image description here

5.3.1私有子密钥的衍生

  • 分层确定性钱包使用CKD(child key derivation)函数去从母密钥衍生出子密钥。

  • 子密钥衍生函数是基于单项哈希函数。这个函数结合了:

  • 一个母私钥或者母公钥(未压缩的)

  • 一个叫做链码(256 bits)的种子

  • 一个索引号(32 bits)

  • 链码是用来给这个过程引入确定性随机数据的,使得索引不能充分衍生其他的子密钥。因此,子密钥并不能让它发现自己的姊妹密钥,除非你已经有了链码。最初的链码种子(在密码树的根部)是用随机数据构成的,随后链码从各自的母链码中衍生出来。

  • 这三个项目(母钥,链码,索引)相结合并散列可以生成子密钥,如下。

  • 母公钥——链码——以及索引号合并在一起并且用HMAC-SHA512函数散列之后可以产生512位的散列。所得的散列可被拆分为两部分。散列右半部分的256位产出可以给子链当链码。左半部分256位散列以及索引码被加载在母私钥上来衍生子私钥。在图5-10中,我们看到这个说明——索引集被设为0去生产母密钥的第0个子密钥(第一个通过索 引)。

  • 向密码树下一层重复这个过程,每个子密钥可以依次成为母密钥继续创造它自己的子 密钥,直到无限代 enter image description here

5.3.2使用衍生的子密钥

子私钥不可追溯,它可以用来做公钥和比特币地址。之后它就可以被用在那个地址来签署交易和支付任何东西。

  • 子私钥、对应的公钥以及比特币地址都不能从随机创造的密钥和地址中被区分出来。事实是它们所在的序列,在创造他们的HD钱包函数之外是不可见的。一旦被创造出来,它们就和“正常”密钥一样运行了。

5.3.3扩展密钥

密钥衍生函数可以被用来创造密钥树上任何层级的子密钥。这只需要三个输入量:一个密钥,一个链码以及想要的子密钥的索引。密钥以及链码这两个重要的部分被结合之后,就叫做扩展密钥 一个扩展密钥作为HD钱包中密钥树结构的一个分支的根。你可以衍生出这个分支的剩下所有部分。扩展私钥可以创建一个完整的分支,而扩展公钥只能够创造一个公钥的分支。

5.3.4公共子密钥推导

正如之前提到的,分层确定性钱包的一个很有用的特点就是可以不通过私钥而直接从公共母密钥派生出公共子密钥的能力。这就给了我们两种衍生子公钥的方法:或者通过子私钥,再或者就是直接通过母公钥。 因此,扩展密钥可以在HD钱包结构的分支中,是被用来衍生所有的公钥(且只有公钥)。 enter image description here

5.3.6硬化子密钥的衍生

  • 从扩展公钥衍生一个分支公钥的能力是很重要的,但牵扯一些风险。访问扩展公钥并不能得到访问子私钥的途径。但是,因为扩展公钥包含有链码,如果子私钥被知道或者被泄漏的话,链码就可以被用来衍生所有的其他子私钥。简单地泄露的私钥以及一个母链码,可以暴露所有的子密钥。更糟糕的是,子私钥与母链码可以用来推断母私钥。
  • 这个硬化衍生函数使用了母私钥去推导子链码,而不是母公钥。这就在母/子顺序中创造了一道“防火墙”——有链码但并不能够用来推算子链码或者姊妹私钥。强化衍生函数看起来几乎与一般的衍生的子私钥相同,不同的是母私钥被用来输入散列函数中而不是母公钥 enter image description here 如果你想要利用扩展公钥的便捷来衍生公钥的分支而不将你自己暴露在泄露扩展链码的风险下, 你应该从强化母私钥衍生公钥,而不是从一般的母私钥来衍生。 最好的方式是,为了避免了推到出主密钥,主密钥所衍生的第一层级的子密钥最好使用强化衍生。

5.3.7正常衍生和强化衍生的索引号码

用在衍生函数中的索引号码是32位的整数。为了区分密钥是从正常衍生函数中衍生出来还是从强化衍生函数中产出,这个索引号被分为两个范围。索引号在0和2^31–1(0x0 to 0x7FFFFFFF)之间的是只被用在常规衍生。索引号在2^31和2^32– 1(0x80000000 to 0xFFFFFFFF)之间的只被用在强化衍生。因此,索引号小于2^31就意味着子密钥是常规的,而大于或者等于2^31的子密钥就是强化型的。

为了让索引号码更容易被阅读和展示,强化子密钥的索引号码是从0开始展示的,但是右上角有一个小撇号。第一个常规子密钥因此被表述为0,但是第一个强化子密钥(索引号为0x80000000)就被表示为0’。第二个强化密钥依序有了索 引号0x80000001,且被显示为1’,以此类推。当你看到HD钱包索引号i’,这就意味着 2^31+i。

5.3.8HD钱包密钥识别符(路径)

HD钱包中的密钥是用“路径”命名的,且每个级别之间用斜杠(/)字符来表示(见表5-6)。由主私钥衍生出的私钥起始以“m”打头。由主公钥衍生的公钥起始以“M“打头。因此,母密钥生成的第一个子私钥是m/0。第一个公钥是M/0。第一个子密钥的子密钥就是m/0/1,以此类推。

密钥的“祖先”是从右向左读,直到你达到了衍生出的它的主密钥。举个例子,标识符m/x/y/z描述的是子密钥m/x/y的第z个子密钥。而子密钥m/x/y又是m/x的第y个子密钥。m/x又是m的第x个子密钥。

5.3.9HD钱包树状结构的导航

通过创建几个HD钱包树的提议标准。BIP-43提出使用第一个强化子索引作为特殊的标识符表示树状结构的“purpose”基于BIP-43,HD钱包应该使用且只用第一层级的树的分支,而且有索引号码去识别结构并且有命名空间来定义剩余的树的目的地。举个例子,HD钱包只使用分支m/i’/是 为了表明那个被索引号“i”定义的特殊为目地。

在BIP-43标准下,为了延长的那个特殊规范,BIP-44提议了多账户结构作为“purpose”。所有遵循BIP-44的HD钱包依据只使用树的第一个分支的要求而被定义:m/44’/。 BIP-44指定了包含5个预定义树状层级的结构:

m / purpose’ / coin_type’ / account’ / change / address_index

第一层的purpose总是被设定为44’。

第二层的“coin_type”特指币种并且允许多元货币HD钱包中的货币在第二个层级下有自己的亚树状结构。目前有三种货币被定义:Bitcoin is m/44’/0’、Bitcoin Testnet is m/44’/1’,以及 Litecoin is m/44’/2’。

树的第三层级是“account”,这可以允许使用者为了会计或者组织目的,而去再细分他们的钱包到独立的逻辑性亚账户。 举个例子,一个HD钱包可能包含两个比特币“账户”:m/44’/0’/0’ 和 m/44’/0’/1’。每个账户都是它自己亚树的根。

第四层级就是“change”。每一个HD钱包有两个亚树,一个是用来接收地址一个是用来创造找零地址。注意无论先前的层级是否使用强化衍生,这一层级使用的都是常规衍生。这是为了允许这一层级的树可以在不安全环境下,输出扩展公钥。

被HD钱包衍生的可用的地址是第四层级的子级,就是第五层级的树的“address_index”。比如,第三个层级的主账户收到比特币支付的地址就是 M/44’/0’/0’/0/2。