免责声明:金色财经所有资讯仅代表作者个人观点,不构成任何投资理财建议。请确保访问网址为(jinse.cn) 举报

    白话区块链技术 第14讲|HD多签地址的实现

    欢迎来到《王毅白话区块链技术》专栏第十四讲:HD多签地址的实现(一)。

    HD在这里的意思是Hierachical Deterministic,即分层确定性。了解过HD钱包的朋友应该了解这个名词,相信这个概念对于我们来讲不陌生,即用一个主密钥来按一定的规则生成一系列的子密钥,同时还可以基于新生成的密钥再生成它自己的子密钥,这样形成一个分层的树状结构的密钥组织。

    多签在这里的意思是在一个地址下的UTXO必须由两个或者两个以上的用户共同去签名才能正常使用并支付成功,即我们平时所说的多方签名,多方签名在BTC的生态里用的是P2SH的方式。

    我们想要做的是要把HD与多签进行结合,生成具有HD特性的多签地址。其基本原理其实是比较简单的:每个签名方构造一个自己的HD密钥树,分别对各个子密钥对进行运算得到多签地址。原理归原理,事实上在生成这样的密钥对时要考虑的问题还是比较多的。

    1. HD密钥对应该如何创建,是否应该遵循一些规则?

    2. MS应该怎么构建,是否也有一定的标准?

    当然,对于以上两个问题,我们可以不必去探究,只是按照HD与MS最基本的方式都构建自己的密钥对,但这样一来,构建的这些密钥对就只能在自己使用的工程中使用,而不能作为一个大家都可以导入引用的数据。

    好了,说了这么多,其实就是说我们在做这件事的时候是要遵循一定的标准的,这篇文章剩下的部分,我们就会详细讲解涉及到的各个规则。

    01

    HD钱包

    通常情况下,客户端可以自由、随机生成密钥对,但每生成一个密钥对,我们就得想办法把私钥加密、保存、备份以防止丢失,这是很麻烦的一件事。当然我们也可以一次生成很多个密钥对供使用,然后把这些密钥对的私钥都通过加密的手段保护起来,这样就不必多次备份了。但这其实是牺牲了用户“可以自由生成密钥对”这个重要功能特点。总结一下,可以自由生成,但是每生成一次就要备份一次;可以只备份一次,但是不能自由生成。

    是不是感觉很为难,鱼与熊掌兼想得之,奈何?HD钱包可以解决这个问题。使用一定的数学算法,我们能生成这样一种密钥树结构:在不必提供私钥的情况下生成一个可用的新的公钥。在我们以前的文章中,总是说私钥生成公钥,公钥生成地址。但是在HD的生态里,不一定是这样的,可以通过公钥来生成公钥,新生成的那个公钥叫子公钥,生成子公钥时使用的那个公钥我们叫它父公钥,那有些朋友会问,那这个新生成的公钥有其对应的私钥吗?答案是肯定的,它对应私钥是通过其父公钥所对应私钥来生成,即父私钥生成子私钥。那这样还会有人问,那这个子私钥可以生成这个子公钥吗?答案也是肯定的,是符合密码学标准的,一个公钥一定可以由一个私钥生成。

    是不是比较清晰了,我们只需要把父私钥备份一次就可以了,然后用父公钥去生成各个子公钥,子公钥再生成它自己的后代子公钥,这样就解决了我们使用自由生成密钥对时面临的问题。

    但这并不是全部,还有新的问题。如果给了钱包一个父公钥,它岂不是知道了这个用户下的所有公钥地址,这如何是好,我还想隐藏一部分地址呢。对于指定的父公钥,确实是没办法再隐藏它这一分支下可能生成的公钥了,但我们可以有多个父公钥呀,或者说我们没必要在树结构的第二级就生成真实地址。在HD的架构里,我们在设计HD密钥树时,就可以设计多个分支,每个分支都是由一个主密钥派生出来的。

    02

    密钥

    在实际生成子密钥的时候,并不是直接从主密钥生成,而是给主密钥再接一个随机的32字节的随机数,这个随机值我们称之为chain code,即链码。生成的子密钥对同样也会对应有自己的链码。因此在HD钱包的架构中,链码也是很重要的。一个扩展密钥就是密钥本身再加上链码,即(K ,C)的形式。

    2.1. 分类


    另外子密钥也不是无上限的,每一对密钥只能生成2³²个子私钥,我们把这些私钥分成两组,0至2³¹-1个是normal child key,2³¹至2³²-1个是hardened child key。通常为了方便表示,用来表示i+2³¹,这些数字就对应着生成子密钥时的序号。那normal child key 与hardened child key有什么区别吗?还是说仅仅是生成序号时名义上的区分呢?我们可以先记下这个问题。

    2.2. CDK方程(Child key derivation)


    我们不过多地讲数字公式,大家只需要知道,这是生成子密钥的函数就行了。函数的输入是父密钥,即父私钥或者父公钥,另外加一个子密钥的序号,值为0至2³²-1,即可生成对应的子密钥。要注意的是当序号小于2³¹时,函数所用的算法与序号大于2³¹时可是不一样的,因此生成的子密钥有normal与hardened之分,这里知道密钥的分类是怎么来的了吧,是因为生成密钥时的算法不同。

    1. 父扩展私钥生成子扩展私钥

    2. 父扩展公钥生成子扩展公钥

    3. 父扩展私钥生成子扩展公钥

    以上三种即为CKD方程的重要应用形式,我们还应该知道父扩展公钥不能生子扩展私钥。

    当然还有至关重要的一点,如果我们知道主公钥与一个normal child key的私钥,那我们就能得到主私钥,吓人吧,因此主公钥其实也是很重要的。因此有一些重要的密钥树层级上,我们得用hardened child key,而不能选用normal child key.

    2.3. 各级序号


     图2

    图2就是比特币BIP32规则下的HDW的一个结构图,我们能看到有这么几级:0级为主密钥节点;1级为帐户节点;2级为地址类型节点,3级为事实子地址节点。这里面的每一级就是我们刚才讲到的:根据父密钥,再加上一个序号生成的一些子密钥。比如1级节点,就是指序号为0至2³²的各个子密钥。当然我们在实际使用中,这一级其实用不了几个,因为一个钱包内不会需要那么多的帐户,基本上是有限个数的。但这里我们要注意,这个序号我们一般取的是2³¹之后的序号,这个原因就是为了防止,子私钥与主公钥泄露后使得主私钥泄露,回想一下上一节里讲过的,如果是harden child key的话,子私钥的泄露是不会使主私钥暴露的。所以我们在以后看到的HD的架构中,第二级的序号一般是2³¹之后的。

    第三级的序号一般是普通序号,用来区分密钥使用目的,比如可以用0来表示接收地址链,1来表示找零、发送地址链。接收地址链即表示,这一个分支产生出来的子密钥用来接收加密货币;找零、发送地址链则表示这一分支产生的子密钥用来接收零钱、转帐时使用。

    结尾

    我们在这里说了很多,其实只是要告诉大家这么一个知识点:主密钥可以生成子密钥,子密钥可以再生成自己的子密钥,一级一级可以生成很多级,每一级最多能有2³²个子密钥。这里最重要想要说明的是,在实际中我们其实是取其中的某一级密钥来使用,比如第4级,那第1到第3级应该采用哪一个分支序号呢,为了使大家在各个系统里方便互相使用,比特币的改进建议里都已经进行了详细的规定,使每一级的序号都有一定的代表意义。

    篇幅所限,我们在下一节里继续说如果构造多签地址里怎么设定每一级序号的意义,及多签构建里应该注意的其它一些问题。

     本期作者|王   毅 

    本期编辑|靳亚峰

    祝你晚安早安午安心安

    jinse.cn 0
    好文章,需要你的鼓励
    jinse.cn 0
    好文章,需要你的鼓励
    参与评论
    0/140
    提交评论
    文章作者: / 责任编辑:

    声明:本文由入驻金色财经的作者撰写,观点仅代表作者本人,绝不代表金色财经赞同其观点或证实其描述。

    提示:投资有风险,入市须谨慎。本资讯不作为投资理财建议。

    金色财经 > 币须说19 > 白话区块链技术 第14讲|HD多签地址的实现
    • 寻求报道
    • 金色财经中国版App下载
      金色财经APP
      iOS & Android
    • 加入社群
      Telegram
    • 意见反馈
    • 返回顶部
    • 返回底部