工作,学习,生活,这里将会有一些记录. 备用域名:http://meisw.51099.com 注册 | 登陆
浏览模式: 标准 | 列表2017年09月的文章

批量导入私钥的比特币钱包

 你写个linux shell(或windows批处理),内容如下
bitcoind importprivkey 私钥1
bitcoind importprivkey 私钥2
bitcoind importprivkey 私钥3
……

就OK了


-------------

大虾版:如果想在wallet.dat里生成大量地址,使用以下命令:-keypool= Set key pool size to (default: 100)再使用比特币钱包管理工具Pywallet把结果提取出来。 菜鸟版: 给大家介绍个网站bitaddress.org,是一个单一的 HTML文件,可以把它保存下来,到离线的电脑上生成大量的地址,使用Bulk Wallet/批量钱包标签,来批量生成地址。Javascript的表现可能会影响生成速度,以目前的硬件水平,可以每分钟生成大约100 ...



--------------

给大家介绍个网站bitaddress.org,是一个单一的 HTML文件,可以把它保存下来,到离线的电脑上生成大量的地址,使用Bulk Wallet/批量钱包标签,来批量生成地址。Javascript的表现可能会影响生成速度,以目前的硬件水平,可以每分钟生成大约1000个地址。要是你愿意等上几个小时(要不让它跑一个晚上),就可以达到你的要求啦。

什么是SPV钱包(轻钱包)?

 

 
SPV、SPV节点和SPV钱包
 
一、什么是SPV
 
SPV是“Simplified Payment Verification”(简单支付验证)的缩写。中本聪论文简要地提及了这一概念,指出:不运行完全节点也可验证支付,用户只需要保存所有的block header就可以了。用户虽然不能自己验证交易,但如果能够从区块链的某处找到相符的交易,他就可以知道网络已经认可了这笔交易,而且得到了网络的多少个确认。
 
按照中本聪的原文,这里有个细节需要注意,SPV指的是“支付验证“,而不是“交易验证”。这两种验证有很大区别。
"交易验证”非常复杂,涉及到验证是否有足够余额可供支出、是否存在双花、脚本能否通过等等,通常由运行完全节点的矿工来完成。
“支付验证”则比较简单,只判断用于“支付”的那笔交易是否已经被验证过,并得到了多少的算力保护(多少确认数)。
 
考虑这样一种情况,A收到来自B的一个通知,B声称他已经从某某账户中汇款一定数额的钱给了A。去中心方式下,没有任何人能证明B的可靠。接到这一通知,A如何能判断B所说的是真的呢?
在比特币系统中,这一通知是以一个固定格式的“交易"来实现的,该交易中包含B的汇款账户、B的签名、汇给A的金额以及A的地址。
如果A想本人亲自验证这笔交易,首先,A要遍历区块链账本,定位到B的账户上,这样才能查看B所给的账户上是否曾经有足够的金额;接下来,A要遍历后续的所有账本,看B是否已经支出了这个账户上的钱给别人(是否存在双花欺骗);然后还要验证脚本来判断B是否拥有该账户的支配权。这一过程要求A必须得到完整的区块链才行。
 
但是,如果A只想知道这笔支付是否已经得到了验证(如果验证了就发货),他可以依赖比特币系统来快速验证。即,检查发生此项支付的那笔交易是否已经收录于区块链中,并得到了多少个确认。
 
原理:block header中有三个关键字段,一是prev_block_hash(前一区块的hash值,确保了区块链所记录的交易次序);二是bits(当前区块的计算难度), 三是merkle_root_hash(借助merkle tree算法,确保收录与区块中所有交易的真实性)。
 
