HBitcoin:C#高级比特币钱包库 - 保护您的财产安全

背景

在几年前,我有写一个叫HiddenBitcoin的钱包库,那是我第一次接触跟比特币相关的项目。多年来我一直在复用这个项目中的代码并不停的改进优化它,虽然到最后我任然没能成功发布一个稳定的版本。可以说这次的HBitcoin就是HiddenBitcoin的后继者了,当初我写HiddenBitcoin的动机是为了学习,然而现在我做HBitcoin是因为某种需求。我一直在不同的Bitcoin项目中重用我的代码。这已经发展到以至于我在这里公布的主类有6个不同的版本。因此,现在是时候把这些代码整理好,并将它们打包成一个我可以随时通过NuGet包安装使用的Bitcoin库。

介绍

HBitcoin库是在NBitcoin的基础上写的。它介于HBitcoin APIBlockchain API之间。它的灵活性要比后者高,但比前者少。如果您要深入的学习Bitcoin,您很有必要去翻阅The C#Bitcoin Book(比特币C#)。

在这学完了这三个部分教程后,您将能够创建一个比特币钱包。

提示 :虽然使用API编程可以帮助开发人员快速开发程序,但开发人员的创新也会被局限于API中。

Nicolas DorierBitcoin的核心开发者,NBitcoinC# Bitcoin库的创建者。在使用本文章的代码库时请记住这个提示。

一个比特币钱包能做什么?

一个比特币钱包有三个关键功能:

  1. 安全地存储密钥并管理对密钥的访问
  2. 监视这些密钥的交易
  3. 创建交易并将它们广播到网络

如何存储密钥?

比特币地址,私钥

比特币地址你应该很熟悉了,你可以往里面存比特币,并且你可以使用相应的私钥来花掉这些比特币。

动态地址

你可能也熟悉钱比特币包并知道他们会为不同的交易生成不同的动态地址。你可能会问为什么这些交易不只使用一个地址?这是为了保护隐私,区块链是公开记账,因此任何人都可以很容易地看到一个比特币地址的收入和支出。因此,避免地址重用是一个更好的主意,尽管这并不能完全解决隐私问题,但这无疑提高了安全性。

HD(Hierarchical Deterministic)钱包(分层确定性钱包)

那么问题又来了,我们如何管理这么多的密钥?存储,监控并花费它们?请注意使用多个密钥会大大地提高比特币钱包的复杂性。

好在HD钱包结构使我们能够只存储一个密钥并从中派生出其他密钥。为了保持我们对NBitcion术语的一致性,我们称之为"BitcoinExtKey"。

关于比特币私钥管理的优化建议

有四种BIP(Bitcoin Improvement Proposal,比特币改进建议)是我们要注意的,分别是BIP32,BIP38,BIP43,BIP44。为了简单起见,你可以把BIP32和BIP38视为相同的BIP。它们定义了一些底层的东西,比如如何派生和加密密钥。这些在NBitcoin中都实现了。BIP43和BIP44建立在BIP32-38的基础上之上,并定义了更多的东西,如关于如何组织和使用密钥的结构。有几种钱包实现了BIP43-44。一开始我也在尝试实现它们,但随后我就决定不用它们了,因为它们不仅让我的项目变得过于复杂,而且我也无法将它应用到以后的一些边缘案例中来。那么这样一来,我就可以为你们提供更简洁的接口了。

多说无益,让我们在代码中见真章!

项目设置

  1. 启动一个新的.NET Core项目
  2. 添加NuGet中的HBitcoin
var network = Network.Main;
//下面输入一个强壮的密码,如"password"
var password = "password";

//用一个密码在指定的网络中的指定路径中创建Safe类
//Safe类用来管理你的私钥种子
//Safe可以自动处理序列
//创建一个Safe类后,它会自动存储在指定的路径中
Mnemonic mnemonic;
Safe safe = Safe.Create(out mnemonic, password, @"Wallets\Wallet.json", network);

//创建Safe类时会同时创建mnemonic(助记符)类,你可以用它来恢复(或复制)Safe类
//你只会在一开始的时候才会接触到mnemonic类
Console.WriteLine(mnemonic);

// 把Safe类恢复到另一个路径中
Safe recoveredSafe = Safe.Recover(mnemonic, password, @"Wallets\SameWallet.json", network);

// 解密/加载一个现存的Safe/钱包文件
Safe loadedSafe = Safe.Load(password, @"Wallets\hiddenWallet.hid");

// 在加载了一个safe后我们最好检查一下它的网络是否正确
if (network != loadedSafe.Network)
	throw new Exception("Wrong network");

// 列出10个地址
for (var i = 0; i < 10; i++)
{
	Console.WriteLine(safe.GetAddress(i));
}

如何解密钱包?

你只需要获得(密码助记符(mnemonic))密码钱包文件)

然后,您就能调用Recover of Load了。

