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 条评论
登录 后参与评论

相关文章

来自专栏区块链技术开发与技术解决方案

区块链公司谈的硬分叉和软分叉是什么

编程术语中的“fork”是一个开源代码修改。通常,分叉代码与原始代码相似,但有重要的修改,并且两个“叉”舒适地共存。有时使用分支来测试流程,但使用加密货币时,它...

1102
来自专栏黑白安全

黑客利用病毒挖门罗币 已获利 60 余万

火绒安全团队截获一批蠕虫病毒。这些病毒通过U盘、移动硬盘等移动介质及网络驱动器传播,入侵电脑后,会远程下载各类病毒模块,以牟取利益。这些被下载的有盗号木马、挖矿...

1193
来自专栏区块链入门

第三课 以太坊术语说明及开发者资源列表

也称钱包,提供账户管理、挖矿、转账、智能合约的部署和执行等等功能,以太坊节点利用以太坊客户端接入到以太坊网络。 现在以太坊客户端主要有:Wallent/ist ...

632
来自专栏FreeBuf

下一个猎杀目标 | 近期大量MySQL数据库遭勒索攻击

随着MongoDB, ElasticSearch, Hadoop, CouchDB和Cassandra服务器的的沦陷,MySQL数据库成了攻击者的下一个猎杀目标...

2216
来自专栏区块链领域

以太坊潜伏多年令全球黑客为之疯狂的“偷渡”漏洞引发偷币狂潮

世界上有一群人,互联网对于他们来说就是提款机。 是的,过去是,现在更是,因为电子货币的出现,他们提款的速度变得更疯狂。 在2017年,我们的蜜罐监测到一起针对以...

3289
来自专栏极客编程

.netcore如何开发以太坊区块链示例 原

本文描述了在dotNet核心中使用像以太坊这样的区块链平台的过程。目标受众是其他想要从以太坊开始的dotNet开发者。需要了解区块链。在本文中,我们构建了一个完...

612
来自专栏蜉蝣禅修之道

以太坊DApp系列(二)---从入门到出家

以太坊自2013年V神提出后,被无数人赋予美好的愿景,甚至被称为区块链2.0,其代币发行量更是达到了全球第二,仅次于比特币,而其带来的智能合约概念颠覆了人们对区...

82618
来自专栏醒者呆

探路以太坊

关键字:以太坊,加密货币,crowdsale,geth,console,web3.js 以太坊简介 一句话简介:以太坊是一个基于功能齐全的编程语言构建的...

3306
来自专栏FreeBuf

利用树莓派探索以太坊第一部分:环境搭建

在本系列文章的第一部分中,我们将在一台树莓派Pi 3 Model B上安装并运行一个以太坊区块链客户端。 ? 毫无疑问,区块链绝对是当前的热点。之所以会这样,...

3786
来自专栏醒者呆

区块链3.0:拥抱EOS

EOS是当下最火的区块链技术,被社会广泛看好为下一代区块链3.0。不同于以太坊的学习,EOS的主语言是C++,本文作为EOS研究的首篇文章,重点介绍EOS的创...

1.1K12

扫码关注云+社区