验证某个交易是否真实存在时,理论上,用户可以通过以下方式进行验证:
0. 从网络上获取并保存最长链的所有block header至本地;
1. 计算该交易的hash值tx_hash;
2. 定位到包含该tx_hash所在的区块,验证block header是否包含在已知的最长链中;
3. 从区块中获取构建merkle tree所需的hash值;
4. 根据这些hash值计算merkle_root_hash;
5. 若计算结果与block header中的merkle_root_hash相等,则交易真实存在。
6. 根据该block header所处的位置,确定该交易已经得到多少个确认。
 
优点:极大地节省存储空间。减轻终端用户的负担。无论未来的交易量有多大,block header的大小始终不变,只有80字节。按照每小时6个的出块速度,每年产出52560个区块。当只保存block header时,每年新增的存储需求约为4兆字节,100年后累计的存储需求仅为400兆,即使用户使用的是最低端的设备,正常情况下也完全能够负载。
 
问题:如何才能通过tx_hash定位到该交易所在的区块? 以往的比特币协议中缺少对此的支持。
 
二、比特币钱包
 
在进一步讨论SPV的实现之前,先要说明一下比特币的钱存放的是什么,钱包和私钥之间是什么关系?
 
比特币钱包
 
既然用到“钱包”一词,那么应该与我们日常生活中使用的钱包有一定的相似之处。为了更直观说明,我们与日常生活中所使用的钱包做一下对比。
日常生活中里面存放的可能是纸币、支票、印鉴等等(为了简化说明,我们把银行卡排除在外,使用银行卡涉及到很多中间环节,增加表述上的复杂度)。
用纸币购物时,
1. 从钱包中凑足若干张不同面值的纸币,计算总面值是否大于所需金额以及应找回多少零钱;
2. 将这些纸币直接交给卖方;
3. 卖方验证这些纸币的真伪;
4. 卖方计算这些纸币的面值是否大于或等于商品价格,并找回相应的零钱。
5. 将收到的零钱放回钱包。
 
比特币的钱包里存放的相当于是一张张标有面值的“一次性支票”和对应的“印鉴”。支付时,
1. 用户从钱包中取出若干张“一次性支票”,自己计算总面值是否大于所需金额以及应找回多少零钱,注意要扣除比特币系统所收取的手续费;
2. 给卖方开一张支票,注明卖方地址和支付金额;如果需要找零,给自己开一张找零支票(写上自己的地址和找零金额);
3. 在每张从钱包中取出的支票上加盖对应的印鉴,确认支付权;
4. 将这些票据提交给比特币系统,比特币系统验证支票的真伪和支付是否有效。
5. 若比特币系统验证通过,收款方将收到的支票放入钱包。用户则将自己钱包中的已支付的支票丢弃(这些支票已经被比特币系统视为无效了,无法继续使用),
 
即使是刚接触比特币的人,估计也能猜出“印鉴”指的是“私钥”。但“一次性支票”是什么?
比特币系统中,这种“一次性支票”的术语是UTXO,全称是Unspent Transaction Outputs(未花费的交易输出)。区块链是一个收录所有历史交易(Transaction)的总帐,每个区块(block)中包含若干笔交易记录。
每个交易记录由两部分构成:资金来源(可以有多个来源)和资金去向(可以有多个去向),术语为Tx_in(交易输入)和Tx_out(交易输出)。也就是说,每笔交易TX包含有若干个Tx_in和若干个Tx_out。
 
 
除创世区块中的交易(genesis block)外,每笔交易必须要有资金来源。资金来源有两种,一种是挖矿奖励(依照固定算法实现的货币发行),出现在每个block的第一笔交易中;另一种是先前的交易中未曾使用的某个Tx_out(交易输出),即UTXO。支出方要出示证据来证明自己对该Tx_out拥有所有权,而比特币系统则要验证该Tx_out是否真的未被花费(是否是UTXO)以及支出方是否有权将其花费。
 
