专栏首页申龙斌的程序人生用NBitcoin进行区块链开发

用NBitcoin进行区块链开发

Bitcoin Core是根正苗红的比特币全节点钱包软件,由创始人中本聪最早完成,编程语言是C++,对于一些现代程序员来说,理解起来有一定难度,所以有些开发者将这些代码移植为其它编程语言。

Bitcoin在.NET平台的一款实现就是今天要介绍的NBitcoin,项目站点:

https://github.com/MetacoSA/NBitcoin

我使用的软件集成开发平台是Visual Studio 2015,.Net Framework是4.5.2。

安装NBitcoin引用

我建立了一个控制台应用HelloBitcoin,需要添加NBitcoin类库的引用,最方便的办法是用NuGet,操作办法见下图,注意可能需要访问外国网站。

安装过程中,会对整个解决方案的依赖类库进行一系列修改, 并且让你接受软件许可授权,可能涉及到的类库:

Newtonsoft.Json 11.0.2

System.Buffers 4.5.0

System.Collections 4.0.11

System.Collections.Concurrent 4.0.12

System.Diagnostics.Debug 4.0.11

System.Globalization 4.0.11

System.Linq 4.1.0

System.Net.Http 4.3.3

System.Net.Requests 4.3.0

System.Reflection 4.1.0

System.Resources.ResourceManager 4.0.1

System.Runtime.Extensions 4.1.0

System.Runtime.InteropServices 4.1.0

Microsoft.Extensions.Logging.Abstractions 1.0.2

最后在调试输出窗口中出现这样一行:

已将“NBitcoin 4.1.1.71”成功安装到 HelloBitcoin

表示NBitcoin安装成功。

用私钥生成比特币地址

下面一段简单的代码用来将一串私钥生成为比特币地址,请与《我生成的比特币地址竟然与别人的重合了》这篇文章一起参考阅读。

程序开头不要忘记这一行:

using NBitcoin;

直接上代码:

简要解释说明一下:

privKeys是私钥,为256位二进制数,NBitcoin中与私钥对应的类是Key。

下面这行语句生成一个随机私钥。

Key k = new Key();

私钥可以生成公钥,再生成比特币地址,借用一下《精通比特币》中的这张原理图。

Network.Main表示使用比特币的真实主网络,直接用真金白银的BTC调试程序太奢侈,可以切换到测试网络Network.TestNet。

程序最终输出:

19t4GGYorFziM26CRMYvxqvDw6NPhuCRJS

对应于BitcoinExplorer工具的命令行是:

bx ec-to-public 3243......E6C8 | bx bitcoin160 | bx address-encode

可以看到,最后生成的比特币地址是一致的。

压缩公钥、非压缩公钥

一个私钥实际上可以产生出两种不同的比特币地址,这个问题有点迷惑人,但这是由于椭圆曲线的特性造成的,先看代码。

k1生成出来的是压缩公钥:

为了方便阅读,我人为插入了空格。

02 2e88d239fb78cee0c1c55943a96dcc8b70adf47e18b53f9ba110b6fb871e1f8b

k2对应于非压缩公钥:

请注意与上面的区别。

04 2e88d239fb78cee0c1c55943a96dcc8b70adf47e18b53f9ba110b6fb871e1f8b b119f9161df032167181d623a401dde4091c3e0be2001e4dea3e1f53f851aa3a

拆开说明这一长串数字的具体含义:

04 // 表示非压缩公钥

2e88d239fb78cee0c1c55943a96dcc8b70adf47e18b53f9ba110b6fb871e1f8b // 椭圆曲线上点的X坐标

b119f9161df032167181d623a401dde4091c3e0be2001e4dea3e1f53f851aa3a // 椭圆曲线上点的Y坐标

椭圆曲线有一个重要特性,它是以X轴为对称轴的,这样记录一个点的坐标时,只需要记录X坐标,省略Y坐标,只需要知道Y坐标的正负号,就可以根据X计算出Y。

在二进制的椭圆曲线运算中,没有正负号,但有奇偶性,只记录X坐标及奇偶性,就是压缩公钥的表示法,刚才的那个公钥就可以节省一半的存储空间。

02 // 表示压缩公钥,Y坐标为偶数

2e88d239fb78cee0c1c55943a96dcc8b70adf47e18b53f9ba110b6fb871e1f8b // 椭圆曲线上点的X坐标

两种公钥表现形式不一样,生成的比特币地址当然就不一样:

地址1:

