收藏 分销(赏)

C#区块链编程.pdf

上传人:二*** 文档编号:4479469 上传时间:2024-09-24 格式:PDF 页数:92 大小:2.78MB 下载积分:5 金币
下载 相关 举报
C#区块链编程.pdf_第1页
第1页 / 共92页
本文档共92页,全文阅读请下载到手机保存,查看更方便
资源描述
1.11.21.2.11.2.21.2.31.2.41.2.51.2.61.2.71.2.81.2.91.31.3.11.3.21.3.31.3.41.3.51.3.61.41.4.11.4.21.4.31.51.5.11.5.21.5.31.5.41.5.51.61.6.11.6.21.6.31.6.4Table of Contents介绍I.简介1.前言2.为什么是区块链编程而不是比特币编程?3.为什么是C#?4.预备条件5.本书众筹6.补充阅读7.图标8.许可:CC(ASA 3U)9.项目设置II.比特币传输1.比特币地址2.交易3.区块链4.“区块链不仅仅是比特币”5.支付比特币6.作为真实性验证方法的所有权证明III.关键的存储和数字生成机制1.足够随机了吗?2.秘钥加密3.秘钥的生成IV.其它类型的所有权1.P2PKH(向公钥付款 Hash)2.多重签名3.P2SH(向脚本哈希付款)4.灵活机动性5.使用TransactionBuilderV.其它类型的资产1.颜色币2.发行一项资产3.传输资产4.单元测试21.6.51.6.61.6.71.6.85.李嘉图合约6.流动的民主7.烧钱和声誉证明8.存在性证明3C#区块链编程Nicolas Dorier编著NBitcoi贡献者,.NET比特币框架Bill Strait联合编著Billd实验室创始人41.前言Ayn Rand在Fountain Head与我有共鸣的一篇文章GAIL WYNAND是享誉世界富有魅力的木偶大师,而HOARK HOWARD是建筑设计行业的领军人物,他们在一起言谈甚欢。GAIL发现与HOARK一起的时候,有种奇妙的放松的感觉,不知道为什么,他于是就问对方。WYNAND 问:“HOWARD,你曾经恋爱过吗?”ROARK 转面直视着他,不假思索地回答:“我现在就在谈恋爱。”“但是当走过一幢建筑的时候,你觉得还有什么比它更棒的?”“棒得多,GAIL”“我正在思考人们说的一句话,世上无快乐。看看他们多么艰辛地寻找生命中快乐的人。看看他们是如何孜孜以求的。为什么生命止于平淡呢?想想可以通过什么权利,任何人都可以因任何原因人存在于世上,而他自己的快乐除外?人人都需要它,而且人人身上的每一部分都需要它。但是人们从来没有找到它。我在思考为什么。有人喝了酒然后说不知道生命的意义。这是我特别看不起的一部分人。寻找更高级意义或者普世目标的人,不知道为了什么而活着的人,嘟囔着必须需找自我的人。你可以在周围听到尽是他们。那些好像是我们时代的标准陈词滥调。每一本书你打开,都在口沫横飞地自我忏悔。好像忏悔是一件高贵的事情。我却认为它是最令人羞耻的事情。”“看,GAIL。”ROARK起身,伸手折断了一棵树上的粗大树枝,双手紧握,一只手在一边;然后,他的手腕和指关节将树枝压弯,慢慢地变成一个拱形。“现在我可以把它做成任何我想要的东西:一张弓,一支矛、一根手杖、一条扶手。那就是生命的意义。”“你的力量?”“你的工作。”他把树枝放到一边。“世间提供给你材料,你从中制造东西.”我想区块链就像是那根树枝。对于局外人而言,感觉像是令人厌烦而毫无用处的数字集合。对于程序员和企业家而言,那就是绝佳的原材料,可以实现我们的梦想。我们赋予它意义和目标。你需要先要了解木材的特性,然后才能从一节树枝制造一张弓、一支矛或者一根手杖,同样地,你也需要知道如何编程实现区块链。我希望,你以自己的技能和智慧,将会发现可以在多大程度上利用这些看上去一无是处的数字集合。我还是需要提醒一下你:学习区块链就好像在黑客帝国中吞下红药片。你将会发现已经无法自已,想尽快辞职转而全职专攻区块链。本书将带你从区块链的基本应用走向高级应用。它不会教你如何使用API(比如比特币核心提供的RPCAPI),但是它将教你如何编写这样的API。拾遗:中本聪曾经把比特币描述成“令人厌烦的灰色。”5面向API编程可以帮你快速实现应用,但是开发者的创造性三就被限于API了。通过完整理解区块链,开发者将拥有能力充分挖掘开发区块链的潜力。62.为什么是区块链编程而不是比特币编程?区块链是金子,比特币是珠宝。我们不想把比特币比作金币,更愿意说它是珠宝。因为金子的第一个杀手级应用就是珠宝。金币来得更晚一点。你不要被蒙了,认为比特币是有瑕疵的,而区块链是珍贵的。如果金子是珍贵的,你会把金项链扔掉吗?区块链是因为比特币而建立并发展起来的。随着区块链价值的增加,更多的比特币也将会应用于区块链,从而增加了对比特币的需求。你的应用是否使用“比特币作为一种货币”的特性取决于你自己的决策。区块链是原材料,比特币是燃料。每次人们认为这种燃料也可以作为交易的媒介时,比特币作为货币的特性就出现了。相对于交易价值,你可以让区块链做得更多。你甚至不需要认为它是货币。我们将在本书中向你展示如果使用作为货币的比特币,但那不是全部。73.为什么是C#?.NET框架在公司很受欢迎。相信对于创业公司和爱好者而言也是理想的工具。.NET框架开发的代码可以在IOS、Android、Windows平板/手机、桌面、服务器以及嵌入式设备中运行。从编译器到运行时内核全部都是开源的微软创业企业扶植计划允许创业公司使用所有微软工具,包括免费使用价值150美元/月的Azure云服务。VisualStudio community2013是一个专业级别的IDE,你可以作为爱好者免费使用C#与Java和C+关系密切。而且,对于已经了解C语言的开发人员来说也很容易阅读。本书作者之一Nicolas Dorier为.NET创建了最受欢迎的比特币框架,名叫NBitcoin。你可以查看这个网址:https:/ Studio 2013-你可以在Google Bing上搜索“Visual studio 2013 community”,然后免费下载使用。比特币核心代码-你需要在开始前进行同步。拾遗:你可以咨询微软cortana或者谷歌Now了解比特币的汇率95.本书众筹如果继续为你贡献内容,我们需要购买披萨、咖啡和寿司。我们需要获得足够多的币。并且如果没有你的反馈,我们将变得漫不经心,以至于无法完成整本书籍的编写工作。因此,我们启动了下列实验,希望你感兴趣。也许有一天你会将它变成完整的商业模型。我们创建了以下内容(不需要担心,我们将在后面看到这里每一行的含义)地址:1KF8kUVHK42XzgcmJF4Lxz4wcL5WDL97PB签名:H1jiXPzun3rXi0N9v9R5fAWrfEae9WPmlL5DJBj1eTStSvpKdRR8Io6/uT9tGH/3OnzG6ym5yytuWoA9ahkC3dQ=信息:Nicolas Dorier Book Funding Address现在我们开始编写本书。当我们肚子饿了,我们就暂停,要求得到本书一下章节的资金支持。你将通过编程完成一个挑战的形式进行汇款,简单地使用钱包汇款将不算数。捐赠人员将通过他们的比特币地址授权获得下一章节。没有任何数字版权管理。如果你没有通过汇款取得了本书,希望你能按照本书的指引汇款。我们将进入下一章节的详细内容。不要掉以轻心,你需要通过编程学会如何使用它。你可以在这个网址上得到更多介绍:http:/ Bitcoin,Andreas M.Antonopoulos编著Nicolas Dorier关于CodeProject的文章(http:/ 3U)如前面“本书众筹”部分描述的一样,我们将向资金支持者的比特币地址分发本书。一旦获得本书,你就可以免费分享和修改,具体参照署名-相同方式共享3.0未本地化版(CC BY-SA3.0)。在免费获得本书后,如果在提醒时给点小费,我们将不胜感激。加密货币拥趸可能说:股权证明和工作量证明是最好的感情表达方式,其它都是浮云。139.项目设置在开始前,我们想告诉你项目的设置要求。1.打开Visual Studio,创建一个新的ConsoleApplication。命名为“ProgrammingBlockchain”。2.在SolutionExplorer中右键打开“Reference”,选择“Manage NuGet Packages”3.搜索“NBitcoin”并安装。注意:下图仅供参考。实际版本和发布日期因你阅读本书的时间而不同。4.在Solution Explorer中右键打开“ProgrammingBlockchain”,选择“Add”,然后“NewFolder”,命名文件夹为“Chapters”。5.右键打开“Chapters”并选择“Add”然后“New Class”。命名这个类为“Chapter1”。在本书的其它章节也如此这般做法。6.打开“Program.cs”,并添加以下代码。14using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Text;using ProgrammingBlockchain.Chapters;namespace ProgrammingBlockchain class Program static void Main(string args)/Select the chapter here.var chapter=new Chapter1();/call the lesson here.chapter.Lesson4();/this will hold the window open for you to read the output.Console.WriteLine(nnnPress enter to continue.);Console.ReadLine();7.注意“using ProgrammingBlockchain.Chapters;”被添加到正在使用的区块。8.这时候,Visual Studio在抱怨“chapter.Lesson1()”不存在。继续阅读本书,我们将创建它。151.比特币地址你的比特币地址是用来接收别人付款的。你也许知道,钱包软件使用私钥来付款。一个比特币地址由两部分组成,一部分是公钥哈希值经过Base58check 编码的组合,另一部分是关于这个网络地址的信息。Base58check 编码有一些很精巧的特性,比如用于避免拼写错误的验证码,避免模糊的字符比如“0”和“O”。拾遗:TestNet是用于开发目的的比特币网络,在这个网上的比特币没有任何价值。MainNet才是人人知道的比特币网络你也许不知道,就区块链而言,还谈不上比特币地址。内部来说,比特币协议使用ScriptPubKey验证比特币的接收动作。ScriptPubKey是一段简短的脚本,用于解释在什么情况下才能声明比特币的所有权。随着本书深入分析,我们将考察ScriptPubKey指令的类型。ScriptPubKey也许包含哈希计算过的公钥,这个公钥允许支付比特币。拾遗:在MainNet上进行比特币编程时犯的错误印象更加深刻下图说明了公钥、私钥、比特币地址和ScriptPubKey的关系。现在我们可以用代码向你演示它们的关系了。打开Chapter1.cs,在顶部添加“using NBitcoin;”然后编写下面的方法。16public void Lesson1()Key key=new Key();/generates a new private key.PubKey pubKey=key.PubKey;/gets the matching public key.Console.WriteLine(Public Key:0,pubKey);KeyId hash=pubKey.Hash;/gets a hash of the public key.Console.WriteLine(Hashed public key:0,hash);BitcoinAddress address=pubKey.GetAddress(Network.Main);/retrieves the bitcoin address.Console.WriteLine(Address:0,address);Script scriptPubKeyFromAddress=address.ScriptPubKey;Console.WriteLine(ScriptPubKey from address:0,scriptPubKeyFromAddress);Script scriptPubKeyFromHash=hash.ScriptPubKey;Console.WriteLine(ScriptPubKey from hash:0,scriptPubKeyFromHash);按F5检查输出。你刚刚学到了如何创建一个私钥,对应的公钥、公钥哈希、比特币地址和ScriptPubKey。我们还没有深入细节,注意ScriptPubKey看上去跟比特币地址没有关系,但是它的确显示了公钥的哈希值。注意我们为何能从比特币地址产生ScriptPubKey?这一步就是所有比特币客户端做的事情,它把人机交互友好的比特币地址翻译成区块链可读的地址。比特币地址由一个网络识别码和公钥哈希组成。学习到这些,就可以由ScriptPubKey和网络识别码产生比特币地址,如下面代码所示:public void Lesson2()Script scriptPubKey=new Script(OP_DUP OP_HASH160 1b2da6ee52ac5cd5e96d2964f12a0241851f8d2a OP_EQUALVERIFY OP_CHECKSIG);BitcoinAddress address=scriptPubKey.GetDestinationAddress(Network.Main);Console.WriteLine(Bitcoin Address:0,address);比特币地址:13Uhw9BmdaXbnjDXiEd4HU4yesj7kKjxCo也可以从ScriptPubKey取回哈希值,产生一个比特币地址,就像我们在Lesson1()里面展示的那样。17public void Lesson3()Script scriptPubKey=new Script(OP_DUP OP_HASH160 1b2da6ee52ac5cd5e96d2964f12a0241851f8d2a OP_EQUALVERIFY OP_CHECKSIG);KeyId hash=(KeyId)scriptPubKey.GetDestination();Console.WriteLine(Public Key Hash:0,hash);BitcoinAddress address=new BitcoinAddress(hash,Network.Main);Console.WriteLine(Bitcoin Address:0,address);公钥哈希:1b2da6ee52ac5cd5e96d2964f12a0241851f8d2a比特币地址:13Uhw9BmdaXbnjDXiEd4HU4yesj7kKjxCo拾遗:公钥哈希值的产生过程使,先将公钥进行SHA256哈希计算,结果再进行RIPEMD160哈希计算,按高位优先记录最终结果。函数看起来是这样的:RIPEMD160(SHA256(pubkey)那么现在你应该理解私钥、公钥、公钥哈希、比特币地址和ScriptPubKey的关系了。私钥通常用Base58Check 编码表示,叫做比特币密码(也叫钱包导入格式,简称WIF),就像比特币地址那样。本书的其余部分,你将使用自己产生的一个地址。注意很容易就可以从比特币密码产生私钥。特别记住,从比特币地址产生公钥是不可能的,因为比特币地址含有公钥哈希但不是公钥本身。public void Lesson4()Key key=new Key();BitcoinSecret secret=key.GetBitcoinSecret(Network.Main);Console.WriteLine(Bitcoin Secret:0,secret);比特币密码:KyVVPaNYFWgSCwkvhMG3TruG1rUQ5o7J3fX7k8w7EepQuUQACfwE复制你得到的比特币密码,在Program.cs的main方法中添加如下代码,代替提供给你的密码。18BitcoinSecret paymentSecret=newBitcoinSecret(KyVVPaNYFWgSCwkvhMG3TruG1rUQ5o7J3fX7k8w7EepQuUQACfwE);练习:注意你自己产生的私钥将用于本身的其余部分,包括它的地址。在本书的其余部分,我将自己的私钥存储在变量BitcoinSecret paymentSecret中。练习:取得paymentSecret的比特币地址,存储到paymentAddress,在Bitcoin Core上发送一些币到上面。比如0.01比特币,感到顺手的时候可以增加一些。192.交易在开始前,记住要创建一个新章节的类。交易是比特币的传输。一个交易可能没有接受者,或者有好几个。发送者也一样。在区块链上,发送者和接受者总是被抽象为ScriptPubKey,就像我们在第10章演示的一样。假设你已经学习完了第4课以及相关的练习,我们继续向前。如果你没有完成练习,继续前请向先前你生成的地址汇款。如果你使用Bitcoin Core,你的交易标签页将如下显示交易信息:现在我们关注一下交易ID。这里它就是:f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94交易ID由SHA256定义。不要使用交易ID处理未经确认的交易。在正式确认前交易ID是可以被更改的,叫做“交易可塑性”你可以在类似Blockchain.info这样网站上检查交易,但是作为一个开发人员,你将需要一个易于查询分析的服务。截止本文时,我们发现Blockr.io是一个不错的服务。如果你上http:/btc.blockr.io/api/v1/tx/raw/f13dc48fb035bbf0a6e989a26b3ecb57b84f85e0836e777d6edf60d87a4a2d94看看,就可以看到交易的原始字节。NBitcoin查询blockr,为你分析信息,所以你就不需要手工来做了。20public void Lesson1()var blockr=new BlockrTransactionRepository();Transaction transaction=blockr.Get(4ebf7f7ca0a5dafd10b9bd74d8cb93a6eb0831bcb637fec8e8aabf8 42f1c2688);Console.WriteLine(transaction.ToString();hash:4ebf7f7ca0a5dafd10b9bd74d8cb93a6eb0831bcb637fec8e8aabf842f1c2688,ver:1,vin_sz:1,vout_sz:2,lock_time:0,size:225,in:prev_out:hash:bf7d91ac70917f98b497927e1b07267507652b206df14ecdba2e9390b9bffc65,n:0 ,scriptSig:3044022069b6b0f1a8d453bdb89e3ad475232b8e01d2851e7b53acab3f830f40e80b3b5102203c049 867975360020293c735d48b4a2dda003aa781c1d8ccd2c7af290dcd11de01 02e3538427350039e67ea99e935cefb740badf3d09ebc301b0bc9d1bb0301a3417,out:value:0.08990000,scriptPubKey:OP_DUP OP_HASH160 5b1d720daf0e95e37d0eaedd282b6ed9a40bab71 OP_EQUALVERIFY OP_CHECKSIG,value:0.01000000,scriptPubKey:OP_DUP OP_HASH160 71049fd47ba2107db70d53b127cae4ff0a37b4ab OP_EQUALVERIFY OP_CHECKSIG现在相关部分包括in和out。你可以看到0.0899比特币被发送给ScriptPubKey,0.01比特币被发送到另外一个地方。(练习:验证ScriptPubKey中的公钥是否与你付款地址相关联的一样)如果你注意一下in,你就发现prev_out(先前的out)被引用了。每一个in都告诉你先前的哪一个out被使用了,这样就可以为交易付款。术语TxOut和Output对Out是匿名的。总的来说,TxOut代表一定数量的比特币和一个ScriptPubKey。(接收端)21每一个out都有一个由交易ID和索引定义的地址,叫做Outpoint。比如,在我的这次交易中0.01比特币的out对应的Outpoint就是(71049fd47ba2107db70d53b127cae4ff0a37b4ab,1).现在让我们看看交易中的in(也叫TxIn、Inputs)TxIn包含正在花出去的prev_out的出口、以及同时被叫做“所有权证明”的ScriptSig。在我的例子里,prev_out的出口是(7def8a69a7a2c14948f3c4b9033b7b30f230308b,0)我们代换第一课代码中的交易ID,就可以检查交易相关的信息。我们可以继续按此方法追踪这个交易ID到比特币的coinbase,也就是他们被挖出来时所在的区块。在我们的例子里,prev_out总使用量为0.1BTC。在这次交易中,0.0899BTC和0.01BTC都被发出去了。意味着还有0.0001BTC没有下落。发送和收到之间的差额被称之为交易费用或者挖矿费用。矿工将指定的交易包含在区块里面,因此需要收费。223.区块链你也许注意到,当我们证明发出去的TxOut所有权时,并没有证明TxOut的实际存在。这就是区块链的主要作用一显身手的地方:区块链是所有交易的数据库,记录了第一个比特币交易以来的所有信息,第一个区块又叫做创始块。区块链在全世界范围内被复制。如果你使用比特币核心,你的电脑上将拥有所有区块链。一旦在区块链上发生交易,那就不能否认它的发生了。矿工只有一个目标,就是在区块链中插入一条交易记录。一组新的交易被添加后,一个区块就被全网广播了。网络上的其它节点确认这个新的区块遵守先前设定的比特币协议。创建一个区块成本很高。如果一个矿工企图增加一个无效的交易,其它节点将不会认可这个区块,矿工在创建这个区块时花费的投资将打水漂。一旦矿工提交了一个有效的区块,里面所有的交易都将被确认。当这个发生时,所有矿工都必须放下手中的工作,开始新的交易。一个区块被确认后,它就被写进区块链了。随着后面继续加入新的区块,它被撤销的概率也就越来越低。在历史上我们第一次拥有的这样一个数据库,它不能被轻易地改写,不再需要信任和审查机制,而且是大范围分布式的。如果我们把比特币当作是一种货币,那区块链就是一套账本。区块链是一个数据库,你给里面的数据赋予含义。你很快就可以发现,一次比特币交易包含的信息远远超过比特币的传输。一次比特币交易在数据库中就是一行记录,永远不可能擦除。作为用户,你可以通过两种不同的方法验证一次交易是否已经记录在区块链里面。检查整个区块链,它在写作本书时有好几个GB大小寻求一颗merkel树,大概有几K。我们将介绍merkel树的更多内容,它与简单支付验证有关联。234.“区块链不仅仅是比特币”有意思的是,同样的语句,有两组不同人的解读。一组人认为比特币是货币,他们相信比特币的价值将牛气冲天。另一组人并不认为比特币作为货币会取得成功,他们试图解释比特币如此有趣的原因。但是有一件事情是我们都认同的:一个不可更改的数据库,它不会被审查、干预和擦写,而且在全世界都有副本,它将对其它行业产生巨大的深远影响。公证员在法庭上记录案件事实,他们就可以将相关文件档案永久地存储在区块链里面。审计将变得自动化而且更有说服力,那时产权归属的存储和交割都在区块链上完成。所有资金周转情况可以公开证明他们的清偿能力。自动化交易脚本可以让交易自动发生,不需要人工干预或者中心权威机构的授权。本书的其余部分,我们将探讨一些基本原理,这些基本原理支撑了以上技术的运转,以及更多其它内容。从支付一个比特币开始吧。245.支付比特币你现在已经了解什么是比特币地址、ScriptPubKey、私钥和矿工了,可以手动完成第一个交易了。创建一个新类Chapter14以及一个方法Lesson1。在你阅读本章节的时候,你需要按照书中所述逐行添加代码创建方法,这个方法将为本书留一个Twitter消息风格的反馈。我们先看看这个交易,它包含了你需要支付的TxOut,就好像我们在第11章做的那样。var blockr=new BlockrTransactionRepository();Transaction fundingTransaction=blockr.Get(0b948b0674a3dbd229b2a0b436e0fce8aa84e6de28b088c610d110c2bf54acb4);在我们的例子里,我们需要使用第二次output:为了完成支付,你需要在交易里面提到这个output。可以如下创建一个交易:Transaction payment=new Transaction();payment.Inputs.Add(new TxIn()PrevOut=new OutPoint(fundingTransaction.GetHash(),1);现在我们注意一下Output。你需要发送0.004BTC,而你支付了0.04BTC,所以需要找给你0.006BTC。同时也需要给矿工一些费用,这样他们好把这次交易添加到他们的下一个区块里面去。因此,你将拿回来0.0059BTC。25本书的捐献地址:1KF8kUVHK42XzgcmJF4Lxz4wcL5WDL97PBvar programmingBlockchain=new BitcoinAddress(1KF8kUVHK42XzgcmJF4Lxz4wcL5WDL97PB);payment.Outputs.Add(new TxOut()Value=Money.Coins(0.004m),ScriptPubKey=programmingBlockchain.ScriptPubKey);payment.Outputs.Add(new TxOut()Value=Money.Coins(0.0059m),ScriptPubKey=paymentAddress.ScriptPubKey);现在可以添加你的反馈了。必须少于40字节,不然它就崩溃了。/Feedback!var message=Thanks!:);var bytes=Encoding.UTF8.GetBytes(message);payment.Outputs.Add(new TxOut()Value=Money.Zero,ScriptPubKey=TxNullDataTemplate.Instance.GenerateScriptPubKey(bytes);Console.WriteLine(payment);26 hash:258ed68ac5a813fe95a6366d94701314f59af1446dda2360cf6f8e505e3fd1b6,ver:1,vin_sz:1,vout_sz:3,lock_time:0,size:166,in:prev_out:hash:4ebf7f7ca0a5dafd10b9bd74d8cb93a6eb0831bcb637fec8e8aabf842f1c2688,n:1 ,scriptSig:,out:value:0.00400000,scriptPubKey:OP_DUP OP_HASH160 c81e8e7b7ffca043b088a992795b15887c961592 OP_EQUALVERIFY OP_CHECKSIG ,value:0.00590000,scriptPubKey:OP_DUP OP_HASH160 71049fd47ba2107db70d53b127cae4ff0a37b4ab OP_EQUALVERIFY OP_CHECKSIG ,value:0.00000000,scriptPubKey:OP_RETURN 42696c6c20537472616974206973207570646174696e672073637265656e73686f74732e 现在我们就完成创建交易了,我们需要对它签名。换句话来说,你需要证明拥有在input里面提到的TxOut。签名比较复杂,细节可以参考:https:/en.bitcoin.it/w/images/en/7/70/Bitcoin_OpCheckSig_InDetail.png。但是我们可以简单一些。首先在scriptSig中插入ScriptPubKey。ScriptPubKey无非就是 paymentAddress.ScriptPubKey,很简单。27payment.Inputs0.ScriptSig=paymentAddress.ScriptPubKey;/also OK:/payment.Inputs0.ScriptSig=/fundingTransaction.Outputs1.ScriptPubKey;payment.Sign(paymentSecret,false);Console.WriteLine(payment);恭喜,你可以在第一个交易上完成签名了。你的交易已经准备好了。剩下的就是发布到网上去让矿工们可以看得到。保证比特币核心正在运行,然后:using(var node=Node.ConnectToLocal(Network.Main)/Connect to the node node.VersionHandshake();/Say hello /Advertize your transaction(send just the hash)node.SendMessage(new InvPayload(InventoryType.MSG_TX,payment.GetHash();/Send it node.SendMessage(new TxPayload(payment);Thread.Sleep(500);/Wait a bitusing代码段将负责断开与节点的链接。以上就是全部!你可以直接连到比特币网络但是,我建议你连接到自己的可信节点(更快更便捷)286.作为真实性验证方法的所有权证明在开始下一章节前,我授予你一个秘钥,用于向我付款。还记得我说的吗:地址:1KF8kUVHK42XzgcmJF4Lxz4wcL5WDL97PB签名:H1jiXPzun3rXi0N9v9R5fAWrfEae9WPmlL5DJBj1eTStSvpKdRR8Io6/uT9tGH/3OnzG6ym5yytuWoA9ahkC3dQ=消息:Nicolas Dorier Book Funding Address这些构成了我拥有这本书私钥的证明。你可以通过下面的代码验证正确性:var address=new BitcoinAddress(1KF8kUVHK42XzgcmJF4Lxz4wcL5WDL97PB);var msg=Nicolas Dorier Book Funding Address;var sig=H1jiXPzun3rXi0N9v9R5fAWrfEae9WPmlL5DJBj1eTStSvpKdRR8Io6/uT9tGH/3OnzG6ym5yytuWoA9ahkC3dQ=;Console.WriteLine(address.VerifyMessage(msg,sig);这些就是我将授予你的。因此如果我给你这个任务:消息:“Prove me you are 1LUtd66PcpPx64GERqufPygYEWBQR2PUN6”你可以使用私钥按照以下方法证明:msg=Prove me you are 1LUtd66PcpPx64GERqufPygYEWBQR2PUN6;sig=paymentSecret.PrivateKey.SignMessage(msg);Console.WriteLine(paymentSecret.GetAddress().VerifyMessage(msg,sig);你将被提醒在以下网址证明自己的ID:http:/ Key()时,实际上是在用PRNG(伪随机数生成器)来产生私钥。在windows平台上,就是用系统提供的RNGCryptoServiceProvider。.在安卓上,我使用SecureRandom,实际上你可以自己实现RandomUtils.Random然后使用它。在IOS上,我还没用实现,你需要自己实现IRandom。对一台电脑来说,随机是很难的。但是最大的问题是,几乎不可能知道一串数字是否真的是随机的。如果有个恶意软件修改了你的PRNG(当然可以预测你将产生的随机数),当你发现时已经太迟了。这就意味着跨平台的PRNG实现(就好像使用电脑时钟加上CPU速度)是危险的,但是当你发现时已经太迟了。出于效率的考虑,大多数PRNG工作方法都是一样的:选择一个随机数,称为种子,然后每次你需要的时候,一个可预测的规则就会为你产生下一个数字。种子的随机程度由熵的测量来定义,但是熵的大小同时取决于观察者。假设你从时钟时间产生一个种子,并且你的时钟分辨率可能是1ms。(实际上是更多,大约15ms)如果黑客知道上星期你产生了key,那么你的种子有1000 60 60 24 7=604800000种可能性。对这个黑客来说,熵就是LOG(604800000;2)=29.17 bits。在我的家用电脑上遍历这样的数字用不了2秒钟,我们把这种遍历叫“暴力攻击”。然而,如果你使用时钟时间+进程ID来产生种子,并且假设有1024个不同的进程ID。那么,现在黑客就需要遍历604800000*1024种可能性,大概需要耗时2000秒。然后,如果再加上我打开电脑的时间,就算黑客知道我是在今天打开的话,那也有86400000种可能性。这样的话,黑客需要遍历604800000 1024 86400000=5,35088E+19种可能性。可是,注意如果黑客攻击了我的电脑,他就可以获得最后的信息片段,减少数字的可能性,从而减少熵。熵按照LOG(possibilities;2)来测量,所以LOG(5,35088E+19;2)=65 bits。足够了吗?也许,如果你面临的黑客不知道可能世界里的更多信息的话。但是既然公钥的哈希是20bytes=160bits,比所有地址空间要小,所以你可以做得更好。注意:增加熵的难度是线性递增的,攻击熵的难度是指数递增的。一种可以快速产生熵的有趣方法就是人类的干预。(比如移动鼠标)如果你不完全信任PRNG平台(并不奇怪),你可以给NBitcoin使用的PRNG输出增加熵。30RandomUtils.AddEntropy(hello);RandomUtils.AddEntropy(new byte 1,2,3);var nsaProofKey=new Key();调用AddEntropy(data)时NBitcoin做的事情如下:additionalEntropy=SHA(SHA(data)additionalEntropy)当你产生一个新数字的时候:result=SHA(PRNG()additio
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 通信科技 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服