资金去向(TX_out)包含两个部分,一是传递的金额,二是支配权(谁可以动用)。取款权通过比特币的脚本系统来实现。若收款方地址是以1开头的普通地址,则脚本中会包含地址所对应公钥的hash值(hash160),动用款项时一般需要用对应的私钥进行签名;若收款方地址是以3开头的多重签名地址,则脚本中会包含某个特定脚本的hash值(hash160),动用款项时,一般需要依照特定的脚本,用多个私钥来签名。
 
用户钱包中的比特币实际上是用户拥有支配权的、且尚未花费的Tx_out中记录的金额总和,即用户可支配的所有UTXO金额之和。
 
完整的钱包中应存有若干个UTXO和支配每个UTXO时所对应的私钥。当然,有时从安全角度出发,可能会把钱包划分为两个部分,在线钱包中只有UTXO,而离线钱包只存私钥。
 
但是,用户怎么才能把自己的所有UTXO都放到钱包中呢?
 
三、用户如何收录自己的UTXO
 
(一)去中心化方式:
实现方法:
1. 在本地建立一个用于存储UTXO的数据库;
2. 设置区块扫描起始点(区块链上的扫描起始高度),从该点开始,依次下载该点之后所有区块(block)的完整数据。
3. 解析每个block的所有TX数据,依次读取每个Tx_in的prev_Tx_out([tx hash] + [tx_out的序号]),检索UTXO数据库中是否存在这个Tx_out,如果有,则从UTXO数据库中删除(或标记删除)。
4. 依次解析每个Tx_out的脚本,若与用户相关,则将[tx hash] + [Tx_out的序号]以及整个tx_out的内容记录到UTXO数据库;
 
备注:如果钱包中只有新创建的私钥,可以从最新的区块开始扫描(由于私钥发生碰撞的可能性可以视为0,在你告知他人比特币地址之前,该私钥对应的地址上不会有任何收入)
 
优点:不依赖于信任;数据准确。
缺点:速度慢,需要从比特币网络下载大量数据,对网络造成的压力大。
 
(二)中心化方式:
1. 某个中心化机构(或个人)运行完整的比特币节点,建立一个收录所有UTXO的数据库。
2. 用户用中心化机构提供的api来请求与自己有关的UTXO数据。
 
优点:速度快,不拖累比特币网络;
缺点:依赖于信任;数据不一定准确(有可能中心化服务器出现故障,或是与中心服务器的会话被劫持,数据遭篡改)
 
 
四、瘦客户端、SPV轻钱包和SPV节点是什么?
 
瘦客户端:参考了SPV的机制,在监听收款地址时,客户端在本地只需保存与用户可支配交易相关的数据。因为本地没有完整的区块链,缺少发送方的相关数据,客户端无法亲自验证交易是否合法,只能判断交易是否是被收录,并且得到了几个确认。这与SPV有很多相似之处,因而很多场合下这种瘦客户端也常被成为是“SPV客户端”,不过,与SPV的区别是,在去中心化方式下,这些客户端仍需下载每个新区块的全部数据并进行解析,只是无需在本地保存全部数据而已。
 
 
“轻钱包”是用瘦客户端模式实现的钱包,因为不存储完整区块链,就涉及到如何获取UTXO的问题。不同的开发者可能有各自的实现方法,但从效率上考虑,往往多用中心化的方式来实现。
 
SPV节点:支持使用布隆过滤器(Bloom filter)在快速检索并返回相关数据的节点。这样的节点可以为去中心化方式SPV查询提供必要的支持。
SPV在实现上涉及到一个问题,如何才能通过tx_hash来定位到该支付交易所在的区块?用中心化方式来实现很好解决,但用去中心化就不那么简单了,因为以往的比特币系统协议中缺少对SPV的支持。原有协议中,可以通过getheaders命令来获取block headers,可以通过getdata命令支持获取指定的block, 但不支持通过tx_hash反向查找所在的block。为了定位block,客户端往往不得不下载整个区块链。Bloom filter解决了客户端检索的问题,原理是Bloom filter可以快速判断出某检索值一定不存在于某个指定的集合,从而可以过滤掉大量无关数据,减少客户端不必要的下载量。
 