谁知道密码?用户。

谁知道助记符(mnemonic)?正常情况下,用户可以把它写在一张纸上放在家里作为备份。

谁知道钱包文件?正常情况下,它存储在用户的硬盘上。

其他钱包

通常,只用助记符来恢复一个钱包就够了。但我觉得这不安全,所以我们的这个钱包不能像那样。

创建时间

var safe2 = Safe.Recover(mnemonic, password, "Wallet.json", network,
	  creationTime: DateTimeOffset.ParseExact("2017-02-20", 
	  "yyyy-MM-dd", CultureInfo.InvariantCulture));
Console.WriteLine(safe.CreationTime);

当你创建一个钱包时,它也会自动保存它的创建时间,这对于编写一些SPV钱包来说非常方便。因此,当您恢复钱包时,您还可以使用创建时间作为参数,如果您没有不填写这个参数,它会默认为可能的最早创建时间,这个时间是硬编码的:

public static DateTimeOffset EarliestPossibleCreationTime
	=> DateTimeOffset.ParseExact("2017-02-19", 
	"yyyy-MM-dd", CultureInfo.InvariantCulture);

这是我第一次介绍创建时间这个概念的日期。如果您没有尝试使用早些的创建时间来恢复钱包,则系统会默认使用EarliestPossibleCreationTime。

安全账户和Hd路径类型

var alice = new SafeAccount(id: 2);
safe.GetAddress(index: 1, hdPathType: HdPathType.Receive, account: alice);
safe.GetPrivateKey(index: 1, hdPathType: HdPathType.Receive, account: alice);

你可以随意地创建账户。在上面的代码中,我创建了id = 2的Alice帐号并恢复了一些她的密钥。

你也可以注意到我指定了HdPathType为receive。如果你没有指定其他参数的话将会用这个作为默认值。请注意,在某些术语中使用了“external(外)”和“internal(内)”来接收和更改地址。当您收钱和消费您钱包的资金时,这是很重要的。在接收资金时,一定要用HdPathType.Receive参数;在花费资金时一定要用HdPathType.Change参数来改变地址。这将使您的钱包更加安全。当然你还可以反复使用一个相同的地址来交易,我当然反对这么做。

结语

我建议你不要应用你自己的密钥存储方案,除非你真的胸有成竹。如果由于某种原因,我的钱包方案的不足以满足您的需求,你可以在GitHub发问,我会尽我所能帮助你。

本文的版权归 飞翔的猪脚粉 所有,如需转载请联系作者。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏智能计算时代

区块链101:比特币交易是如何运作的?

简单的版本: 如果我想把我的一些比特币发送给你,我发布了我的意图,而节点扫描整个比特币网络来验证我是否有我想要发送的比特币,而2)还没有发送给其他人。一旦该信息...

3085
来自专栏区块链入门

第十三课 如何在DAPP应用实现自带钱包转账功能?

区块链是一个伟大的发明,它改变了生产关系。很多生态,有了区块链技术,可以由全公司员工的"全员合伙人"变成了全平台的”全体合伙人”了,是真正的共享经济模式。

1206
来自专栏申龙斌的程序人生

Bitcoin Core钱包常用的命令行参数

对于踏入币圈的朋友,我一直强烈建议要学习Bitcoin Core钱包软件,因为BitcoinCore这款全节点钱包是中本聪(比特币的发明人)最早实现的,虽然下载...

1512
来自专栏CSDN技术头条

玩区块链游戏谜恋猫 CryptoKitties, 学习区块链技术

以太坊是可编程的区块链,是业内公认的区块链 2.0 代表项目。可以将以太坊理解为一个操作系统,使用 Solidity 等语言编写智能合约发布应用到链上,使用 G...

1263
来自专栏Seebug漏洞平台

金钱难寐,大盗独行——以太坊 JSON-RPC 接口多种盗币手法大揭秘

2010年,Laszlo 使用 10000 个比特币购买了两张价值25美元的披萨被认为是比特币在现实世界中的第一笔交易。

772
来自专栏区块链大本营

干货 | 以太坊工具集合,解决你的入门困难

1813
来自专栏量化投资与机器学习

用Python实现一个基于RSA算法的区块链客户端(区块链系列4)

1965
来自专栏DannyHoo的专栏

iOS开发中解决Compiling IB documents for earlier than ios 7 is no longer supported的问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

771
来自专栏SAP最佳业务实践

SAP最佳业务实践:FI–资产会计(162)-2资产主数据

4 流程步骤 4.1 主数据维护 固定资产是企业拥有的对象、权限或其他项目,旨在长期使用并可在资产负债表中个别标识。维护固定资产包含创建、更改和显示资产主记录...

3336
来自专栏FreeBuf

区块链安全技术总结

区块链的安全需求越来越多,下面就将这些需求一一拆分,看看区块链安全需求到底是个什么样子。

1314

扫码关注云+社区