专栏首页申龙斌的程序人生用NBitcoin进行区块链开发(7):助记词

用NBitcoin进行区块链开发(7):助记词

比特币的私钥是256位的二进制数字,占32个字节,比如: 3243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C8

这串数字输入费劲,还容易出错,中本聪就规定了一种WIF格式,称为Wallet Import Format,这种格式的私钥可以非常方便地导入到Bitcoin Core等钱包软件中。

刚才的私钥转换为WIF格式,以字母K开头: KxuRLWqnfcgs8ru7YiMBfP6T71jK9twCedaeBtHgRgzb8adnoZzH

管理一大堆私钥仍然非常麻烦,BIP32规范引入了HD钱包的概念,这里的HD不是HardDisk的缩写,而是指分层确定性(Hierarchical Deterministic)钱包。

有了HD钱包,只需备份好一个主私钥就可以生成所有其它私钥,所以私钥的备份显得尤为重要,抄错一个字母,可能币就丢了,因此BIP39规范又引入了助记词mnemonic words。

助记词由12个到24个常用单词组成,比如:

base quality head cereal media bracket castle either sign crumble pull rug

NBitcoin中提供了一个Mnemonic类,可以方便生成助记词,也可以通过助记词生成私钥。

Mnemonic m = new Mnemonic(Wordlist.English, WordCount.Twelve);
Console.WriteLine(string.Join(" ", m.Words));
m = new Mnemonic(Wordlist.English, WordCount.Eighteen);
Console.WriteLine(string.Join(" ", m.Words));
m = new Mnemonic(Wordlist.English, WordCount.TwentyFour);
Console.WriteLine(string.Join(" ", m.Words));
输出结果
method bachelor promote into sense autumn bag stock genuine style canyon warm
pair move hire skirt acquire wreck repeat motion actual brown kid today virus mansion portion demise possible brother
hamster museum voyage unveil chuckle grit inform clog ripple blur rug entry fruit saddle you undo drama home business company dinner cupboard unfold lawsuit

有了主私钥之后,与不同的KeyPath结合,可以扩展出多币种、多帐户的不同地址,理论上可以是无穷多个。

图片摘自《精通比特币》

BIP44规范中又对KeyPath的5个组成部分进行了明确约定:

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

purpose在BIP44中设置为常量44。

coin_type标识币种,BTC是0,以太坊是60,BCH是145,EOS是194,XMR是128。详细列表见这个网址: https://github.com/satoshilabs/slips/blob/master/slip-0044.md

account可以指定不同的帐户,比如用于捐赠的,用于挖矿的,用于消费的等等,根据个人喜好设置。

change用于生成找零地址。

最后的index还可以指定多个地址。

根据这种定义,第一个BTC地址的KeyPath就是:

m/44’/0’/0’/0/0

m表示私钥。M表示公钥。 值得注意的是里面的单撇符号,前3个数字后面有单撇,后面2个数字则没有。单撇的含义是hardened,相当于安全加固,用于切断某些子私钥的相关性,避免泄漏了某个子私钥对其它私钥造成影响。

而下一个BTC地址的KeyPath则是:

m/44’/0’/0’/0/1

很多种钱包都遵守BIP44规范:

  • Mycelium Bitcoin Wallet
  • TREZOR (source)
  • KeepKey (source)
  • Ledger Wallet (source)
  • Jaxx

在NBitcoin中可以方便地计算出这些私钥和地址:

string strWords = "base quality head cereal media bracket castle either sign crumble pull rug";
Mnemonic mm = new Mnemonic(strWords, Wordlist.English);
ExtKey hdroot = mm.DeriveExtKey();

// the first BTC address
var extkey = hdroot.Derive(new KeyPath("m/44'/0'/0'/0/0"));
var btcPriv1 = extkey.PrivateKey.GetWif(Network.Main);
Console.WriteLine(btcPriv1);
var btcAddr1 = btcPriv1.GetAddress();
Console.WriteLine(btcAddr1);

// the second BTC address
extkey = hdroot.Derive(new KeyPath("m/44'/0'/0'/0/1"));
var btcPriv2 = extkey.PrivateKey.GetWif(Network.Main);
Console.WriteLine(btcPriv2);
var btcAddr2 = btcPriv2.GetAddress();
Console.WriteLine(btcAddr2);

在下面这个网站中可以非常方便地验证上面代码的正确性: https://iancoleman.io/bip39/#english

上面程序输出的私钥和地址:

L39FE7LfN5wBfLJthraKVhCdgDaWFgNn5xWhUgzfamWuzitbsjma
1DHQZkmhKSEEjzfP9cAFfKABeVivTpXJwq
Kwgo2fdv2mjQfMmBarMqLfCigwRdALeq9ek38wETMuevb9TaXGJp
1AJjN85VyZSffPDaFzfeyeTV5shNdUGpCg

你也可以将上面的12个助记词导入到Jaxx钱包中,看看生成的BTC、BCH、ETH等地址是否完全一致。不怕麻烦的话,也可以自己生成一套助记词,恢复到Ledger Nano S硬件钱包中。

Jaxx钱包显示私钥的结果

ETH的私钥和地址的编码方式与BTC的不一样,在NBitcoin中当然无法显示以太坊的东西,需要使用Nethereum的类库,请自行从nuget里安装即可。

extkey = hdroot.Derive(new KeyPath("m/44'/60'/0'/0/0"));
var eth1 = new Nethereum.Signer.EthECKey(extkey.PrivateKey.ToBytes(), true);
Console.WriteLine(eth1.GetPrivateKey());
Console.WriteLine(eth1.GetPublicAddress());

extkey = hdroot.Derive(new KeyPath("m/44'/60'/0'/0/1"));
var eth2 = new Nethereum.Signer.EthECKey(extkey.PrivateKey.ToBytes(), true);
Console.WriteLine(eth2.GetPrivateKey());
Console.WriteLine(eth2.GetPublicAddress());

对应的私钥和地址:

0x00daa97f89afd2a06279cdfc3c5f488f97b2bb89bc4af95882cac8065704c74fdf
0x4ffc6A9E3CfF2D670f02a1dC7b8aaAF705FEBFfb
0x0088cd6fa7ab95499ed3f8271ac7bc8495e9372fb540098a6c85a9ad7d89d3d43a
0x87c6d9ab2d28c870ECeB9c8e34236Add80874B2d

掌握了这些私钥和地址的生成规则后,请自行练习生成BCH和BSV的私钥和地址。

本文分享自微信公众号 - 申龙斌的程序人生(slbGTD)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-02-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • HD钱包【区块链生存训练】

    早期的Bitcoin Core钱包一次性生成100个私钥,如果交易比较频繁,私钥可能会用光,然后再产生一批私钥,所以需要定期备份wallet.dat文件,否则会...

    申龙斌
  • 通过欧拉计划学Rust编程:第100题

    由于研究Libra等数字货币编程技术的需要,学习了一段时间的Rust编程,一不小心刷题上瘾。

    申龙斌
  • 我生成的比特币地址竟然与别人的重合了

    申龙斌
  • 用 Java 实现梯度下降

    梯度下降是一种优化算法,用于查找给定函数的局部最小值。它被广泛用于高级机器学习算法中,最小化损失函数。

    用户5224393
  • Linux系统搭建C++开发环境

    Linux编译C++程序必须安装g++编译器。这里使用yum方式安装。首先切换到root账号,su - root 然后输入密码。

    震八方紫面昆仑侠
  • 0464-如何离线分析HDFS的FsImage查找集群小文件

    随着Hadoop集群数据量的增长,集群中也同时会存在大量的小文件,即文件Size比HDFS的Block Size(默认128MB)小的多的文件。Hadoop集群...

    Fayson
  • 宝塔面板未授权访问数据库管理界面漏洞复现

    宝塔面板是一款服务器管理软件,支持windows和linux系统,可以通过Web端轻松管理服务器,提升运维效率。例如:创建管理网站、FTP、数据库,拥有可视化文...

    Timeline Sec
  • ASP.NET Core 2.2 十九. 你扔过来个json,我怎么接

      前文说道了Action的激活,这里有个关键的操作就是Action参数的映射与模型绑定,这里即涉及到简单的string、int等类型,也包含Json等复杂类型...

    FlyLolo
  • ASP.NET MVC编程——单元测试

    1自动化测试基本概念 自动化测试分为:单元测试,集成测试,验收测试。 单元测试 检验被测单元的功能,被测单元一般为低级别的组件,如一个类或类方法。 单元测试要满...

    甜橙很酸
  • [Spring cloud 一步步实现广告系统] 6. Service实现&Zuul配置&Test

    这里我们使用Spring DATA JPA来实现数据库操作,当然大家也可以使用Mybatis,都是一样的,我们依然以用户表操作为例:

    Isaac Zhang

扫码关注云+社区

领取腾讯云代金券