前文提到,SPV的用途是验证某个支付是否确实存在,并得到多少个确认。而钱包的用途则是用于管理自己的资产以及进行支付。简言之,SPV的应用场合往往是为发货做准备(知道钱到帐了),“轻钱包”的应用场合往往是数钱或花钱。虽然“轻钱包”中部分借鉴了SPV的机制,但和SPV是完全不用的应用方向,直接把这两个词连起略显牵强。这种钱包要么采用中心化的方式——提高了效率,但引入了信任的风险;要么采用去中心化方式——无需信任,但效率低,且增加网络的负担。
 
SPV节点的出现使以去中心化方式来实现高效、低负荷的“轻钱包”成为了可能。笔者认为将基于SPV节点来实现的"轻钱包"简称为“SPV轻钱包”可能会更为合适些。

看完让你彻底搞懂Websocket原理

 偶然在知乎上看到一篇回帖,瞬间觉得之前看的那么多资料都不及这一篇回帖让我对 websocket 的认识深刻有木有。所以转到我博客里,分享一下。比较喜欢看这种博客,读起来很轻松,不枯燥,没有布道师的阵仗,纯粹为分享。废话这么多了,最后再赞一个~

一、websocket与http

WebSocket是HTML5出的东西(协议),也就是说HTTP协议没有变化,或者说没关系,但HTTP是不支持持久连接的(长连接,循环连接的不算)

首先HTTP有 1.1 和 1.0 之说,也就是所谓的 keep-alive ,把多个HTTP请求合并为一个,但是 Websocket 其实是一个新协议,跟HTTP协议基本没有关系,只是为了兼容现有浏览器的握手规范而已,也就是说它是HTTP协议上的一种补充可以通过这样一张图理解

有交集,但是并不是全部。

另外Html5是指的一系列新的API,或者说新规范,新技术。Http协议本身只有1.0和1.1,而且跟Html本身没有直接关系。。通俗来说,你可以用HTTP协议传输非Html数据,就是这样=。=

再简单来说,层级不一样。

二、Websocket是什么样的协议,具体有什么优点

首先,Websocket是一个持久化的协议,相对于HTTP这种非持久的协议来说。简单的举个例子吧,用目前应用比较广泛的PHP生命周期来解释。

HTTP的生命周期通过 Request 来界定,也就是一个 Request 一个 Response ,那么在 HTTP1.0 中,这次HTTP请求就结束了。

在HTTP1.1中进行了改进,使得有一个keep-alive,也就是说,在一个HTTP连接中,可以发送多个Request,接收多个Response。但是请记住 Request = Response , 在HTTP中永远是这样,也就是说一个request只能有一个response。而且这个response也是被动的,不能主动发起。

教练,你BB了这么多,跟Websocket有什么关系呢?_(:з」∠)_好吧,我正准备说Websocket呢。。

首先Websocket是基于HTTP协议的,或者说借用了HTTP的协议来完成一部分握手。

首先我们来看个典型的 Websocket 握手(借用Wikipedia的。。)

GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13 Origin: http://example.com

熟悉HTTP的童鞋可能发现了,这段类似HTTP协议的握手请求中,多了几个东西。我会顺便讲解下作用。

Upgrade: websocket Connection: Upgrade

这个就是Websocket的核心了,告诉 Apache 、 Nginx 等服务器:注意啦,我发起的是Websocket协议,快点帮我找到对应的助理处理~不是那个老土的HTTP。

Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13

首先, Sec-WebSocket-Key 是一个 Base64 encode 的值,这个是浏览器随机生成的,告诉服务器:泥煤,不要忽悠窝,我要验证尼是不是真的是Websocket助理。

然后, Sec_WebSocket-Protocol 是一个用户定义的字符串,用来区分同URL下,不同的服务所需要的协议。简单理解:今晚我要服务A,别搞错啦~