19t4GGYorFziM26CRMYvxqvDw6NPhuCRJS

地址2:

17mKugcBDEJbu391Fq41AdwLeGHwJLPRDf

比特币的交易信息中经常存储公钥,压缩公钥节省了大量存储空间,意义重大,后来的钱包软件主要都使用压缩公钥,也就是常用上面的地址1

19t4GGYorFziM26CRMYvxqvDw6NPhuCRJS

WIF钱包导入格式

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

用GetWif()函数可以非常容易地得到WIF格式的私钥。

以K开头的为压缩表示法:

KxuRLWqnfcgs8ru7YiMBfP6T71jK9twCedaeBtHgRgzb8adnoZzH

以5开头的是非压缩表示法,但本质上两个私钥是一模一样的:

5JCRYcJrKGLTK6R3PbHopfY9BRdmtrq5TCTesx7x9mQUDeYDfZj

P2SH地址、隔离见证地址

前面见到的比特币地址都是以1开头的:

19t4GGYorFziM26CRMYvxqvDw6NPhuCRJS

17mKugcBDEJbu391Fq41AdwLeGHwJLPRDf

很多人现在看到的是以3开头的地址,这种地址术语是P2SH地址,即Pay-to-Script Hash地址,这类地址是由交易脚本创建的,具体原理先不用了解,代码很方便。

pk1.GetScriptAddress(Network.Main)

结果是这样的:

33yjfa31iqdDRqHqQRuvySB7SVV7wd77aj

后来又出来了隔离见证地址,采用Bech32格式编码。

pk1.GetSegwitAddress(Network.Main)

样子是这样的: bc1qv950rspcgfqufasc29calr5qphh4ucl3ur7vnm

看到这样的地址别以为收到了假比特币。

以前在给多个人发币时,使用NBitcoin时踩了一些坑:

当时想参考NBitcoin的API文档:

https://metacosa.github.io/NBitcoin/api/index.html

可惜文档非常糟糕,还不如果直接看源代码,几乎是边google边试错完成了程序。

所以我准备把更详细的使用方法逐步整理出来,请留言或点赞,给我助力。

--- END ---

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

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

原始发表时间:2018-11-29

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 零基础学编程005:打印一行复利数据

    问题 上次文章《集成开发环境IDE》里留了一道练习题: 如何用Python打印这篇枯燥的《复利数据表》: (1+0.01) ^ 1 = 1.01 (1+0.0...

    申龙斌
  • 通过欧拉计划学Rust编程(第345题)

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

    申龙斌
  • 用API在Bigone上提交一笔订单

    想写一个交易所的量化程序,第一步得利用API建立一笔订单,比如,我想在EOS-BTC市场中创建一笔卖单,价格为0.002985,数量为1个EOS。

    申龙斌
  • 一个scrapy框架的爬虫(爬取京东图书)

    我们的这个爬虫设计来爬取京东图书(jd.com)。 scrapy框架相信大家比较了解了。里面有很多复杂的机制,超出本文的范围。 1、爬虫spider tips:...

    用户1225216
  • 不知道怎么买币?一文带给你当下最火爆最具潜力的加密货币介绍!

    从2017年底出现的加密货币奇点到容纳众多Altcoin、实用Token、新协议、优秀的落地项目和智能合约平台的整个生态系统,数字加密货币的历史是丰富的、动态的...

    区块链大本营
  • 关与代码重构那些事

    说个我朋友的事(我的一个朋友系列)。这个人颇有些强迫症。他在入职某家公司一段时间后,实在受不了负责模块那些祖传代码的组织方式,就用工作之余的的时间彻底重构了部分...

    Fundebug
  • AngularJS在自动化测试中的应用

    1、AngularJS是一组用来开发web页面的框架、模板以及数据绑定和丰富UI的组件;

    宜信技术学院
  • 热爱物理的Mma们~~~电偶极子的电势和电场~~~

    WolframChina
  • 浅谈现代前端框架技术思想

    本篇文章并没有涉及到如何设计一个前端框架具体的技术细节,而是从更上层的角度去谈现代的前端框架是如何进行抽象的。就像作者说的那样,抽象,本质上是一种泛化与概括的思...

    桃翁
  • 启动IIS站点时报错WAS未启动

    命令行执行iisreset报错:IIS 服务或万维网发布服务,或者依赖这两种服务的某个服务未能启动。该服务或所依赖的服务可能在启动期间发生错误或者已禁用。

    shawyang

扫码关注云+社区

领取腾讯云代金券