最后, Sec-WebSocket-Version 是告诉服务器所使用的 Websocket Draft(协议版本),在最初的时候,Websocket协议还在 Draft 阶段,各种奇奇怪怪的协议都有,而且还有很多期奇奇怪怪不同的东西,什么Firefox和Chrome用的不是一个版本之类的,当初Websocket协议太多可是一个大难题。。不过现在还好,已经定下来啦~大家都使用的一个东西~ 脱水: 服务员,我要的是13岁的噢→_→

然后服务器会返回下列东西,表示已经接受到请求, 成功建立Websocket啦!

HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= Sec-WebSocket-Protocol: chat

这里开始就是HTTP最后负责的区域了,告诉客户,我已经成功切换协议啦~

Upgrade: websocket Connection: Upgrade

依然是固定的,告诉客户端即将升级的是 Websocket 协议,而不是mozillasocket,lurnarsocket或者shitsocket。

然后, Sec-WebSocket-Accept 这个则是经过服务器确认,并且加密过后的 Sec-WebSocket-Key 。 服务器:好啦好啦,知道啦,给你看我的ID CARD来证明行了吧。。

后面的, Sec-WebSocket-Protocol 则是表示最终使用的协议。

至此,HTTP已经完成它所有工作了,接下来就是完全按照Websocket协议进行了。具体的协议就不在这阐述了。

——————技术解析部分完毕——————

你TMD又BBB了这么久,那到底Websocket有什么鬼用, http long poll ,或者ajax轮询 不都可以实现实时信息传递么。

好好好,年轻人,那我们来讲一讲Websocket有什么用。来给你吃点胡(苏)萝(丹)卜(红)

三、Websocket的作用

在讲Websocket之前,我就顺带着讲下 long poll 和 ajax轮询 的原理。

ajax轮询

ajax轮询的原理非常简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。

场景再现:

客户端:啦啦啦,有没有新信息(Request)

服务端:没有(Response)

客户端:啦啦啦,有没有新信息(Request)

服务端:没有。。(Response)

客户端:啦啦啦,有没有新信息(Request)

服务端:你好烦啊,没有啊。。(Response)

客户端:啦啦啦,有没有新消息(Request)

服务端:好啦好啦,有啦给你。(Response)

客户端:啦啦啦,有没有新消息(Request)

服务端:。。。。。没。。。。没。。。没有(Response) —- loop

long poll

long poll 其实原理跟 ajax轮询 差不多,都是采用轮询的方式,不过采取的是阻塞模型(一直打电话,没收到就不挂电话),也就是说,客户端发起连接后,如果没消息,就一直不返回Response给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。

场景再现:

客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request)

服务端:额。。 等待到有消息的时候。。来 给你(Response)

客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request) -loop

从上面可以看出其实这两种方式,都是在不断地建立HTTP连接,然后等待服务端处理,可以体现HTTP协议的另外一个特点,被动性。

何为被动性呢,其实就是,服务端不能主动联系客户端,只能有客户端发起。

简单地说就是,服务器是一个很懒的冰箱(这是个梗)(不会、不能主动发起连接),但是上司有命令,如果有客户来,不管多么累都要好好接待。

说完这个,我们再来说一说上面的缺陷(原谅我废话这么多吧OAQ)

从上面很容易看出来,不管怎么样,上面这两种都是非常消耗资源的。

ajax轮询 需要服务器有很快的处理速度和资源。(速度)long poll 需要有很高的并发,也就是说同时接待客户的能力。(场地大小)

所以 ajax轮询 和 long poll 都有可能发生这种情况。

客户端:啦啦啦啦,有新信息么?

服务端:月线正忙,请稍后再试(503 Server Unavailable)

客户端:。。。。好吧,啦啦啦,有新信息么?

服务端:月线正忙,请稍后再试(503 Server Unavailable)

客户端:然后服务端在一旁忙的要死:冰箱,我要更多的冰箱!更多。。更多。。(我错了。。这又是梗。。)

言归正传,我们来说Websocket吧

通过上面这个例子,我们可以看出,这两种方式都不是最好的方式,需要很多资源。

一种需要更快的速度,一种需要更多的’电话’。这两种都会导致’电话’的需求越来越高。

哦对了,忘记说了HTTP还是一个状态协议。

通俗的说就是,服务器因为每天要接待太多客户了,是个健忘鬼,你一挂电话,他就把你的东西全忘光了,把你的东西全丢掉了。你第二次还得再告诉服务器一遍。

所以在这种情况下出现了,Websocket出现了。他解决了HTTP的这几个难题。首先,被动性,当服务器完成协议升级后(HTTP->Websocket),服务端就可以主动推送信息给客户端啦。所以上面的情景可以做如下修改。

客户端:啦啦啦,我要建立Websocket协议,需要的服务:chat,Websocket协议版本:17(HTTP Request)

服务端:ok,确认,已升级为Websocket协议(HTTP Protocols Switched)

客户端:麻烦你有信息的时候推送给我噢。。

服务端:ok,有的时候会告诉你的。

服务端:balabalabalabala

服务端:balabalabalabala

服务端:哈哈哈哈哈啊哈哈哈哈

服务端:笑死我了哈哈哈哈哈哈哈

就变成了这样,只需要经过一次HTTP请求,就可以做到源源不断的信息传送了。(在程序设计中,这种设计叫做回调,即:你有信息了再来通知我,而不是我傻乎乎的每次跑来问你 )

这样的协议解决了上面同步有延迟,而且还非常消耗资源的这种情况。那么为什么他会解决服务器上消耗资源的问题呢?

其实我们所用的程序是要经过两层代理的,即HTTP协议在Nginx等服务器的解析下,然后再传送给相应的Handler(PHP等)来处理。简单地说,我们有一个非常快速的 接线员(Nginx) ,他负责把问题转交给相应的 客服(Handler) 。

本身接线员基本上速度是足够的,但是每次都卡在客服(Handler)了,老有客服处理速度太慢。,导致客服不够。Websocket就解决了这样一个难题,建立后,可以直接跟接线员建立持久连接,有信息的时候客服想办法通知接线员,然后接线员在统一转交给客户。

这样就可以解决客服处理速度过慢的问题了。

同时,在传统的方式上,要不断的建立,关闭HTTP协议,由于HTTP是非状态性的,每次都要重新传输 identity info (鉴别信息),来告诉服务端你是谁。

虽然接线员很快速,但是每次都要听这么一堆,效率也会有所下降的,同时还得不断把这些信息转交给客服,不但浪费客服的处理时间,而且还会在网路传输中消耗过多的流量/时间。

但是Websocket只需要一次HTTP握手,所以说整个通讯过程是建立在一次连接/状态中,也就避免了HTTP的非状态性,服务端会一直知道你的信息,直到你关闭请求,这样就解决了接线员要反复解析HTTP协议,还要查看identity info的信息。

同时由客户主动询问,转换为服务器(推送)有信息的时候就发送(当然客户端还是等主动发送信息过来的。。),没有信息的时候就交给接线员(Nginx),不需要占用本身速度就慢的客服(Handler)了

——————–

至于怎么在不支持Websocket的客户端上使用Websocket。。答案是: 不能

但是可以通过上面说的 long poll 和 ajax 轮询 来 模拟出类似的效果

ubuntu下从源码编译比特币(Bitcoin)客户端

./configure

运行完上边的这个命令之后,你就可以知道你的系统中都少什么库,下边就是安装缺少的库的方法
If you encounter configure: error: libdb_cxx headers missing
提示少libdb_cxx头,这个时候运行下边令命安装db的C++开发库
sudo apt-get install libdb5.1++-dev 

 
 
./configure --with-incompatible-bdb