精通比特币中文版.pdf
http://www.100md.com
2020年1月19日
![]() |
| 第1页 |
![]() |
| 第10页 |
![]() |
| 第20页 |
![]() |
| 第29页 |
![]() |
| 第39页 |
![]() |
| 第629页 |
参见附件(12515KB,639页)。
精通比特币,这是一本深度解析比特币的籍,全书共分为十个章节,作者从基础说起到深奥的技术概念,用故事、比喻、实例和代码片段为读者展示,让你更加容易看懂!

精通比特币介绍
快加入这场给金融世界带来风暴的技术革命。《精通比特币》作为指南提供了参与货币因特网所需的知识,可以带你穿越看似复杂的比特币世界。无论是正在开发下一个杀手级应用、投资初创企业还是仅仅对新技术好奇,这本经修订和扩充的第二版都能提供入门所需关键细节内容。
比特币是第1种成功的去中心化数字货币,虽然仍处于其早期阶段,但已经催生了数十亿规模的全球经济,任何具有相关知识和热情的人都可以参与。《精通比特币》就提供了这些知识,你只要提供热情即可。
精通比特币作者
Andreas M. Antonopoulos是知名的技术专家和连续创业者,他已经成为比特币行业著名和令人尊敬人士。作为公众演说家、教师和作家,Andreas 担任了多家技术初创企业的顾问,还定期在全世界的各种会议和社区活动中发表演讲。
精通比特币主目录
第1章 介绍
第2章 比特币的原理
第3章 比特币客户端
第4章 密钥、地址、钱包
第5章 交易
第6章 比特币网络
第7章 区块链
第8章 挖矿与共识
第9章 竞争币、竞争块链和应用程序
第10章 比特币安全
精通比特币点评
1、当我在德勤Rubix平台任职期间,《精通比特币》曾是新招募技术员工初学该主题的必读书之一。
2、正如区块链协议所体现的精神,《精通比特币》也是协作编纂的成果,该书是为开发者准备的zui全面而精当的参考。如果你想从平台角度完整把握区块链的潜在能力,请读此书。
3、Andreas的书将帮助你加入这场金融世界的软件革命。
精通比特币截图


目录
1. 介绍
2. 前言
3. 快速术语检索
4. 第1章 介绍
5. 第2章 比特币的原理
6. 第3章 比特币客户端
7. 第4章 密钥、地址、钱包
8. 第5章 交易
9. 第6章 比特币网络
10. 第7章 区块链
11. 第8章 挖矿与共识
12. 第9章 竞争币、竞争块链和应用程序
13. 第10章 比特币安全
14. 附录1
15. 附录2
16. 附录3
17. 附录4
18. 贡献与勘误
精通比特币
作者:Andreas M Antonopoulos
Andreas M. Antonopoulos 是一位著名的技术专家和连续创业企业家,比
特币界最著名和倍受尊敬的人物之一。身为一名迷人的公共演说家、教
师和作家,他善于把复杂的问题变得简单而易于理解。
Andreas M. Antonopoulos 的成长和互联网密不可分,青少年时期,他便
在自己希腊的家中创办了他的首家公司——一个早期电子信息服务系统
和原始的互联网服务提供商。他取得了伦敦大学学院的电脑科学学位、数据通信学位以及分布式系统学位,该学校最近跻身于全球大学排名前
十。移居美国后,Andreas M. Antonopoulos 和别人合办了一家成功的技术研究公司,管理公司的他,在网络、安全、数据中心和云计算方面,为许多世界五百强公司的首席执行者提供建议。他撰写了200多篇关于
安全、云计算和数据中心的文章,已经在世界范围内被印制出版,并在
多家报刊发表。此外,他还持有两项网络和安全领域的专利权。
1990年,Andreas M. Antonopoulos 开始在私人、专业和学术等诸多场合
讲授IT话题。从五名企业高管的会议室,到千人参与的大型会议,他不
断磨练着自己的演讲水平。超过400次的锻炼,不仅使他成为了为人津
津乐道的教授,还铸就了他世界级演讲大师的美名。2014年,第一所授
予数字货币学士学位的尼科西亚大学邀请他来校任教。上任后,他与别
人合作开设了这门课程。他还参与讲授了数字货币导论,后者成了为尼
科西亚大学的一门大型网络公开课(MOOC)。
作为一名比特币企业家,Andreas M. Antonopoulos 已成立了不少比特币
企业,并推出了一些社区开源项目。他担任好几家比特币和加密货币公
司的顾问。他既是一名出版作家,发表了大量关于比特币的文章和博
文;也是一档流行博客“Let’s Talk Bitcoin”的固定主持人;还是在全球
各地的技术安全会议上演说的常客。
译者:
薄荷凉幼;陈萌琦;陈姝吉;程鹏;程西园;达文西;吉鸿帆;李
丹;李润熙;李凌豪;李昕阳;刘畅;吕新浩;马峰;牛东晓;秦
彤;邱蒙;戎如香;史磊;汪海波;王宏钢;辛颖;杨兵;尹文
东;余龙;张林;张琦张大嫂;张亚超;张泽铭;赵冬帅;赵余;
YANG YANG
简介
想要加入一场颠覆金融世界的技术革命吗?《精通比特币》会为你参与
这个货币网络提供必备知识,引导你进入看似复杂的比特币世界。无论
你是正在构建下一个杀手级应用、投资创业,还是单纯对技术好奇,这
本实用的书都是你不可或缺的阅读材料。
比特币,作为第一个成功的去中心化数字货币,尽管还处在起步阶段,却已经催生了数十亿美元的全球性经济体。它对任何具备相应知识和参与热情的人都是开放的。《精通比特币》会为您提供必要的知识,但请
各位读者自备热情。
本书包括:
针对非技术用户、投资者以及企业高管,概括性地介绍比特币
针对开发人员、工程师以及软件系统架构师,介绍比特币和加密货
币的技术基础
详细介绍比特币去中心化网络、点对点体系结构、交易生命周期以
及安全原则等细节的
比特币和区块链的发明的衍生物,包括替代链、货币以及应用程序
通过用户故事、简练的类比、示例以及代码段来阐释的关键技术概
念
Andreas M. Antonopoulos 是比特币行业最为知名和受人尊敬的技术专
家、连续创业家,现担任多家技术创业公司的顾问。他同时还是一名出
色的演说家,教师以及作家,经常在世界各地的会议和团体活动中发表
演说,用通俗易懂的讲解把复杂的学科普及给广泛听众。
“论及比特币,有人问我它到底是怎样工作的?现在我有了一个极
好的答案——《精通比特币》这本书会让每位读者深刻理解比特币
的工作原理,还会帮助读者为写出下一代神奇加密货币的应用程序
做好充分准备。”
——Gavin Andresen,比特币基金会,首席科学家
“Andreas的书将帮助你投身于金融世界的软件革命。”
——Naval Ravikant,AngelList联合创始人
捐赠
在本书翻译过程中, 火币 、 OKCoin 、 云币 各捐赠了2个比特币,捐赠地址为: 18AN9XojYq5EU5x8p6pgdYk3RKo6zu9xzy ;这些比特币当前
并没有发放给参与翻译的义工。计划大体如下:
1. 此比特币地址继续接受捐赠:
18AN9XojYq5EU5x8p6pgdYk3RKo6zu9xzy
2. 捐赠的比特币将主要用于本书翻译的纠错与修订(具体奖励措施尚
未确定);如果您发现了书中的错误,请点击 此处 填写《勘误收
集表》。
3. 一年之后(即,2016 年 6 月 1 日),剩余的比特币将平均发放给
译者们,留作纪念。
4. 捐赠名单讲在此页面公布。如果您愿意,捐赠比特币时,请使用
blockchain.info 或者 bitfoo.com ,在 note 中标明您的身份,以作纪
念。
前言
关于本书
我第一次偶遇比特币是在2011年年中,当时的反应大概是“哈!书呆子
的钱嘛!”因为没能领会它的重要性,我忽视它长达六个月之久,而让
我稍感宽慰的是,许多我认识的一些聪明绝顶人也是这种反应。在一次
邮件列表讨论时,我再次接触到了比特币,于是决定阅读中本聪
(Satoshi Nakamoto)写的白皮书,研究比特币的权威解释,看看到底
是怎么一回事。我仍记得刚刚读完那九页内容的那一刻,那时我才终于
明白了:比特币不单单是一种数字货币,还是一种给货币及其他很多东
西提供基础的信任网络。对“不是货币,而是去中心化信任网络”的领
悟,让我开启了为期四个月的比特币沉醉之旅。我如饥似渴地寻找任何
关于比特币的点滴信息,变得越来越着迷,每天都花上12个小时以上紧
盯屏幕,竭尽所能地不断阅读、写作、学习和编程。从这段着魔的状态
中走出来的时候,我的体重由于前期没有规律饮食轻了20多磅,同时我
也坚定了要全心投入比特币事业的决心。
随后的两年,我创立了一系列开发比特币相关服务和产品的公司,之后
我决定写我的第一本书。书的主题就是激发了我疯狂的创造力并让我冥
思苦想的比特币,它是我在继互联网之后遇到的最为振奋人心的技术。
现在是时候跟更广大的读者分享我对这项惊人技术的热情了。阅读对象
本书主要面向程序员。如果你能使用一门编程语言,本书将会告诉你加
密货币的原理、使用方法,以及如何开发与之相关的软件。对希望理解
比特币及加密货币内在工作机制的非程序员读者们,本书前几章作为对
比特币的深入介绍依然适用。
封面故事
在群居生物物种中,切叶蚁表现出了高度复杂行为的物种特征。但是,群落中的每一只蚂蚁个体仅仅遵循一些社会互动和化学气味(即信息
素)交换的简单规则。维基百科提到:“切叶蚁形成地球上仅次于人类
的最为庞大且复杂的动物社会。”实际上,切叶蚁不吃叶子,而是使用
叶子制造一种真菌来充当蚁群主要食物来源。意识到了吗?它们在耕
作!
虽然切叶蚁形成的是阶级社会,且依靠蚁后繁衍后代,但是在蚁群中不
存在中央集权体制或领导人。通过切叶蚁我们可以看到,群落中数百万
成员所展现的高度智能且复杂的行为是社会网络中的个体互动这一性质
的凸显。
大自然向我们证明,去中心化体制具有弹性并能创造出意想不到的复杂
性和难以想象的精妙,而不需要中央集权体制、等级制度或复杂的组织
结构。
比特币网络正是这样一个高度复杂的去中心化的可信网络,能够支撑无
数财务流程。然而,比特币网络的每一个节点都遵循着一些简单的数学
准则。节点间的相互作用促成引起了组织的复杂行为,而并不是任何某
个单一节点自身具有复杂性和可信性。就像蚁群一样,比特币的弹性网
络是一个由众多遵循简单准则的简单节点所组成的弹性网络,这些简单
的节点准则聚合在一起可以完成惊人的事情,而不需要任何中枢协调。
本书惯例
本书中的印刷惯例如下: 此图标表示小贴士,建议,或一般性注解。
此图标表示预警或警告。
代码示例
本书示例是基于类Unix操作系统(例如Linux或Mac OS X)的命令行,用Python,C++编程语言来说明的。全部代码段均可在 Github主代码库
中的code子目录获得。读者可以通过GitHub创建自己的代码分支,尝试
书中示例,或者提交代码更正。
所有代码段在大多数操作系统上都可以通过最小化安装对应语言的编译
器和解释器来重现。在必要的地方,本书还提供了基本的安装指令以及
每步指令输出的结果。
为了便于打印,本书重新格式化了部分代码段和代码输出。在所有此类
例子中,每行代码以反斜杠(\)字符和换行符分开。当你需要尝试这
些示例时,请删除这两个字符的,把被分隔的两行重连起来,就可以看
到与例子中一致的结果了。
本书所有代码段尽可能地采用实值计算,因此你可以通过重复构建本书
提供的代码示例,用你自己写的代码计算出相同的结果。譬如,书中出
现的私钥和对应的公钥及地址也都是真实存在的。示例中的所有交易、区块和区块链均被记录在实际的比特币区块链中,是公共账目的一部
分,因而你可以在任何比特币系统中检查它们。
使用代码示例
本书的目的是帮助你完成工作。总的来说,你可以在你的程序和文档中
使用本书的代码示例。除非你要复制代码的关键部分,否则不需要联系我们获得许可。例如,使用程序中的几段代码,或者引用本书及代码来
回答问题是不需要获准的;而售卖或分发包含O’Reilly书中代码示例的
光盘,或者将大量书中代码合并于你的产品或文档则必须获得我们的许
可。
我们鼓励、但不强制要求您在引用本书时表明出处。书目引用格式通常
包括书名、作者、出版商、ISBN。例如:“精通比特币,Andreas?M?Antonopoulos (O'Reilly)。版权2015 Andreas?M?Antonopoulos,978-1-449-37404-4.”
本书某些版本提供了开源许可,如 CC-BY-NC ,这种情况下,开源许可
条款适用。
如果你觉得你对本书代码示例的使用超出了合理范围或上述许可,请随
时与我们联系:permissions@oreilly.com.
快速术语检索
“常用术语表”中包含了很多常见的比特币相关术语。这些术语在本书中
也多次出现。建议您给本章节做上标记,阅读时可作快速索引。
地址
比特币地址(例如:1DSrfJdB2AnWaFNgSbv3MZC2m74996JafV)由一
串字符和数字组成,以阿拉伯数字“1”开头。就像别人向你的email地址
发送电子邮件一样,他可以通过你的比特币地址向你发送比特币。
BIP
比特币改进提议 (Bitcoin Improvement Proposals 的缩写),指比特币
社区成员所提交的一系列改进比特币的提议。例如,BIP0021是一项改
进比特币统一资源标识符(URI)计划的提议。
比特币
“比特币”既可以指这种虚拟货币单位,也指比特币网络或者网络节点使
用的比特币软件。区块
一个区块就是若干交易数据的集合,它会被标记上时间戳和之前一个区
块的独特标记。区块头经过哈希运算后会生成一份工作量证明,从而验
证区块中的交易。有效的区块经过全网络的共识后会被追加到主区块链
中。
区块链
区块链是一串通过验证的区块,当中的每一个区块都与上一个相连,一
直连到创世区块。
确认
当一项交易被区块收录时,我们可以说它有一次确认。矿工们在此区块
之后每再产生一个区块,此项交易的确认数就再加一。当确认数达到六
及以上时,通常认为这笔交易比较安全并难以逆转。
难度
整个网络会通过调整“难度”这个变量来控制生成工作量证明所需要的计
算力。
难度目标
使整个网络的计算力大致每10分钟产生一个区块所需要的难度数值即为
难度目标。
难度调整
整个网络每产生2,106个区块后会根据之前2,106个区块的算力进行难度
调整。
矿工费
交易的发起者通常会向网络缴纳一笔矿工费,用以处理这笔交易。大多
数的交易需要0.5毫比特币的矿工费。哈希
二进制数据的一种数字指纹。
创世区块
创世区块指区块链上的第一个区块,用来初始化相应的加密货币。
矿工
矿工指通过不断重复哈希运算来产生工作量证明的各网络节点。
网络
比特币网络是一个由若干节点组成的用以广播交易信息和数据区块的
P2P网络。
工作量证明
工作量证明指通过有效计算得到的一小块数据。具体到比特币,矿工必
须要在满足全网目标难度的情况下求解SHA256算法。
奖励
每一个新区块中都有一定量新创造的比特币用来奖励算出工作量证明的
矿工。现阶段每一区块有25比特币的奖励。
私钥
用来解锁对应(钱包)地址的一串字符,例如
5J76sF8L5jTtzE96r66Sf8cka9y44wdpJjMwCxR3tzLh3ibVPxh。
交易
简单地说,交易指把比特币从一个地址转到另一个地址。更准确地说,一笔“交易”指一个经过签名运算的,表达价值转移的数据结构。每一
笔“交易”都经过比特币网络传输,由矿工节点收集并封包至区块中,永
久保存在区块链某处。钱包
钱包指保存比特币地址和私钥的软件,可以用它来接受、发送、储存你
的比特币。
第1章 介绍
1.1 什么是比特币?
比特币是一些概念与技术的集合,这些概念与技术构成了数字货币生态
系统的基础。人们称之为“比特币”的货币单位用于存储,也用于在比特
币网络参与者之间传输价值。比特币用户之间通过比特币协议进行通讯
主要是在互联网上,当然也可以使用其他传输网络进行交流。比特币的
协议栈以开源软件的形式实现,这些软件可以在包括笔记本电脑、智能
手机在内的多种设备上运行,这使得比特币技术非常亲民。
用户可以通过在网络上传输比特币来实现几乎传统货币能做的全部事
情,例如买卖商品、给个人或组织汇款,或提供贷款。比特币可以在专
门的交易所里购买,出售,或者与其他币种进行兑换。从一定意义上来
说,由于具有快捷、安全以及无国界的特性,比特币正是互联网货币的
完美形态。
不同于传统的货币,比特币是完全虚拟的。没有实物的货币,甚至就本
质而言,也没有数字货币。比特币隐匿于发送者和接收者间价值传递的
交易中。比特币用户拥有能够使他们在比特币网络中证明自己交易权的
密钥,解密后可使用比特币,也可以将它购买、,出售,以及与其他币
种进行兑换。由于比特币快捷、安全以及无国界的特性,在某种意义
上,比特币就是互联网货币的完美形态。
用传统货币能做到的事情,用户在网络上利用比特币都可以做到,包括
发送给新的接收者。这些密钥通常存储在每个用户的计算机的数字钱包
里。每一笔交易都需用密钥解密,这是使用比特币的唯一先决条件,它
完完全全掌握在每个用户的手中。
比特币是一个分布式的点对点网络系统。因此,没有“中央”服务器,也
没有中央控制点。比特币是通过一个名为“挖矿”的过程产生的,挖矿需要在处理比特币交易的同时参与竞赛来解决一个数学问题。在比特币网
络中的任何参与者(比如,任何人使用一个设备来运行完整的比特币协
议栈)都是潜在的矿工,用他们电脑算力来验证和记录交易。每隔10分
钟,有人能够验证过去10分钟发生的交易,作为回报,将会获得崭新的
比特币。从本质上讲,比特币挖矿分散了中央银行的货币发行,也分散
了其结算功能,并且能够在全球竞争中取代任何一家中央银行。
比特币协议包括了内置算法,该算法可以调节网络中的挖矿功能。矿工
必须完成的任务——在比特币网络中成功地记录一个区块交易——的难
度是在动态调整的,因此,无论何时有多少矿工(多少CPU)在挖矿,通常每10分钟就会有人成功。
新比特币开采出的每四年,这项协议也会减半开采速率,并限制比特币
的开采总量为一个固定值:2,100万枚。其结果是,在流通中的比特币
数量很容易根据预测曲线得出,将会在2140年达到2,100万枚。由于比
特币的发行率是递减的,从长期来看,比特币是一种通货紧缩的货币。
此外,通过超出预期发行率来“印刷”新比特币,造成通货膨胀是不可实
现的。
实质上,比特币本身也是协议,是一种网络,是一种分布式计算革新的
代名词。比特币通货仅是这种创新的首次应用。作为一个开发者,我看
到比特币类似于互联网货币,一个通过分布式计算来传播价值和保障数
字资产所有权的网络。比起初识比特币,这里将知无不言。
在本章中,我们将会从一些主要概念和术语解释开始,获取必备软件,使用比特币进行简单的交易。在接下来的章节里,我们将开始揭开使比
特币成为可能的技术面纱,解释比特币网络和比特币协议的内部运行机
制。
比特币之前的数字货币
切实可行的数字货币的出现是与密码学发展息息相关的。基本的挑
战在于,当一个人考虑到用比特来代表可以兑换商品和服务的价值
时,接受数字货币也就不足为奇。任何接受数字货币的人都面临的
两个基本问题是:
1. 我能相信这钱是真实可信的,而不是伪造的吗?
2. 我能确定没人说这笔钱是他们的,而不是我的吗?(又名“双重支付”问题)
纸币的发行机构不断的利用日益复杂的纸张和打印技术来遏制造假
问题。实物货币很容易解决双重支付问题,因为同一张纸币不可能
会同时出现在两个不同的地方。当然,传统货币也经常数字化储存
和数字化传输。在这些情况下,假币和双重支付问题是被中央权威
机构的处理方式是清除所有的电子交易记录,该中央权威在流通中
持有一种全球通货观。对于数字货币来说,不能有效利用秘制油墨
印刷技术或条形全息图,密码学为用户所主张的合法性价值提供了
信任的基础。具体地来说,加密数字签名能够使一个用户签署一项
能够提供其资产所有权证明的数字资产或数字交易。采用适当的结
构,数字签名也可以用于解决双重支付的问题。
在20世纪80年代后期,当密码学开始越来越广泛地使用并被理解
时,许多研究人员开始尝试使用密码学来建立数字通货。这些早期
的数字通货项目发行的数字货币,通常倚靠一种国家通货或像黄金
一样的贵金属。
虽然这些早期的数字通货的运行了,他们却是中心化的,因此,他
们很容易遭受到政府和黑客的攻击。早期的数字通货使用了一个中
央结算所来处理所有的定期交易,就像一个传统的银行系统。不幸
的是,在大多数情况下,这些新兴的数字货币成为了政府担忧的目
标,最终从法律程序上消失了。另一些则是在发行这些数字货币的
母公司突然违约时颓然失败了。为了坚定的抵制对手的介入,无论
这些对手是合法的政府或是犯罪分子,去中心化的数字货币需要的
是避免单节点攻击。比特币正是这样的系统,设计完全去中心化,不被任何中央政权或中央点控制,这样的货币系统是不会遭受攻
击,也不会变得腐败。
比特币代表了数十年的密码学和分布式系统的巅峰之作,这是一个
独特而强大的组合,汇集了四个关键的创新点。比特币由这些构
成:
一个去中心化的点对点网络(比特币协议)
一个公共的交易账簿(区块链)
一个去中心化的数学的和确定性的货币发行(分布式挖矿) ? 一个去中心化的交易验证系统(交易脚本)
1.2 比特币发展史
2008年,一位化名为中本聪的人,在一篇名为《比特币:一个点对点的
电子现金系统》的论文中首先提出了比特币。中本聪结合以前的多个数
字货币发明,如B-money和HashCash,创建了一个完全去中心化的电子
现金系统,不依赖于通货保障或是结算交易验证保障的中央权威。关键
的创新是利用分布式计算系统(称为“工作量证明”算法)每隔10分钟进
行一次的全网“选拔”,能够使去中心化的网络同步交易记录。这个能优
雅的解决双重支付问题,即一个单一的货币单位可以使用两次。此前,双重支付问题是数字货币的一个弱点,并通过一个中央结算机构清除所
有交易来处理。
根据中本聪的一篇涉及比特币网络运行的发表论文,比特币网络自从被
许多其他的程序员修订之后,于2009年启动。分布式计算,为比特币提
供了成倍增长的安全性和韧性,现在超过了世界顶级超级电脑的联合处
理能力。根据比特币兑美元汇率,比特币的总市场估值为50至100亿美
元。目前从全网来看,比特币处理的最大交易额为1.5亿美元,这笔交
易及时处理和转账,没有缴纳任何手续费。
中本聪在2011年4月退出公众视野,将比特币代码开发与网络建设的重
任留给了欣欣向荣的社区成员。而“中本聪”究竟是谁,时至今日仍然是
未解之谜。然而,比特币系统的运行,既不依赖于中本聪,也不依赖于
其他任何人——比特币系统依赖于完全透明的数学原理。这项发明本身
就是开创性的,它已经蔓延到了分布式计算、经济学、计量经济学领
域。
一个分布式计算问题的解决方案
中本聪的此项发明,对“拜占庭将军”问题也是一个可行的解决方
案,这是一个在分布式计算中未曾解决的问题。简单来说,这个问
题包括了试图通过在一个不可靠、具有潜在威胁的网络中,通过信
息交流来达成一个行动协议共识。中本聪的解决方案是使用工作量
证明的概念在没有中央信任机构下达成共识,这代表了分布式计算
的科学突破,并已经超越了货币广泛的适用性。它可以用来达成去中心化的网络共识来公正选举、彩票、资产登记,以及数字化公证
等等。
1.3 比特币的应用、用户和他们的故事
比特币是一项技术,但它所传递的货币从实质上来说,是一种人与人之
间价值交换的基础语言。让我们通过他们的故事,来看看使用比特币的
人和一些最常用的通货和协议。我们将会反复用到这些贯穿本书的故
事,以此来说明现实生活中数字货币的用途,以及他们是如何通过比特
币的各种技术使之成为可能的。
北美低价零售
Alice住在北加州的旧金山湾区。她已经从她的科技迷朋友口中得知了比
特币,想要开始使用它。我们会跟进她的故事,来了解比特币,获取一
些,并在帕洛阿尔托的Bob家咖啡店用比特币购买一杯咖啡。这个故事
会从零售的消费者角度向我们介绍比特币软件,交易平台,以及基本的
交易。
北美高价零售
Carol是一位旧金山艺术画廊的主人。她出售昂贵的油画来换取比特
币。这个故事将介绍高额商品的零售商们所面临的“51%”攻击的风险。
离岸合同服务
Bob是帕洛阿尔托一家咖啡店的老板,正在建设一个新网站。他曾与一
个住在印度班加罗尔的网站开发者Gopesh签订了协议。Gopesh已同意比
特币支付。这个故事将研究使用比特币进行海外购、合约服务,以及国
际电汇。
慈善捐赠
Eugenia是菲律宾一家儿童慈善机构的董事。最近,她发现了比特币,并希望利用它来和一个全新的国内外捐助群体接洽,以此为她的慈善募
捐。她还研究如何使用比特币快速优化资金配置。这个故事将会演示用
比特币来进行跨币种跨国界的全球融资,展示慈善组织所使用的公开透明账簿。
进口出口
Mohammed是迪拜一位电子进口商。他试着用比特币来进行快捷支付,进口美国和中国的电子产品到阿联酋。这个故事将示范用比特币来支付
大型企业间实物商品的国际收支。
比特币挖矿
Jing是上海一名计算机工程专业的学生。他建了一个用来挖比特币的矿
机,使用他的专业技能来为自己创收。这个故事将审查基于比特币
的“工业”:用于确保比特币网络安全和发行新货币的特殊设备。
这些故事都是根据真实行业内的真实人物原型来的,他们正在用比特币
创造新市场,创造新产业,用比特币这个新兴事物来解决全球经济问
题。
1.4 入门
加入比特币网络并开始使用通货,所有用户需要做的就是下载应用程序
或使用在线应用程序。因为比特币是一个标准,也有许多运行比特币的
客户端软件。还有一个标准客户端,也称为中本聪客户端,这是由一个
开发团队管理的一个开源项目,源自于中本聪编写的初始客户端。
比特币客户端的三种主要形式是:
完整客户端
一个完整客户端,或称“全节点”,是存储所有比特币交易的整个交易历
史(由每一个用户完成的每一笔交易,曾经所有的每一笔)的客户端,管理用户的钱包,并可以在比特币网络上直接开始交易。这类似于一个
独立的电子邮件服务器,因为它处理着协议的各个方面,而不依赖于任
何其它的服务器或第三方服务。
轻量级客户端 一个轻量级客户端存储用户的钱包,但需要依赖第三方服务器才能进行
比特币交易,才能接入比特币网络。轻量级客户端不保存所有交易的完
整副本,因此必须信赖第三方的服务器来获取交易确认。这就类似于一
个独立的电子邮件客户端,能够通过邮箱服务器来访问一个邮箱,因为
它在网络交流中依赖于一个第三方服务器。
在线客户端
在线客户端通过网页浏览器在第三方服务器上访问和储存该用户的钱
包。这类似于在线邮件,因为它完全依赖于第三方服务器。
移动客户端
智能手机的移动客户端,例如基于Android系统,既可以作完整客
户端运行,也可作为轻量级客户端或在线客户端。一些移动客户端
是与在线客户端或桌面客户端同步的,提供跨多个设备但有一个共
同的资金源的多平台钱包。
比特币客户端的选择,取决于用户想要管理资金的数目。一个完整的客
户端将为用户提供最高级的管理和独立性。这样钱包的备份和安全责任
就转移到了用户身上。另一种选择是在线客户端,其设置和使用是最简
单的,但在线客户端的取舍还在于需衡量第三方介入的风险,因为安全
性和控制权是由用户和网页服务商所共同承担的。如果一个在线钱包服
务遭受了损失,就像已发生过的那样,用户们可能会失去所有的资金。
反过来看,如果用户的一个完整客户端没有进行适当的备份,他们可能
会因为电脑的操作失误而丢失他们的资金。
这本书的目的在于,我们将演示各种可下载的比特币客户端的使用方
法,从原版客户端(中本聪客户端)到在线钱包。一些案例将使用到原
版客户端,除了作为一个完整的客户端以外,也会公开钱包的API,网
络和交易服务。如果您计划进入比特币系统探索编程的话,将会需要原
版客户端。
1.4.1 快速入门
我们在“ 1.3 比特币的应用、用户和他们的故事 ”一节中介绍了Alice,她
并不是技术性用户,最近才从一个朋友那听说了比特币。她通过浏览比
特币官方网站bitcoin.org开始了自己的比特币之旅,在官网上,她发现了很多种可供选择的比特币客户端。她根据官网提供的建议,选择了轻
量级的Multibit客户端。
Alice通过官网bitcoin.org上提供的链接,在她的电脑里下载安装了
Multibit客户端。目前Multibit电脑客户端有WindowsWindows, Mac OS
和 Linux版本。
比特币钱包必须由一个密码或密令来保护。有许多试图破解弱密码
的潜在威胁,所以要注意谨慎设置一个不会被轻易破解的密码。密
码应使用大小写字母、数字和符号的组合,避免出现生日、球队名
字等个人信息。避免使用任何能在字典里轻易找到的词语,不管这
个词语是什么语言的。如果条件允许,可以利用密码生成器生成一
个完全随机的12位以上的密码。请记住:比特币是一种随时能被转
移到世界其他任何地方的货币。如果不加以妥善保管,会很容易被
偷走。
Alice下载并安装了Multibit客户端后,打开程序就会出现一个欢迎界
面,如图1-1所示:图1-1 Multibit比特币客户端的欢迎界面
Multibit客户端会自动为Alice生成一个钱包和一个全新的比特币地址,点击图1-2所示的请求标签即可看到。图1-2 Multibit客户端请求标签中Alice的新比特币地址
界面中最重要的是Alice的比特币地址。类似于电子邮件的地址,Alice
可以分享这个地址,这样任何人都可以通过这个地址直接将比特币发送
到的新钱包里。界面上看起来一长串的字母和数字就是地址:
1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK。
地址旁是一个二维码。这个二维码是可以被智能手机摄像头扫描到该钱
包地址的条形码,即窗口右边黑白相间的方块。通过点击比特币地址或
二维码旁边的复制按钮,Alice可以将它们分别复制到剪贴板。点击二维
码可以将其放大,便于智能手机扫描。
Alice也可以打印出这个地址二维码给别人,这样就不用打一长串字母和
数字了。
比特币地址以数字1或3开头。类似于电子邮件地址,这些地址可以分享
给其他的比特币的用户,这样他们就可以直接通过这些地址发送比特币
到你的钱包里。不同于电邮地址的是,你可以任意地创建新的比特币地
址,这些地址都能成功地将资金转到你的钱包。钱包是多个地址和解锁
资金密钥的简单集合。每笔交易你都可以使用不同的地址,这有利于提
高隐私的安全性。用户可创建地址的数量几乎不受限制。
现在Alice已经准备好开始使用她的新比特币钱包了。1.4.2 获取你的第一枚比特币
现在你还无法在银行或是外币兑换处买到比特币。截至2014年,在大多
数国家,购买比特币还是相当困难的。你可以去一些专门的通货交易
所,购买比特币或是出售比特币换取当地货币,交易所是以在线通货市
场的方式来运营。包括以下几种:
Bitstamp
一个欧洲通货市场,通过电汇方式,支持包括欧元、美元在内的多币种
交易。
Coinbase
美国比特币钱包,也是买家和卖家进行比特币交易的一个平台。
Coinbase允许用户通过ACH系统来连接美国支票账户,这样易于购买和
出售比特币。
这一类的数字加密货币交易所,在国家货币和加密货币夹缝中求生存。
因此,会受各国法规和国际法规的制约,而且往往会具体到某单个国家
或经济区,并只限于该地区的国家货币。你所选择的货币交易所,只限
于你使用的本国货币,也只能是在你国范围内合法运营的交易所。类似
于在银行开户,用此类服务来设置这些必要的账户需要花费数日或数周
的时间,因为他们需要各种形式来了解你的客户,确认交易将符合反洗
钱法。一旦你拥有了交易所的一个账户,你就可以像用代理账户购买出
售外币一样的,更快捷地购买或出售比特币了。
bitcoin charts 是提供价格索引的站点,一个包括数十家货币交易所其他
市场数据的站点,在这里你可以找到更完整的数据。
新用户有以下四种方法来获取比特币:
找个有比特币的朋友,直接向他购买一些。很多比特币用户都是这
样开始的。
利用 localbitcoins.com 这样的分类服务网站来寻找你所在地区的卖
家,使用现金进行面对面的线下交易。 ? 出售某种产品或服务来换取比特币。如果你是个程序员,可以出售
你的编程技能。
使用你所在地区的比特币ATM机。利用CoinDesk里的 在线地图 来找
到你附近的比特币取款机。
Alice是经朋友介绍认识比特币的,所以在等待加州通货市场上的账号被
验证和激活的同时,她轻而易举的就获取了她的第一枚比特币。
1.4.3 发送和接收比特币
Alice已经创建好她的比特币钱包,准备接收资金了。她的钱包程序随机
生成了一个私钥(关于私钥的详细介绍见“ 4.1.3 私钥 “)和对应的比特
币地址。这时,她的比特币地址还未在全网公布,也未在在任何比特币
系统中“登记”。她的比特币地址只是一串数字,对应一个她可以掌控的
资金私钥。在该地址和账户之间还没有任何交易产生,也没有任何关
联。直到这个地址接收到在比特币账簿(区块链)中公布过的一笔交易
时,才会成为众多可能“有效”的比特币地址之一。一旦该地址接受了一
笔交易,就会变成全网所知的地址之一,Alice就可以在公开账簿中查询
余额了。
Alice和Joe约在当地的一个饭店里会面,正是Joe把比特币介绍给了Alice
的。这样Alice就可以用美金向Joe换取一些比特币,让Joe发送一些比特
币到她的账户里。她带来了打印版的比特币地址和钱包二维码。从安全
角度来说,比特币地址没什么特别机密的。她可以在任何地方公布自己
的地址,而不用担心帐户安全。
Alice只想兑换10美元的比特币,免得在这项新技术上冒险花太多钱。所
以她给了Joe 10美元和她地址的打印件,这样Joe就可以给她发送等值的
比特币了。
接下来Joe需要弄清楚汇率,以便于发送给Alice相应数额的比特币。有
很多应用和网站都会提供当前的市场汇率,下列是一些最流行的:
Bitcoin Charts
Bitcoin Chart 是一个市场数据服务网站,显示了全球众多交易所的比特
币市场汇率,以当地不同的汇率来进行结算。Bitcoin Average
Bitcoin Average是一个提供每个币种的交易量加权平均价格的简单视图
网站。
ZeroBlock
ZeroBlock是一个免费的安卓和iOS应用程序,可以显示不同交易所的比
特币价格。(见图1-3)
Bitcoin Wisdom
另一个市场数据索引服务站。图1-3 ZeroBlock,一款基于安卓和iOS系统的比特币市场汇率应用
程序
Joe使用上述的程序或网站中的其中一个,查到比特币的价格约为每个
比特币价值100美元左右。按照这个汇率,Alice给了他10美元,作为交
换,他应当给Alice 0.1个比特币,即10,000,000聪。
Joe查到一个市场价后,打开自己的手机钱包应用,选择“发送”比特
币。图1-4 Blockchain 手机钱包的比特币发送界面
例如,如果是在苹果手机上使用Blockchain手机钱包,他会看见屏幕上
要求输入:
对方的收款地址
需要发送的比特币数量
在比特币地址的输入栏,有一个看起来像二维码的小图标。Joe可以用
他的智能手机摄像头扫描条形码,而不用再输入Alice的比特币地址
(1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK)了,不用再打出这个又长
又繁琐的地址。Joe轻击二维码图标,启动智能手机的摄像头,然后扫
描Alice带来的二维码打印版。手机钱包程序会填好比特币地址,Joe可
以通过比较这个地址和Alice打印的地址中的几个数字,来确认已正确地
扫描。
接着Joe输入了交易的比特币金额,0.1比特币。他仔细检查,确保已经
输入了正确的金额,因为他马上要发送这些钱了,任何一点点的小失误
都会导致发送到错误的地址。最后,他按下了发送键来完成这笔交易。
Joe的手机钱包会创建一笔交易,将Joe的钱包里的0.10比特币发送到
Alice提供的地址,利用Joe的私钥来签名这笔交易。这就公告了比特币
全网,Joe已经授权允许从他的一个地址转账比特币到Alice的新地址。
由于交易是通过P2P网络协议传输,它会迅速在整个比特币网络传播。
不到一秒钟,网络中大多数连接良好的节点都会收到该交易信息,并首
次公布Alice的地址。
如果Alice手边有智能手机或笔记本电脑,她也能看到这笔交易。比特币
账簿—一个不断膨胀的文件记录,记载了每一笔曾发生过的比特币交易
—是公开的,意味着她可以查看所有曾经使用该地址的记录,可以查看
是否有人朝这个账户发送了比特币。她只要在blockchain.info网站的搜
索框中,输入她自己的地址,就可以轻而易举的知晓了。网页会显示出
该地址所有的交易记录 。Joe点击发送后,0.10比特币会很快转到她的
钱包里,如果Alice正看这个页面,她就会发现网页更新了这笔新交易信
息。确认
起初,Alice的地址会显示Joe发出这笔的交易为“未确认”,这意味
着这笔交易已经被广播到网络,但是尚未列入比特币交易记录账
簿,即区块链中。总的来说,交易必须由一个矿工“开采”,交易是
包括在区块中的。当新区块创建时,大约十分钟左右,该区域内的
交易就会被全网接受为“已确认”,区块中的比特币也都能使用。交
易可以立即被其他人看到,但只有当其被包含在新开采的区块中,才是“被信任的”。
第2章 比特币的原理
2.1 交易、区块、挖矿和区块链
与传统银行和支付系统不同,比特币系统是以去中心化信任为基础的。
由于比特币网络中不存在中央权威信任机构,“信任”成为了比特币用户
之间存在的一种突出特性。在本章中,我们将从一个较高层面检视比特
币,通过追踪一笔比特币系统中的单独交易,来看看它在比特币分布式
共识机制中变得“被信任”和“被接受”的情形,以及最终成功地被存储到
区块链(区块链是一个分布式的公共账簿,包含所有发生在比特币系统
中的交易)。
书中每一个例子都是比特币网络中发生的真实交易,通过将资金从一钱
包发送到另一钱包来模拟用户(Joe、Alice和Bob)间的交互。我们在追
踪一笔通过比特币网络和区块链的交易时,将用到一些区块链数据库查
询网站使每个步骤可以方便在网页上直接被呈现。提供区块链数据查询
的网站就像是一个比特币的搜索引擎,你可以搜索比特币的地址、交易
和区块,以及可以看他们之间的关系和资金流动。
常见的区块链数据查询网站包括:
Blockchain info
Bitcoin Block Explorer
insight ? blockr Block Reader
以上每一个查询网站都有搜索功能,可以通过地址,交易哈希值或区块
号,搜索到在比特币网络和区块链中对应的等价数据。我们将给每个例
子提供一个链接,可以直接带你到相关条目,方便你做详细研究。
2.1.1 比特币概述
图2-1 比特币概述
如图2-1所示的概述图中,我们可以看到比特币系统由用户(用户通过密钥控制钱包)、交易(每一笔交易都会被广播到整个比特币网络)和
矿工(通过竞争计算生成在每个节点达成共识的区块链,区块链是一个
分布式的公共权威账簿,包含了比特币网络发生的所有的交易)组成。
在本章中,我们将通过追踪在网络上传输的一笔交易,从整个比特币系
统的的视角检视各个部分之间的交互。后续章节将详细阐述钱包、挖
矿、商家系统背后的技术细节。
2.1.2 买咖啡
在之前章节里,Alice是一名刚刚获得第一枚比特币的新用户。在“ 1.4.2
获取你的第一枚比特币 ”一节中,Alice和她的朋友Joe会面时,用现金换
取了比特币。由Joe产生的这笔交易使得Alice的钱包拥有了0.10比特
币。现在Alice将第一次使用比特币在加利福尼亚州帕罗奥图的Bob咖啡
店买一杯咖啡。Bob咖啡店给他的销售网点系统新增加了一个比特币支
付选项,价格单上列的是当地货币(美元)的售价,但在收银台,顾客
可以选择用美元或比特币支付。此时,Alice点了杯咖啡,然后Bob将交
易键入到收银机,之后销售系统将按照当前市场汇率把美元总价转换为
比特币,然后同时显示两种货币的价格,并显示一个包含这笔交易支付
请求的二维码(如图2-2所示):
图2-2
总价:
1.50 USD
0.0150 BTC这个二维码中的URL是:
bitcoin:1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA?
amount=0.015
label=Bob%27s%20Cafe
message=Purchase%20at%20Bob%27s%20Cafe
根据BIP0021的定义,此URL的意思是:
A bitcoin address: 1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA
The payment amount: 0.015
A label for the recipient address: Bob's Cafe
A description for the payment: Purchase at Bob's Cafe
与一个简单包含目的比特币地址的二维码不同,当前支付请求的是
一个二维编码过的URL,它包含有一个目的地址,一笔支付金额,和一个像“Bob咖啡”这样的交易描述。这使比特币钱包应用在发送支付请求时,可以预先填好支付用的特定信息,给用户显示一种友
好易懂的描述。你可以用比特币钱包应用扫描这个二维码来看Alice
可能看到的信息。
Bob说到,“总共1.50美元,或15毫比特币”
Alice用她的智能手机扫描了显示的条形码。她的智能手机显示一笔给
Bob咖啡的0.0150比特币的支付请求,然后她按下发送键授权了这笔支
付。在几秒钟时间内(大约与信用卡授权所需时间相同)Bob将会在收
银台看到这笔交易,并完成交易。
在接下来的章节中,我们将更详细地检视这笔交易,观察Alice的钱包是
怎样构建交易,交易又是怎样在网络中广播、怎样被验证,以及Bob在
后续交易中怎样消费那笔钱。
从千分之一比特币(1毫比特币)到一亿分之一比特币(1聪比特
币),比特币网络可以处理任意小额交易。在本书中,我们将
用“比特币”这个术语来表示任意数量的比特币货币,从最小单元
(1聪)到可被挖出的所有比特币总数(21,000,000)。
2.2 比特币交易
简单来说,交易告知全网:比特币的持有者已授权把比特币转帐给其他
人。而新持有者能够再次授权,转移给该比特币所有权链中的其他人,产生另一笔交易来花掉这些比特币,后面的持有者在花费比特币也是用
类似的方式。
交易就像复式记账法账簿中的行。简单来说,每一笔交易包含一个或多
个“输入”,输入是针对一个比特币账号的负债。这笔交易的另一面,有
一个或多个“输出”,被当成信用点数记入到比特币账户中。这些输入和
输出的总额(负债和信用)不需要相等。相反,当输出累加略少于输入
量时,两者的差额就代表了一笔隐含的“矿工费”,这也是将交易放进账簿的矿工所收集到的一笔小额支付。如图2-3描述的是一笔作为记账簿
记录的比特币交易。
图2-3
交易也包含了每一笔被转移的比特币(输入)的所有权证明,它以所有
者的数字签名形式存在,并可以被任何人独立验证。在比特币术语
中,“消费”指的是签署一笔交易:转移一笔以前交易的比特币给以比特
币地址所标识的新所有者。
交易是将钱从交易输入移至输出。输入是指钱币的来源,通常是之
前一笔交易的输出。交易的输出则是通过关联一个密钥的方式将钱
赋予一个新的所有者。目的密钥被称为是安全锁(Encumbrance)。这样就给资金强加了一个要求:有签名才能在
以后的交易中赎回资金。一笔交易的输出可以被当做另一笔新交易
的输入,这样随着钱从一个地址被移动到另一个地址的同时形成了
一条所有权链(如图2-4)。
图2-4
Alice支付Bob咖啡时使用一笔之前的交易作为输入。在以前的章节中,Alice从她朋友Joe那里用现金换了点比特币。那笔交易有一些比特币被
Alice的密钥锁定(阻塞)。在她支付Bob咖啡店的新交易中使用了之前
的交易作为输入,并以支付咖啡和找零作为新的输出。交易形成了一条
链,最近交易的输入对应以前交易的输出。Alice的密钥提供了解锁之前
交易输出的签名,因此向比特币网络证明她拥有这笔钱。她将咖啡的支
付附到Bob的地址上,同时“阻塞”那笔输出,指明要求是Bob签名才能
消费这笔钱。这就描述了在Alice和Bob之间钱的转移。上图展示了从Joe
到Alice再到Bob的交易链。2.2.1 常见的交易形式
最常见的交易形式是从一个地址到另一个地址的简单支付,这种交易也
常常包含给支付者的“找零”。一般交易有一个输入和两个输出,如图2-
5所示:
图2-5
另一种常见的交易形式是集合多个输入到一个输出(如图2-6)的模
式。这相当于现实生活中将很多硬币和纸币零钱兑换为一个大额面钞。
像这样的交易有时由钱包应用产生来清理许多在支付过程收到的小数额
的找零。
图2-6
最后,另一种在比特币账簿中常见的交易形式是将一个输入分配给多个
输出,即多个接收者(如图2-7)的交易。这类交易有时被商业实体用
作分配资金,例如给多个雇员发工资的情形。
图2-7
2.3 交易的构建
Alice的钱包应用知道如何选取合适的输入和输出以建立Alice所希望的
交易。Alice只需要指定目标地址和金额,其余的细节钱包应用会在后台
自动完成。很重要的一点是,钱包应用甚至可以在完全离线时建立交
易。就像在家里写张支票,之后放到信封发给银行一样,比特币交易建
立和签名时不用连接比特币网络。只有在执行交易时才需要将交易发送
到网络。
2.3.1 获取正确的输入
Alice的钱包应用首先要找到一些足够支付给Bob所需金额的输入。大多
数钱包应用维护着一个含有用钱包自己密钥锁定的“未消费交易输出”小
型数据库。因此Alice的钱包会包含她用现金从Joe那里购买的比特币的
交易输出副本(参见在“ 1.4.2 获取你的第一枚比特币 ”一节)。完整客
户端含有整个区块链中所有交易的所有未消费输出副本。这使得钱包即
能拿这些输出构建交易,又能在收到新交易时很快地验证其输入是否正确。然而,完整客户端占太大的硬盘空间,所以大多数钱包使用轻量级
的客户端,只保存用户自己的未消费输出。
如果钱包客户端没有某一未消费交易输出,它可以通过不同的服务者提
供的各种API或完整索引节点的JSON PRC API从比特币网络中拿到这一
交易信息。例子2-1展示了用HTTP GET命令对一个特定URL建立了一个
RESTful API的请求。这个URL会返回一个地址的所有未消费交易输
出,以提供给需要这些信息的任何应用作为建立新交易的输入而进行消
费。我们用一个简单的HTTP命令行客户端 cURL来获得这个响应数据。
例2-1 查找Alice的比特币地址所有的未消费的输出
curl https:blockchain.infounspent?active=1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK
例2-2 查找返回的响应数据
{
unspent_outputs: [
{
tx_hash:186f9f998a5...2836dd734d2804fe65fa35779,tx_index:104810202,tx_output_n:0,script:76a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac,value:10000000,value_hex:00989680,confirmations:0
}
]}
例2-2的响应数据显示了在Alice的地址
1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK 上面有一个未消费输出(还
未被兑换)。这个响应包含一个交易的索引。而从Joe那里转过来的未
消费输入就包含在这个交易里面,它的价值是一千万聪(satoshi),即
0.10比特币。通过这个信息,Alice的钱包应用就可以创建新的交易将钱
转账到新地址。
点击查看Joe和Alice间的交易信息
如你所见,Alice的钱包在单个未消费的输出中有足够的比特币支付一杯
咖啡。假如不够的话,Alice的钱包应用就不得不搜寻一些小的未消费输
出,像是从一个存钱罐里找硬币一样,直到找到足够支付咖啡的数量。
在两种情境下,可能都需要找回零钱,而这些找零也会是钱包所创建的
交易的输出组成部分。我们会在下一节会有所描述。
2.3.2 创建交易输出
交易的输出会被创建成为一个包含这笔数额的脚本的形式,只能被引入
这个脚本的一个解答后才能兑换。简单点说就是,Alice的交易输出会包
含一个脚本,这个脚本说 “这个输出谁能拿出一个签名和Bob的公开地
址匹配上,就支付给谁”。因为只有Bob的钱包的私钥可以匹配这个地
址,所以只有Bob的钱包可以提供这个签名以兑换这笔输出。因此Alice
会用需要Bob的签名来包装一个输出。
这个交易还会包含第二个输出。因为Alice的金额是0.10比特币的输出形式,对0.015 比特币一杯的咖啡来说太多了,需要找Alice 0.085比特币的
零钱。Alice钱包创建给她的零钱的支付就在付给Bob的同一个交易里
面。可以说,Alice的钱包将她的金额分成了两个支付:一个给Bob,一
个给自己。她可以在以后的交易里消费这笔零钱输出。
最后,为了让这笔交易尽快地被网络处理,Alice的钱包会多付一小笔费
用。这个不是明显地包含在交易中的;而是通过输入和输出的差值所隐
含的。如果Alice创建找零时只找 0.0845比特币,而不是 0.085比特币的
话,这里就有剩下 0.0005比特币(50万聪) 。因为加起来小到 0.10,所以这个 0.10 比特币的输入就没有被完整的消费了。这个差值会就被
矿工当作交易费放到区块的交易里,最终放进区块链帐薄中。
这个交易的结果信息可以用区块链数据查询站点看到,如图2-8所示。
图2-8
点击查看Alice支付Bob咖啡的交易的信息
2.3.3 将交易放到总账簿中
这个被Alice钱包应用创建的交易大小为258字节,包含了金额未来所属
需要的全部信息。现在,这个交易必须要被传送到比特币网络中以成为
分布式账簿(区块链)的一部分。在下一节里,我们来看下一个交易如
何成为新区块的一部分,以及区块是如何被挖矿构建的。最后,我们会
看看新区块被加进区块链后,是如何随更多区块的添加而增加可信度
的。
2.3.3.1 交易的传送
因为这个交易包含处理所需的所有信息,所以这个交易是被如何或从哪
里传送到比特币网络的就无所谓了。比特币网络是由参与的比特币客户
端联接几个其他比特币客户端组成的P2P网络。比特币网络的目的是将
交易和区块传播给所有参与者。
2.3.3.2 如何传播
Alice的钱包应用可以发送新的交易给其它任意一个已联接到互联网的比
特币客户端,不论其是由有线网、WiFi、还是通过手机联接的。她的钱
包不必直接连着Bob的比特币钱包,且她不必使用咖啡厅提供的网络联
网,虽然这两者都是可能的。任何比特币网络节点(其它客户端)收到
一个之前没见过的有效交易时会立刻将它转发给联接到自身的其它节
点。因此,这个交易迅速地从P2P网络中传播开来,几秒内就能到达大
多数节点。
2.3.3.3 Bob的视角
如果Bob的比特币钱包应用是直接连接Alice的钱包应用的话,Bob的钱
包应用也许就是第一个收到这个交易的节点。然而,即使Alice的交易是从通过其它节点发过来的,一样可以在几秒钟内到达Bob钱包应用这
里。Bob的钱包会立即确认Alice的交易是一个收入支付,因为它包含能
用Bob的私钥兑换的输出。Bob的钱包应用也能够独立地用之前未消费
输入来确认这个交易是正确构建的,并且由于包含足够交易费会被下一
个区块包含进去。这时Bob就可以以一个很小的风险假定这个交易会很
快被加到区块且被确认。
一个对比特币交易的常见误解是它们必须要等10分钟后被确认加进
一个新区块,或等60分钟以得到六次确认后才是有效的。虽然这些
确认可以确保交易已被整个网络接受,但对于像一杯咖啡这样的小
额商品来说就没有必要等待那么长时间了。一个商家可以免确认来
接受比特币小额支付。这样做的风险不比接受一个不是用有效身份
证领取或没有签名的信用卡的风险更大,而后者是现在商家常做的
事情。
2.4 比特币挖矿
这个交易现在在比特币网络上传播开来。但只有被一个称为挖矿的过程
验证且加到一个区块中之后,这个交易才会成为这个共享账簿(区块
链)的一部分。关于挖矿的详细描述请见 第8章 。
比特币系统的信任是建立在计算的基础上的。交易被包在一起放进区块
中时需要极大的计算量来证明,但只需少量计算就能验证它们已被证
明。挖矿在比特币系统中起着两个作用:
挖矿在构建区块时会创造新的比特币,和一个中央银行印发新的纸
币很类似。每个区块创造的比特币数量是固定的,随时间会渐渐减少。
挖矿创建信任。挖矿确保只有在包含交易的区块上贡献了足够的计
算量后,这些交易才被确认。区块越多,花费的计算量越大,意味着更
多的信任。描述挖矿的一个好方法是将之类比为一个巨大的多人数独谜题游戏。一
旦有人发现正解之后,这个数独游戏会自动调整困难度以使游戏每次需
要大约10分钟解决。想象一个有几千行几千列的巨大数独游戏。如果给
你一个已经完成的数独,你可以很快地验证它。然而,如果这个数独只
有几个方格里有数字其余方格都为空的话,就会花费非常长的时间来解
决。这个数独游戏的困难度可以通过改变其大小(更多或更少行列)来
调整,但即使它非常大时验证它也是相当容易的。而比特币中的 谜题
是基于哈希加密算法的,其展现了相似的特性:非对称地,它解起来困
难而验证很容易,并且它的困难度可以调整。
在 “ 1.3 比特币的应用、用户和他们的故事 ”一节中,我们提到了一个叫
Jing的在上海学计算机工程的学生。Jing在比特币网络中扮演了一个矿
工的角色。大概每10分钟,Jing和其他上千个矿工一起展开一场对一个
区块的交易寻找正解的全球竞赛。为寻找这个解,也被称为工作量证
明,整个网络需要具有每秒亿万次哈希计算的能力。这个工作量证明算
法指的用SHA256加密算法不断地对区块头和一个随机数字进行哈希计
算,直到出现一个和预设值相匹配的解。第一个找到这个解的矿工会赢
得这局竞赛并会将此区块发布到区块链中。
Jing从2010年开始挖矿,当时他使用一个非常快的桌面电脑来为新区块
寻找正解。随着更多的矿工加入比特币网络中,寻找谜题正解的困难度
迅速增大。不久,Jing和其他矿工升级成更专业的硬件,比如游戏桌面
电脑或控制台专用的高端独享图像处理单元芯片(即显卡GPU)。在写
这本书的时候,解题已经变得极其困难,只有使用集成了几百个挖矿专
用算法硬件并能同时在一个单独芯片上并行工作的专用集成电路
(ASIC)挖矿才会营利。Jing同时加入了一个类似彩票奖池的、能够让
多个矿工共享计算力和报酬的矿池。Jing现在运行两个通过USB联接的
ASIC机器每天24小时不间断地挖矿。他卖掉一些挖矿所得到的比特币
来支付电费,并可以通过营利获得一些收入。作为专用挖矿软件的后
台,他的计算机里安装了一个比特币索引客户端,名称为bitcoind。
2.5 区块中的挖矿交易记录
网络中产生的一笔交易直到成为整个比特币大账簿——区块链的一部分
时才会被确认有效。平均每10分钟,矿工会将自上一个区块以来发生的
所有交易生成一个新的区块。新交易不断地从用户钱包和应用流入比特
币网络。当比特币网络上的节点看到这些交易时,会先将它们放到各自节点维护的一个临时的未经验证的交易池中。当矿工构建一个新区块
时,会将这些交易从这个交易池中拿出来放到这个新区块中,然后通过
尝试解决一个非常困难的问题(也叫工作量证明)以证明这个新区块的
合法性。挖矿过程的细节会在 “8.1 简介” 一节中详加描述。
这些交易被加进新区块时,以交易费用高的优先以及其它的一些规则进
行排序。矿工一旦从网络上收到一个新区块时,会意识到在这个区块上
的解题竞赛已经输掉了,会马上开始下一个新区块的挖掘工作。它会立
刻将一些交易和这个新区块的数字指纹放在一起开始构建下一个新区
块,并开始给它计算工作量证明。每个矿工会在他的区块中包含一个特
殊的交易,将新生成的比特币(当前每区块为25比特币)作为报酬支付
到他自己的比特币地址。如果他找到了使得新区块有效的解法,他就会
得到这笔报酬,因为这个新区块被加入到了总区块链中,他添加的这笔
报酬交易也会变成可消费的。参与矿池的Jing设置了他的软件,使得构
建新区块时会将报酬地址设为矿池的地址。然后根据各自上一轮贡献的
工作量将所得的报酬分给Jing和其他参与矿池挖矿的矿工。
Alice的交易被网络拿到后放进未验证交易池中。因为包含足够的交易
费,它被Jing的矿池放到了生成的新区块中。大约在Alice的钱包第一次
将这个交易发送出来五分钟后,Jing的ASIC矿机发现了新区块的正解并
将之发布为第277,316号区块,包含419个其它交易。Jing的ASIC矿机将
这个新区块发布到网络上后,其它矿机就会验证它,并投身到构建新区
块的竞赛中。
你可以查看包含 Alice交易记录 的这个区块的信息。
几分钟后,第277,317号新区块诞生在另一个挖矿节点中。因为这个新
区块是基于包含Alice交易的第277,316号区块的,在这个区块的基础上
增加了更多的计算,因此就加强了这些交易的可信度。包含Alice交易的
区块对这个交易来说算一次证明。基于这个区块每产生一个新区块,对这个交易来说就会增加了一次证明。当区块一个个堆上来时,这个
交易变得指数级地越来越难被推翻,因此它在网络中得到更多信任。
图2-9
在图2-9中,我们可以看到包含Alice的交易的第277,316号区块。在它之
下有377,361个区块(包括0号区块),像链子一样一个连着一个(区块
链),一直连到0号区块,即创世区块。随着时间变长,这个区块链的
高度也随之增长,每个区块和整个链的计算复杂度也随之增加。包含
Alice的交易的区块后面形成的新区块使得信任度进一步增加,因为他们
叠加了更多的计算在这个越来越长的链子上。按惯例来说,一个区块获
得六次以上“证明”时就被认为是不可撤销的了,因为要撤销和重建六个
区块需要巨量的计算。在 第8章 我们会详细描述挖矿和信任建立的过
程。
2.6 消费这笔交易
既然Alice的这笔交易已经成为区块的一部分被嵌入到了区块链中,它就
成为了整个分布式比特币账簿的一部分并对所有比特币客户端应用可见。每个比特币客户端都能独立地验证这笔交易是有效且可消费的。全
索引客户端可以追钱款的来源,从第一次有比特币在区块里生成的那一
刻开始,按交易与交易间的关系顺藤摸瓜,直到Bob的交易地址。轻量
级客户端通过确认一个交易在区块链中且在它后面有几个新区块来确认
一个支付的合法性。这种方式叫做简易支付验证(参见 “6.7 简易支付验
证(SPV)节点” )。
Bob现在可以将此交易和其它交易的结果信息作为输入,创建新的所有
权为其他人的交易。这样就实现了对此交易的消费。举个例子,Bob可
以用Alice支付咖啡的比特币转账给承包商或供应商以支付相应费用。大
多数情况下,Bob用的比特币商户端会将多个小额支付聚合成一个大的
支付,也许会将一整天的比特币收入聚合成一个交易。这样会将多个支
付合成到咖啡店财务账户的一个单独地址。图2-6为交易集合示例。
当Bob花费从Alice和其他顾客那里赚得的比特币时,他就扩展了比特币
的交易链条。而这个链条会被加到整个区块链账簿,使所有人知晓并信
任。我们假定Bob向在邦加罗尔的网站设计师Gopesh支付一个新网页的
设计费用。那么区块交易链会如图2-10所示。
图2-10
第3章 比特币客户端3.1 比特币核心:参考实现
你可以从bitcoin.org下载标准客户端,即比特币核心,也叫“中本聪客户
端”(satoshi client)。它实现了比特币系统的所有方面,包括钱包、对
整个交易账簿(区块链)完整拷贝的交易确认引擎,和点对点比特币网
络中的一个完整网络节点。
在Bitcoin网站的选择钱包页面 ,下载参考客户端比特币核心。根据操作
系统不同,你将下载不同的可执行安装工具。对于Windows,它是一个
ZIP归档文件或.exe格式的可执行文件。对于Mac OS,它是一个.dmg格
式的磁盘映像。Linux版本包括用于Ubuntu系统的PPA包,或是 tar.gz格
式的压缩包。图3-1所示的Bitcoin.org页面上列出了一些推荐的比特币客
户端。
图3-1 选择比特币客户端
3.1.1 第一次运行比特币核心如果你下载了一个安装包,比如.exe、.dmg、或PPA,你可以和安装其
它任何应用程序一样,在你的操作系统上安装它。对于Windows,运
行.exe文件,按照提示一步步操作。对于Mac OS,启动.dmg文件,然后
将Bitcoin-QT 图标拖拽到你的应用程序目录就可以了。对于Ubuntu,在
文件资源管理器中双击PPA文件,会打开程序包管理器来安装它。一旦
完成了安装,在你的应用程序列表中会有一个新的应用叫Bitcoin-QT。
双击这个图标就可以启动比特币客户端了。
第一次运行比特币核心时,它会开始下载整个区块链,这个过程可能需
要数天(见下图)。让它在后台运行,直到显示“已同步”,并且余额旁
边不再显示“数据同步中”。
比特币核心拥有交易账簿(区块链)的一份完整拷贝,里面记录了
自2009年比特币网络被发明以来发生在比特币网络上的每一笔交
易。这个数据集有几个GB(在2013年底大约是16GB),并且需要
几天的时间完成增量形式的下载(从区块0顺次下载到最新区
块)。在整个区块链数据集下载完成前,客户端将不能处理任何交
易或是更新账户余额。在下载数据集的过程中,客户端账户余额旁
会显示“数据同步中”,底部会显示“正在同步”。请确保你有足够的
磁盘空间、带宽和时间来完成初始同步。
3.1.2 从源码编译比特币核心比特币核心
对于开发者,可以选择下载包含完整源代码的ZIP包,也可以从Github
上克隆权威的源码仓库。在面 GitHub上的比特币页面 ,在侧边栏选择
下载ZIP。或者使用git命令行(git command line)在自己系统上创建源
码的本地拷贝。在下面的例子中,我们将通过unix风格的命令行,在
Linux或是Mac OS 上克隆源代码:
git clone https:github.combitcoinbitcoin.git
Cloning into 'bitcoin'...remote: Counting objects: 31864, done.
remote: Compressing objects: 100% (1200712007), done.
remote: Total 31864 (delta 24480), reused 26530 (delta 19621)
Receiving objects: 100% (3186431864), 18.47 MiB | 119 KiBs, done.
Resolving deltas: 100% (2448024480), done.
终端上的提示和输出结果可能会因版本有所不同。即使你的屏幕上
输出的内容跟这里的例子有点不一样,请遵照代码中的文档,这些
都是正常的。
在git clone操作完成后,在你本地的bitcoin目录就会有一份完整的源码
拷贝。通过在命令提示行输入cd bitcoin切换到这个目录下:
cd bitcoin
默认情况下,本地拷贝将与最新的代码同步,这可能是bitcoin的一个不
稳定或是 beta 版本。在编译这些代码之前,签出发布标签(realease
tag)以选择某一特定版本(a specific version)。 这将通过一个关键的
标签标记,让本地拷贝与代码仓库的特定快照同步。开发者用标签来标
记代码的特定发行版本号(version numBTCer)。首先,要找到可用的
标签,可以通过git tag命令:
git tag
v0.1.5v0.1.6test1
v0.2.0
v0.2.10
v0.2.11
v0.2.12
[... many more tags ...]
v0.8.4rc2
v0.8.5
v0.8.6
v0.8.6rc1
v0.9.0rc1
列出的标签是bitcoin的所有发行版本。按照约定,带有rc后缀的是预发
行版本,可以用来测试。没有后缀的稳定版本可以直接在产品环境上运
行。从上面的列表中,选择最新的发行版本,目前是v0.9.0rc1。为了让
本地代码跟这个版本一致,我们需要用git checkout 命令:
git checkout v0.9.0rc1
Note: checking out 'v0.9.0rc1'.
HEAD is now at 15ec451... Merge pull request 3605
源代码包含文档,可以在多个文件夹中找到。在命令提示行输入more
README.md可以在bitcoin目录下的README.md中查看主文档,用空
格键可以翻页。在这一章,我们将构建命令行的比特币客户端,在linux
上称作bitcoind。在您的平台上,通过输入more docbuild-unix.md,可以
阅读编译bitcoind命令行客户端的说明。Mac OSX和Windows平台的说明
可以在doc目录下找到,分别是build-osx.md或是build-msw.md。
仔细阅读build文档第一部分中build的必备条件。这些是在你编译之前你
的系统上必须具备的库文件。如果缺少这些必备条件,构建过程将会出
现错误并导致失败。如果因为缺少一个必备条件而发生这种情况,你可
以先安装它,然后在你停下的地方重新构建。假设这些必备条件已经具
备,你就可以开始构建过程,通过authgen.sh脚本,生成一组构建脚
本。
从v0.9版本开始,比特币核心的构建过程改用
autogenconfiguremake 体系。旧版本是用一个简单的Makefile,并
且和下面的例子稍微有一点不同。请遵照你想要编译版本的说明文
档。v0.9版本引入的 autogenconfiguremake 构建体系可能用于未来
所有版本的代码,是下面的例子中演示的系统
.autogen.sh
configure.ac:12: installing `srcbuild-auxconfig.guess'
configure.ac:12: installing `srcbuild-auxconfig.sub'
configure.ac:37: installing `srcbuild-auxinstall-sh'
configure.ac:37: installing `srcbuild-auxmissing'
srcMakefile.am: installing `srcbuild-auxdepcomp'
autogen.sh脚本创建了一系列的自动配置脚本,会询问你的系统以发现
正确的设置,确保你已安装必要的库来编译源码。这里面最重要的是
configure脚本,它会提供许多不同的选项来定制构建过程。输
入.configure --help 可以查看各种不同的选项:
.configure --help
`configure' configures Bitcoin Core 0.9.0 to adapt to many kinds of systems.
Usage: .configure [OPTION]... [VAR=VALUE]...
To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.
See below for descriptions of some of the useful variables.
Defaults for the options are specified in brackets.
Configuration:
-h, --help display this help and exit--help=short display options specific to this package--help=recursive display the short help of all the included packages
-V, --version display version information and exit
[... many more options and variables are displayed below ...]Optional Features:--disable-option-checking ignore unrecognized --enable--with options--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
[... more options ...]
Use these variables to override the choices made by `configure' or to help it to
find libraries and programs with nonstandard nameslocations.
Report bugs to.
通过使用--enable-FEATURE和--disable-FEATURE选项,configure脚本
允许你启用或是禁用某些功能,FEATURE需要被替换成功能名称,在
上面的帮助输出中可以找到。在这一章,我们将用默认的功能来构建
bitcoind客户端。这里不会使用配置选项,但是你应该检查一遍,明白
哪些可选的功能可以作为客户端的一部分。下一次,运行configure脚本
就可以自动发现所有必要的库,然后为我们的系统创建一个定制的构建
脚本。
.configure
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking for a BSD-compatible install... usrbininstall -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... binmkdir -pchecking for gawk... no
checking for mawk... mawk
checking whether make sets (MAKE)... yes
[... many more system features are tested ...]
configure: creating .config.status
config.status: creating Makefile
config.status: creating srcMakefile
config.status: creating srctestMakefile
config.status: creating srcqtMakefile
config.status: creating srcqttestMakefile
config.status: creating sharesetup.nsi
config.status: creating shareqtInfo.plist
config.status: creating qapull-testerrun-bitcoind-for-test.sh
config.status: creating qapull-testerbuild-tests.sh
config.status: creating srcbitcoin-config.h
config.status: executing depfiles commands
如果一切顺利,configure命令将会以创建可定制的构建脚本结束。这些
构建脚本允许我们编译bitcoind。如果有缺失的库或是错误,configur命
令将会以错误信息终止。如果出现了错误,可能是因为缺少库或是有不
兼容的库。重新检查构建文档,确认你已经安装缺失的必备条件。然后
运行configure,看看错误是否消失了。下一步,你将编译源代码,这个
过程可能需要1个小时完成。在编译的过程中,你应该过几秒或是几分
钟看一下输出结果。如果出现了问题,你会看到错误。如果中断了,编
译的过程可以在任何时候恢复。输入make命令就可以开始编译了: make
Making all in src
make[1]: Entering directory `homeubuntubitcoinsrc'
make all-recursive
make[2]: Entering directory `homeubuntubitcoinsrc'
Making all in .
make[3]: Entering directory `homeubuntubitcoinsrc'
CXX addrman.o
CXX alert.o
CXX rpcserver.o
CXX bloom.o
CXX chainparams.o
[... many more compilation messages follow ...]
CXX test_bitcoin-wallet_tests.o
CXX test_bitcoin-rpc_wallet_tests.o
CXXLD test_bitcoin
make[4]: Leaving directory `homeubuntubitcoinsrctest'
make[3]: Leaving directory `homeubuntubitcoinsrctest'
make[2]: Leaving directory `homeubuntubitcoinsrc'
make[1]: Leaving directory `homeubuntubitcoinsrc'
make[1]: Entering directory `homeubuntubitcoin'
make[1]: Nothing to be done for `all-am'.
make[1]: Leaving directory `homeubuntubitcoin'
如果一切顺利,bitcoind现在已经编译完成。最后一步就是通过make命
令,安装 bitcoind 可执行文件到你的系统路径下:
sudo make install
Making install in src
Making install in .
binmkdir -p 'usrlocalbin'
usrbininstall -c bitcoind bitcoin-cli 'usrlocalbin'
Making install in test
make install-am
binmkdir -p 'usrlocalbin'
usrbininstall -c test_bitcoin 'usrlocalbin'
你可以通过询问系统下面2个可执行文件的路径,来确认bitcoin是否安
装成功。
which bitcoind
usrlocalbinbitcoind
which bitcoin-cli
usrlocalbinbitcoin-clibitcoind 默认的安装位置是usrlocalbin。当你第一次运行bitcoind时,它
会提醒你用一个安全密码给JSON-RPC接口创建一个配置文件。通过在
终端输入bitcoind就可以运行bitcoind了:
bitcoind
Error: To use the -server option, you must set a rpcpassword in the
configuration file:
homeubuntu.bitcoinbitcoin.conf
It is recommended you use the following random password:
rpcuser=bitcoinrpc
rpcpassword=2XA4DuKNCbtZXsBQRRNDEwEY2nM6M4H9Tx5dFjoAVVbK
(you do not need to remember this password)
The username and password MUST NOT be the same.
If the file does not exist, create it with owner-readable-only file permissions.
It is also recommended to set alertnotify so you are notified of problems;
for example: alertnotify=echo %s | mail -s Bitcoin Alert admin@foo.com
在你喜欢的编辑器中编辑配置文件并设置参数,将其中的密码替换成
bitcoind推荐的强密码。不要使用出现在这里的密码。在.bitcoin目录下
创建一个名为.bitcoinbitcoin.conf 的文件,然后输入用户名和密码:
rpcuser=bitcoinrpc
rpcpassword=2XA4DuKNCbtZXsBQRRNDEwEY2nM6M4H9Tx5dFjoAVVbK当你正在编辑配置文件的时候,你可能想要设置一些其他选项,例如
txindex(见 “交易数据库索引及txindex选项” )。通过输入 bitcoind --help
,可以查看所有可用的选项列表。
现在可以运行比特币核心客户端。当你第一次运行的时候,它会下载所
有的区块,重新构建比特币区块链。这是一个好几个GB的文件,可能
需要大约2天的时间全部下载完。你可以通过 SourceForge 上的BitTorrent
客户端下载区块链的部分拷贝来缩短区块链的初始化时间。
选项 -daemon 可以以后台模式运行 bitcoind。
bitcoind -daemon
Bitcoin version v0.9.0rc1-beta (2014-01-31 09:30:15 +0100)
Using OpenSSL version OpenSSL 1.0.1c 10 May 2012
Default data directory homebitcoin.bitcoin
Using data directory bitcoin
Using at most 4 connections (1024 file descriptors available)
init message: Verifying wallet...
dbenv.open LogDir=bitcoindatabase ErrorFile=bitcoindb.log
Bound to [::]:8333
Bound to 0.0.0.0:8333
init message: Loading block index...
Opening LevelDB in bitcoinblocksindex
Opened LevelDB successfully
Opening LevelDB in bitcoinchainstate
Opened LevelDB successfully
[... more startup messages ...]3.2 通过命令行使用比特币核心的JSON-
RPC API接口
比特币核心客户端实现了JSON-RPC接口,这个接口也可以通过命令行
帮助程序bitcoin-cli访问。命令行可以使用API进行编程,让我们有能力
进行交互实验。开始前,调用help命令查看可用的比特币RPC命令列
表:
bitcoin-cli help
addmultisigaddress nrequired [key,...] ( account )
addnode node add|remove|onetry
backupwallet destination
createmultisig nrequired [key,...]
createrawtransaction [{txid:id,vout:n},...] {address:amount,...}
decoderawtransaction hexstring
decodescript hex
dumpprivkey bitcoinaddress
dumpwallet filename
getaccount bitcoinaddress
getaccountaddress account
getaddednodeinfo dns ( node )
getaddressesbyaccount account
getbalance ( account minconf )
getbestblockhash
getblock hash ( verbose )
getblockchaininfogetblockcount
getblockhash index
getblocktemplate ( jsonrequestobject )
getconnectioncount
getdifficulty
getgenerate
gethashespersec
getinfo
getmininginfo
getnettotals
getnetworkhashps ( blocks height )
getnetworkinfo
getnewaddress ( account )
getpeerinfo
getrawchangeaddress
getrawmempool ( verbose )
getrawtransaction txid ( verbose )
getreceivedbyaccount account ( minconf )
getreceivedbyaddress bitcoinaddress ( minconf )
gettransaction txid
gettxout txid n ( includemempool )
gettxoutsetinfo
getunconfirmedbalance
getwalletinfo
getwork ( data )
help ( command )
importprivkey bitcoinprivkey ( label rescan )
importwallet filename
keypoolrefill ( newsize )
listaccounts ( minconf )
listaddressgroupingslistlockunspent
listreceivedbyaccount ( minconf includeempty )
listreceivedbyaddress ( minconf includeempty )
listsinceblock ( blockhash target-confirmations )
listtransactions ( account count from )
listunspent ( minconf maxconf [address,...] )
lockunspent unlock [{txid:txid,vout:n},...]
move fromaccount toaccount amount ( minconf comment )
ping
sendfrom fromaccount tobitcoinaddress amount ( minconf comment commentto)
sendmany fromaccount {address:amount,...} ( minconf comment )
sendrawtransaction hexstring ( allowhighfees )
sendtoaddress bitcoinaddress amount ( comment comment-to )
setaccount bitcoinaddress account
setgenerate generate ( genproclimit )
settxfee amount
signmessage bitcoinaddress message
signrawtransaction hexstring ( [{txid:id,vout:n,scriptPub-
Key:hex,redeemScript:hex},...] [privatekey1,...] sighashtype )
stop
submitblock hexdata ( jsonparametersobject )
validateaddress bitcoinaddress
verifychain ( checklevel numBTClocks )
verifymessage bitcoinaddress signature message
walletlock
walletpassphrase passphrase timeout
walletpassphrasechange oldpassphrase newpassphrase3.2.1 获得比特币核心客户端状态的信息
命令: getinfo
比特币 getinfo RPC命令显示关于比特币网络节点、钱包、区块链数据库
状态的基础信息。使用 bitcoin-cli 运行它:
bitcoin-cli getinfo
{
version : 90000,protocolversion : 70002,walletversion : 60000,balance : 0.00000000,blocks : 286216,timeoffset : -72,connections : 4,proxy : ,difficulty : 2621404453.06461525,testnet : false,keypoololdest : 1374553827,keypoolsize : 101,paytxfee : 0.00000000,errors :
}数据以JSON格式显示,JSON是一种可以很容易被编程语言“消耗”,但
同时对人类可读性也很高的格式。在这些数据中,我们看到比特币软件
客户端的版本编号(90000),协议编号(70002),钱包编号
(60000)。我们看到钱包中的当前余额是0。我们看到当前的区块高
度,这可以告诉我们有多少区块对此客户端已知(286216)。我们同样
看到关于比特币网络和关于此客户端的各种数据。我们将在其他章节中
更具体地探索这些设置。
bitcoind客户端需要花费可能超过一天的时间从其他比特币客户端
下载区块以“赶上”当前区块链高度。你可以使用getinfo命令查看已
知区块的数字以检查同步进度。
3.2.2 钱包设置及加密
命令: encryptwallet 、 walletpassphrase
在你向前生成秘钥和其他命令之前,你应当先用密码加密钱包。对于本
例,将使用 encryptwallet 命令,密码为“foo”。很明显,在你自己操作的
时候记得使用强且复杂的密码替换“foo”。
bitcoin-cli encryptwallet foo
wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet.
The keypool has been flushed, you need to make a new backup.
你可以再次使用 getinfo 命令以验证钱包是否已经加密。这次你将发现有
个叫做 unlocked_until 的新条目。这是一个计数器,告诉你保持钱包处于
解锁状态的解密密码将在内存中存储多久。最初计数器设置为0,意味
着钱包是被锁定的:
bitcoin-cli getinfo
{
version : 90000,[... other information...]
unlocked_until : 0,errors :
}
想解锁钱包,要使用 walletpassphrase 命令。 walletpassphrase 命令需要两个
参数——密码,和多久钱包会再次被自动锁定的秒数数字(计时器):
bitcoin-cli walletpassphrase foo 360
你可以确认钱包是解锁状态然后通过再次运行 getinfo 查看超过时限:
bitcoin-cli getinfo{
version : 90000,[... other information ...]
unlocked_until : 1392580909,errors :
}
3.2.3 钱包备份、纯文本导出及恢复
命令: backupwallet 、 importwallet 、 dumpwallet
下一步,我们将练习创建钱包的备份文件,然后从备份文件重新加载钱
包。使用 backupwallet 命令备份,提供文件名作为命令参数。这里我们将
钱包备份为文件 wallet.backup :
bitcoin-cli backupwallet wallet.backup
现在,为了重新加载备份文件,我们使用 importwallet 命令。如果你的钱
包处于锁定状态,你将需要先将钱包解锁(参考下一节的 walletpassphrase)以导入备份文件:
bitcoin-cli importwallet wallet.backup
dumpwallet 命令用来将钱包转储为人类可读的文本文件:
bitcoin-cli dumpwallet wallet.txt
more wallet.txt
Wallet dump created by Bitcoin v0.9.0rc1-beta (2014-01-31 09:30:15 +0100)
Created on 2014-02- 8dT20:34:55Z
Best block at time of backup was 286234
(0000000000000000f74f0bc9d3c186267bc45c7b91c49a0386538ac24c0d3a44), mined on 2014-02- 8dT20:24:01Z
KzTg2wn6Z8s7ai5NA9MVX4vstHRsqP26QKJCzLg4JvFrp6mMaGB9 2013-07- 4dT04:30:27Z
change=1 addr=16pJ6XkwSQv5ma5FSXMRPaXEYrENCEg47F
Kz3dVz7R6mUpXzdZy4gJEVZxXJwA15f198eVui4CUivXotzLBDKY 2013-07- 4dT04:30:27Z
change=1 addr=17oJds8kaN8LP8kuAkWTco6ZM7BGXFC3gk
[... many more keys ...]
3.2.4 钱包地址及接收交易
命令: getnewaddress 、 getreceivedbyaddress 、 listtransactions 、getaddressesbyaccount 、 getbalance
比特币参考客户端维护了一个地址池,地址池的大小可以用 getinfo 命令
keypoolsize 参数获取。这些地址是自动生成的,可以被用作公开接收地
址或零钱地址。使用 getnewaddress 命令可以获得其中的一个地址:
bitcoin-cli getnewaddress
1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL
现在我们可以使用这个地址从一个外部钱包(假设你在其他交易所、在
线钱包或其他bitcoind钱包有一些比特币)向我们的bitcoind钱包发送一
小笔比特币。在本例中,我们将向下面的地址中发送50mBTC(0.050比
特币)。
我们可以询问bitcoind客户端此地址已经接收到的比特币数额,以及指
定该数额要被加到余额中所需要的确认数。在本例中,我们指定只需要
0个确认。在从另一个钱包发送比特币数秒之后,我们将在这个钱包看
到反应。我们用 getreceivedbyaddress 命令、这个地址及设置确认数为0:
bitcoin-cli getreceivedbyaddress 1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL 0
0.05000000
如果我们忽略这个命令后面的0,我们将只能在至少 minconf 个确认之后
才能看到数额, minconf 是想要某笔交易出现在余额中所设置的最少确认
数。 minconf 设置在bitcoind配置文件指定。由于这笔发送比特币的交易仅在数秒之前完成,它还没有被确认,因而我们将看到余额是0:
bitcoin-cli getreceivedbyaddress 1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL
0.00000000
整个钱包接收到的交易可以通过使用 listtransactions 命令展示出来:
bitcoin-cli listtransactions
[
{
account : ,address:1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL,category : receive,amount : 0.05000000,confirmations : 0,txid : 9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309ac
bae2c14ae3,time : 1392660908,timereceived : 1392660908
}
]我们可以使用 getaddressesbyaccount 命令列出整个钱包的所有地址:
bitcoin-cli getaddressesbyaccount
[
1LQoTPYy1TyERbNV4zZbhEmgyfAipC6eqL,17vrg8uwMQUibkvS2ECRX4zpcVJ78iFaZS,1FvRHWhHBBZA8cGRRsGiAeqEzUmjJkJQWR,1NVJK3JsL41BF1KyxrUyJW5XHjunjfp2jz,14MZqqzCxjc99M5ipsQSRfieT7qPZcM7Df,1BhrGvtKFjTAhGdPGbrEwP3xvFjkJBuFCa,15nem8CX91XtQE8B1Hdv97jE8X44H3DQMT,1Q3q6taTsUiv3mMemEuQQJ9sGLEGaSjo81,1HoSiTg8sb16oE6SrmazQEwcGEv8obv9ns,13fE8BGhBvnoy68yZKuWJ2hheYKovSDjqM,1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL,1KHUmVfCJteJ21LmRXHSpPoe23rXKifAb2,1LqJZz1D9yHxG4cLkdujnqG5jNNGmPeAMD
]
最后, getbalance 命令将显示所有经过至少 minconf 个确认的交易加和后的
余额:
bitcoin-cli getbalance
0.05000000
如果交易还未被确认,getbalance返回的余额将为0。配置
项“minconf”决定了交易在余额中体现的最少确认数。
3.2.5 探索及解码交易
命令: gettransaction 、 getrawtransaction 、 decoderawtransaction
我们将使用 gettransaction 命令探索前面列出的入账交易。我们使用
gettransaction 命令通过交易哈希值获取一笔交易,交易哈希值出现在前
面的txid条目:
bitcoin-cli gettransaction
9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3
{
amount : 0.05000000,confirmations : 0,txid:9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3,time : 1392660908,timereceived : 1392660908,details : [
{
account : ,address:1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL,category : receive,amount : 0.05000000 }
]
}
交易ID在交易确认之前并不权威。区块链中找不到交易哈希值并不
意味着此笔交易没有进行。这被称作“交易延展性”,因为交易哈希
值在区块确认之前是可以更改的。在确认之后txid是不变且权威
的。
用 gettransaction 命令显示的交易格式为简化格式。若要得到整个交易代
码并且将之解码,我们将使用两个命令: getrawtransaction 和
decoderawtransaction 。第一, getrawtransaction 把交易哈希值(txid)当做一
个参数,并且把整个交易以一个“原始”的十六进制字符串的形式返回,而这也正是交易在比特币网络上存在的形式:
bitcoin-cli getrawtransaction
9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae30100000001d717279515f88e2f56ce4e8a31e2ae3e9f00ba1d0add648e80c480ea22e0c7d3000000008b483045022100a4ebbeec83225dedead659bbde7da3d026c8b8e12e61a2df0dd0758e227383b302203301768ef878007e9ef7c304f70ffaf1f2c975b192d34c5b9b2ac1bd193dfba2014104793ac8a58ea751f9710e39aad2e296cc14daa44fa59248be58ede65e4c4b884ac5b5b6dede05ba84727e34c8fd3ee1d6929d7a44b6e111d41cc79e05dbfe5ceaffffffff02404b4c00000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac1f312906000000001976a914107b7086b31518935c8d28703d66d09b3623134388ac00000000
要解码这个十六进制字符串,我们使用 decoderawtransaction 命令。复制粘
贴这个十六进制字符串作为 decoderawtransaction 的第一个参数以将整个内容解读为JSON数据格式(由于格式原因,在下面例子中十六进制字符
串被缩短):
bitcoin-cli decoderawtransaction 0100000001d717...388ac00000000
{
txid:9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3,version : 1,locktime : 0,vin : [
{
txid:d3c7e022ea80c4808e64dd0a1dba009f3eaee2318a4ece562f8ef815952717d7,vout : 0,scriptSig : {
asm :
3045022100a4ebbeec83225dedead659bbde7da3d026c8b8e12e61a2df0dd0758e227383b302203301768ef878007e9ef7c304f70ffaf1f2c975b192d34c5b9b2ac1bd193dfba20104793ac8a58ea751f9710e39aad2e296cc14daa44fa59248be58ede65e4c4b?
884ac5b5b6dede05ba84727e34c8fd3ee1d6929d7a44b6e111d41cc79e05dbfe5cea,hex:
483045022100a4ebbeec83225dedead659bbde7da3d026c8b8e12e61a2df0dd0758e227383b302203301768ef878007e9ef7c304f70ffaf1f2c975b192d34c5b9b2ac1bd193dfba2014104793ac8a58ea751f9710e39aad2e296cc14daa44fa59248be58ede65e4c4b884ac5b5b6dede05ba84727e34c8fd3ee1d6929d7a44b6e111d41cc79e05dbfe5cea
},sequence : 4294967295
}
],vout : [
{
value : 0.05000000,n : 0,scriptPubKey : {
asm : OP_DUP OP_HASH160
07bdb518fa2e6089fd810235cf1100c9c13d1fd2 OP_EQUALVERIFY OP_CHECKSIG,hex :76a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac,reqSigs : 1,type : pubkeyhash, addresses : [
1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL
]
}
},{
value : 1.03362847,n : 1,scriptPubKey : {
asm : OP_DUP OP_HASH160
107b7086b31518935c8d28703d66d09b36231343 OP_EQUALVERIFY OP_CHECKSIG,hex : 76a914107b7086b31518935c8d28703d66d09b3623134388ac,reqSigs : 1,type : pubkeyhash,addresses : [
12W9goQ3P7Waw5JH8fRVs1e2rVAKoGnvoy
]
}
}
]
}
交易解码展示这笔交易的所有成分,包括交易的输入及输出。在这个例
子中,我们可以看到这笔给我们新地址存入50mBTC的交易使用了一个
输入并且产生两个输出。这笔交易的输入是前一笔确认交易的输出(展
示位以d3c7开头的vin txid)。两个输出则是50mBTC存入额度及返回给
发送者的找零。我们可以使用相同命令(例如 gettransaction )通过检查由本次交易的txid
索引的前一笔交易进一步探索区块链。通过从一笔交易跳到另外一笔交
易,我们可以追溯一连串的交易,因为币值一定是从一个拥有者的地址
传送到另一个拥有者的地址。
一旦我们接收到的交易以记录在区块中的方式被确认, gettransaction 命
令将返回附加信息,显示包含交易的区块的哈希值(标识符)。
bitcoin-cli gettransaction
9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3
{
amount : 0.05000000,confirmations : 1,blockhash :
000000000000000051d2e759c63a26e247f185ecb7926ed7a6624bc31c2a717b,blockindex : 18,blocktime : 1392660808,txid : 9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3,time : 1392660908,timereceived : 1392660908,details : [
{
account : ,address : 1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL,category : receive,amount : 0.05000000
}
]
}这里,我们在区块哈希值(这笔交易所在区块的哈希值)条目看到新信
息,以及值为18的区块索引(表明我们的交易为此区块的第18笔交
易)。
交易数据库索引及txindex选项
比特币核心默认建立包含仅与用户钱包相关交易的数据库。若你想
使用类似 gettransaction 的命令访问所有交易,你需要配置比特币核
心去建立一个完整的交易索引,这个可以通过txindex选项实现。在
比特币核心配置文件中将 txindex 赋值为1(通常在安装目录的
.bitcoinbitcoin.conf 中可以找到)。一旦你改变了此参数,你需要
重启bitcoind,并等待其重建索引。
3.2.6 探索区块
命令: getblock 、 getblockhash
既然我们知道我们的交易在哪个区块中,我们可以使用 getblock 命令,并把区块哈希值作为参数来查询对应的区块:
bitcoin-cli getblock 000000000000000051d2e759c63a26e247f185ecb7926ed7a6624b?
c31c2a717b true
{
hash : 000000000000000051d2e759c63a26e247f185ecb7926ed7a6624bc31c2a717
b,confirmations : 2,size : 248758,height : 286384,version : 2,merkleroot :
9891747e37903016c3b77c7a0ef10acf467c530de52d84735bd55538719f9916,tx : [
46e130ab3c67d31d2b2c7f8fbc1ca71604a72e6bc504c8a35f777286c6d89bf0,2d5625725b66d6c1da88b80b41e8c07dc5179ae2553361c96b14bcf1ce2c3868, 923392fc41904894f32d7c127059bed27dbb3cfd550d87b9a2dc03824f249c80,f983739510a0f75837a82bfd9c96cd72090b15fa3928efb9cce95f6884203214,190e1b010d5a53161aa0733b953eb29ef1074070658aaa656f933ded1a177952,ee791ec8161440262f6e9144d5702f0057cef7e5767bc043879b7c2ff3ff5277,4c45449ff56582664abfadeb1907756d9bc90601d32387d9cfd4f1ef813b46be,3b031ed886c6d5220b3e3a28e3261727f3b4f0b29de5f93bc2de3e97938a8a53,14b533283751e34a8065952fd1cd2c954e3d37aaa69d4b183ac6483481e5497d,57b28365adaff61aaf60462e917a7cc9931904258127685c18f136eeaebd5d35,8c0cc19fff6b66980f90af39bee20294bc745baf32cd83199aa83a1f0cd6ca51,1b408640d54a1409d66ddaf3915a9dc2e8a6227439e8d91d2f74e704ba1cdae2,0568f4fad1fdeff4dc70b106b0f0ec7827642c05fe5d2295b9deba4f5c5f5168,9194bfe5756c7ec04743341a3605da285752685b9c7eebb594c6ed9ec9145f86,765038fc1d444c5d5db9163ba1cc74bba2b4f87dd87985342813bd24021b6faf,bff1caa9c20fa4eef33877765ee0a7d599fd1962417871ca63a2486476637136,d76aa89083f56fcce4d5bf7fcf20c0406abdac0375a2d3c62007f64aa80bed74,e57a4c70f91c8d9ba0ff0a55987ea578affb92daaa59c76820125f31a9584dfc,9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3,[... many more transactions ...]
],time : 1392660808,nonce : 3888130470,bits : 19015f53,difficulty : 3129573174.52228737,chainwork :
000000000000000000000000000000000000000000001931d1658fc04879e466,previousblockhash :
0000000000000000177e61d5f6ba6b9450e0dade9f39c257b4d48b4941ac77e7,nextblockhash :
0000000000000001239d2c3bf7f4c68a4ca673e434702a57da8fe0d829a92eb6这个区块包含367笔交易,并且如你所见,列出的第18笔交易( 9ca8f9…)就是存入50mBTC到我们地址的txid我们可以通过heigh条目来判断:
这就是整个区块链中第286,384个区块。
我们同样可以使用 getblockhash 命令通过区块高度来检索一个区块,这样
需要将区块高度作为参数,并返回那个区块的区块哈希值。
bitcoin-cli getblockhash 0000000000019d6689c085ae165831e934ff763ae46a2a6c17?
2b3f1b60a8ce26f
bitcoin-cli getblockhash
这里,我们获得了“创世区块”的区块哈希值,这是被中本聪所挖的第一
个区块,高度为0。所获得的区块信息如下:
bitcoin-cli getblock 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1?
b60a8ce26f
{
hash : 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26?f,confirmations : 286388,size : 285,height : 0,version : 1,merkleroot : 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7af? deda33b,tx : [
4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
],time : 1231006505,nonce : 2083236893,bits : 1d00ffff,difficulty : 1.00000000,chainwork :
0000000000000000000000000000000000000000000000000000000100010001,nextblockhash :
00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048
}
getblock 、 getblockhash 和 gettransaction 命令可以按照一定编程准则,去探
索区块链数据库。
3.2.7 基于UTXO(未花费的交易输出)的建立、签名与提交
命令: listunspent 、 gettxout 、 createrawtransaction 、 decoderawtransaction 、signrawtransaction 、 sendrawtransaction
比特币的交易是基于花费“输出”上的,即上一笔交易的支出,整个交易
在地址之间转移所有权。我们的钱包现在收到了一笔向我们钱包地址发
来的钱(输出)。一旦它被确定之后,那笔钱就属于我们了。
首先,我们可以使用 listunspent 命令去查看我们钱包中所有剩余的从之
前交易中已确认的支出:
bitcoin-cli listunspent[
{
txid :
9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3,vout : 0,address : 1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL,account : ,scriptPubKey : 76a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac,amount : 0.05000000,confirmations : 7
}
]
我们发现交易 9ca8f9 建立了一个被指派到 1hvzSo 地址的输出(“vout”一项
为0)对于50mBTC数量的比特币在这个时间点已经收到了7次确认。通
过参考交易之前的txit和vout指数,交易系统将先前的输出变为本次的输
入。我们现在可以创立一个花费第0个vout的易 9ca8f9 的账单。利用他的
输入分配成新的输出,即给新地址赋值。
首先,让我们仔细观察输出的结果。我们可以使用 gettxout 命令来得到
未花费的输出的详细细节。交易输出通常可以参考txid和vout两个指
标。以下就是我们通过 gettxout 命令得到的结果:
bitcoin-cli gettxout
9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3 0
{
bestblock :
0000000000000001405ce69bd4ceebcdfdb537749cebe89d371eb37e13899fd9,confirmations : 7,value : 0.05000000, scriptPubKey : {
asm : OP_DUP OP_HASH160 07bdb518fa2e6089fd810235cf1100c9c13d1fd2
OP_EQUALVERIFY OP_CHECKSIG,hex : 76a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac,reqSigs : 1,type : pubkeyhash,addresses : [
1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL
]
},version : 1,coinbase : false
}
在这里我们看到由50mBTC分配到我们的账户地址 1hvz… 中。如果我们想
用掉剩余的比特币,我们要重新建立一笔新的交易。首先,我们为这笔
交易建立一个新的地址,告诉它将去往哪里:
bitcoin-cli getnewaddress 1LnfTndy3qzXGN19Jwscj1T8LR3MVe3JDb
我们将25mBTC送往我们钱包中新的地址 1LnfTn… 。在这笔新的交易中,我们将要花费50mBTC并且放入25mBTC到这个新地址中。因为我们必
须花费所有之前交易的输出,同时我们必然产生一些找零。我们将产生的找零放回1hvz…的地址之中,即将找零放回到原先产生比特币的地址
之中。最后,我们必须为这次交易支出一些费用——我们将0.5mBTC作
为交易费,最终再存入24.5mBTC的找零。新的输出(25mBTC+
24.5mBTC=49.5mBTC)和输入(50 mBTC)之间的差额就是奖励给矿
工的交易费。
我们用 createrawtransaction 命令去建立一笔交易。我们将交易的收入(50
已确认未支出的mBTC)和两笔交易的输出(送往新地址的比特币和从
原先账户找回的零钱)作为 createrawtransaction 的参数。
bitcoin-cli createrawtransaction '[{txid :
9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3, vout : 0}]'
'{1LnfTndy3qzXGN19Jwscj1T8LR3MVe3JDb: 0.025,1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL: 0.0245}'
0100000001e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862aecf53ebd69f9a89c0000000000ffffffff02a0252600000000001976a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac50622500000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac00000000
createrawtransaction 命令产生了一个原始十六进制字符串,其中编码了这
笔交易的诸多细节。我们首先要通过 decoderawtransaction 命令来解码这个
字符串,以确认所有的细节准确无误:
bitcoin-cli decoderawtransaction
0100000001e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862aecf53ebd69f9a89c0000000000ffffffff02a0252600000000001976a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac50622500000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac00000000
{
txid : 0793299cb26246a8d24e468ec285a9520a1c30fcb5b6125a102e3fc05d4f3cba,version : 1,locktime : 0,vin : [
{
txid :9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3,vout : 0,scriptSig : {
asm : ,hex :
},sequence : 4294967295
}
],vout : [
{
value : 0.02500000,n : 0,scriptPubKey : {
asm : OP_DUP OP_HASH160
d90d36e98f62968d2bc9bbd68107564a156a9bcf OP_EQUALVERIFY OP_CHECKSIG,hex : 76a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac,reqSigs : 1,type : pubkeyhash,addresses : [
1LnfTndy3qzXGN19Jwscj1T8LR3MVe3JDb
]
}
},{
value : 0.02450000,n : 1,scriptPubKey : {
asm : OP_DUP OP_HASH160
07bdb518fa2e6089fd810235cf1100c9c13d1fd2 OP_EQUALVERIFY OP_CHECKSIG,hex : 76a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac,reqSigs : 1, type : pubkeyhash,addresses : [
1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL
]
}
}
]
}
结果无误!我们的交易“消耗了”从我们已确认的交易中未花费的输出,然后将它变成两笔输出,一个是走向了新地址的25mBTC,另一个是从
原来地址返回的24.5mBTC零钱。这之间0.5mBTC的差额作为交易费,以奖励挖出包含我们这笔交易区块的矿工。
你有可能注意到,交易中包含一个空的条目 scriptSig ,因为我们并没有
给它签名。如果没有签名,那么交易是没有意义的;同时我们也不能证
明我们拥有未花费的输出的来源地址的所有权。通过签名,我们移除了
输出上的障碍同时证明了我们的输出可靠。我们使用 signrawtransaction 命
令去签名交易。它需要原始十六进制的字符串作为参数:
一个加密的钱包在签名之前必须解密,因为签名需要利用钱包中的
秘钥。
bitcoin-cli walletpassphrase foo 360 bitcoin-cli signrawtransaction 0100000001e34ac1e2baac09c366fce1c2245536bda8?
f7db0f6685862aecf53ebd69f9a89c0000000000ffffffff02a0252600000000001976a914d90?
d36e98f62968d2bc9bbd68107564a156a9bcf88ac50622500000000001976a91407bdb518fa2e?
6089fd810235cf1100c9c13d1fd288ac00000000
{
hex :
0100000001e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862aecf53ebd69f9a89c000000006a47304402203e8a16522da80cef66bacfbc0c800c6d52c4a26d1d86a54e0a1b76d661f020c9022010397f00149f2a8fb2bc5bca52f2d7a7f87e3897a273ef54b277e4af52051a06012103c9700559f690c4a9182faa8bed88ad8a0c563777ac1d3f00fd44ea6c71dc5127ffffffff02a0252600000000001976a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac50622500000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac00000000,complete : true
}
输入 signrawtransaction 命令后,得到另一串十六进制的原始加密交易。我
们要对它进行解密,然后去查看发生的变化,请输入 decoderawtransaction
命令:
bitcoin-cli
decoderawtransaction0100000001e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862aecf53ebd69f9a89c000000006a47304402203e8a16522da80cef66bacfbc0c800c6d52c4a26d1d86a54e0a1b76d661f020c9022010397f00149f2a8fb2bc5bca52f2d7a7f87e3897a273ef54b277e4af52051a06012103c9700559f690c4a9182faa8bed88ad8a0c563777ac1d3f00fd44ea6c71dc5127ffffffff02a0252600000000001976a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac50622500000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac00000000
{
txid : ae74538baa914f3799081ba78429d5d84f36a0127438e9f721dff584ac17b346,version : 1,locktime : 0,vin : [
{
txid :
9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3,vout : 0,scriptSig : {
asm :
304402203e8a16522da80cef66bacfbc0c800c6d52c4a26d1d86a54e0a1b76d661f020c9022010397f00149f2a8fb2bc5bca52f2d7a7f87e3897a273ef54b277e4af52051a0601
03c9700559f690c4a9182faa8bed88ad8a0c563777ac1d3f00fd44ea6c71dc5127, hex :
47304402203e8a16522da80cef66bacfbc0c800c6d52c4a26d1d86a54e0a1b76d661f020c9022010397f00149f2a8fb2bc5bca52f2d7a7f87e3897a273ef54b277e4af52051a06012103c9700559f690c4a9182faa8bed88ad8a0c563777ac1d3f00fd44ea6c71dc5127
},sequence : 4294967295
}
],vout : [
{
value : 0.02500000,n : 0,scriptPubKey : {
asm : OP_DUP OP_HASH160
d90d36e98f62968d2bc9bbd68107564a156a9bcf OP_EQUALVERIFY OP_CHECKSIG,hex : 76a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac,reqSigs : 1,type : pubkeyhash,addresses : [
1LnfTndy3qzXGN19Jwscj1T8LR3MVe3JDb
]
}
},{
value : 0.02450000,n : 1,scriptPubKey : {
asm : OP_DUP OP_HASH160
07bdb518fa2e6089fd810235cf1100c9c13d1fd2 OP_EQUALVERIFY OP_CHECKSIG,hex : 76a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac,reqSigs : 1,type : pubkeyhash,addresses : [
1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL ]
}
}
]
}
现在,交易中的收入包含了 scritSig ,一串证明钱包地址 1hvz… 所有权的
数字签名,同时移除了支出上的障碍,然后我们可以对钱包中的钱进行
消费。签名可以让这笔交易被比特币交易网络中的任何节点验证,使他
们变得可靠。
现在,该是提交新交易到比特币网络的时候了。我们使用由原始十六进
制 signrawtransaction 命令生成的 sendrawtransaction 命令。以下就是和刚才解
码时类似的字符串:
bitcoin-cli
sendrawtransaction0100000001e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862aecf53ebd69f9a89c000000006a47304402203e8a16522da80cef66bacfbc0c800c6d52c4a26d1d86a54e0a1b76d661f020c9022010397f00149f2a8fb2bc5bca52f2d7a7f87e3897a273ef54b277e4af52051a06012103c9700559f690c4a9182faa8bed88ad8a0c563777ac1d3f00fd44ea6c71dc5127ffffffff02a0252600000000001976a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac50622500000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac00000000ae74538baa914f3799081ba78429d5d84f36a0127438e9f721dff584ac17b346
当使用 sendrawtransaction 命令发布交易到比特币网络时,它会返回交易的
哈希值。我们现在可以通过 gettransaction 命令查询交易ID:
bitcoin-cli gettransaction
ae74538baa914f3799081ba78429d5d84f36a0127438e9f721dff584ac17b346
{ amount : 0.00000000,fee : -0.00050000,confirmations : 0,txid : ae74538baa914f3799081ba78429d5d84f36a0127438e9f721dff584ac17b346,time : 1392666702,timereceived : 1392666702,details : [
{
account : ,address : 1LnfTndy3qzXGN19Jwscj1T8LR3MVe3JDb,category : send,amount : -0.02500000,fee : -0.00050000
},{
account : ,address : 1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL,category : send,amount : -0.02450000,fee : -0.00050000
},{
account : ,address : 1LnfTndy3qzXGN19Jwscj1T8LR3MVe3JDb,category : receive,amount : 0.02500000
},{
account : ,address : 1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL,category : receive,amount : 0.02450000
} ]
}
和以前一样,我们同样可以通过使用 getrawtransaction 和 decodetransaction 命
令来检查交易中的细节。这些命令会得到一个在发送到比特币网络之前
进行编码和解码并且十分精准的原始十六进制字符串。
3.3 其他替代客户端、资料库、工具包
除了参考客户端(bitcoind),还可以使用其他的客户端和资料库去连
接比特币网络和数据结构。这些工具都由一系列的编程语言执行,用他
们各自的语言为比特币程序提供原生的交互。
其他的执行方式包括:
libbitcoin和sx tools
一款C++,通过命令行完成的全节点多线程客户端与程序库
bitcoinj
一款全节点java客户端和程序库
btcd
一款全节点GO 语言的比特币客户端
Bits of Proof(BOP)
一款Java企业级平台的比特币工具
picocoin 一款轻量级比特币执行客户端
pybitcointools
一款Python语言的比特币程序库
pycoin
另一款Python语言的比特币程序库
在其他的编程语言中,还有许多形式的比特币(程序)库。开发者也尽
其所能,一直在尽力创造新的比特币工具。
3.3.1 Libbitcoin和sx Tools
Libbitcoin程序是一款基于C++层面,可扩展、多线程、模块化的执行工
具。它可以支持全节点客户端和一款叫做sx的命令行工具,并可以提供
我们本章所讨论的比特币命令相同的功能。Sx工具同时提供了管理和操
作工具,是bitcoind所不能提供的,包括type-2型确定性密钥和密码助记
工具。
安装sx
若要安装sx工具以及相关libbitcoin库,请在Linux操作系统中下载并安装
在线安装包:
wget http:sx.dyne.orginstall-sx.sh
sudo bash .install-sx.sh
现在你应当已经安装好了sx工具。输入没有参数的sx命令来显示帮助文档,帮助文档列出了所有可用的命令(详见附录4)。
sx工具提供了许多实用的编码与解码地址的命令,可以从不同的编
码方式转化,也可以转化成不同的方式。通过他们,可以探索更多
的编码方式,比如Base58,Base58Check,hex,等等。
3.3.2 pycoin
pycoin 最初由Richard Kiss创立并维护,是一款基于Python库,并可以支
持比特币密钥的操作和交易的客户端,甚至可以支持编译语言从而处理
非标准交易。
Pycoin库同时支持Python2(2.7x)与Python3,以及一些便于使用的命令
行工具,比如ku和tx。如果在Python3的虚拟环境下安装 pycoin0.42,请
输入以下命令:
python3 -m venv tmppycoin
. tmppycoinbinactivate
pip install pycoin==0.42
Downloadingunpacking pycoin==0.42
Downloading pycoin-0.42.tar.gz (66kB): 66kB downloaded
Running setup.py (path:tmppycoinbuildpycoinsetup.py) egg_info for pack-age
pycoin
Installing collected packages: pycoin
Running setup.py install for pycoin
Installing tx script to tmppycoinbin
Installing cache_tx script to tmppycoinbin Installing bu script to tmppycoinbin
Installing fetch_unspent script to tmppycoinbin ......
1. 介绍
2. 前言
3. 快速术语检索
4. 第1章 介绍
5. 第2章 比特币的原理
6. 第3章 比特币客户端
7. 第4章 密钥、地址、钱包
8. 第5章 交易
9. 第6章 比特币网络
10. 第7章 区块链
11. 第8章 挖矿与共识
12. 第9章 竞争币、竞争块链和应用程序
13. 第10章 比特币安全
14. 附录1
15. 附录2
16. 附录3
17. 附录4
18. 贡献与勘误
精通比特币
作者:Andreas M Antonopoulos
Andreas M. Antonopoulos 是一位著名的技术专家和连续创业企业家,比
特币界最著名和倍受尊敬的人物之一。身为一名迷人的公共演说家、教
师和作家,他善于把复杂的问题变得简单而易于理解。
Andreas M. Antonopoulos 的成长和互联网密不可分,青少年时期,他便
在自己希腊的家中创办了他的首家公司——一个早期电子信息服务系统
和原始的互联网服务提供商。他取得了伦敦大学学院的电脑科学学位、数据通信学位以及分布式系统学位,该学校最近跻身于全球大学排名前
十。移居美国后,Andreas M. Antonopoulos 和别人合办了一家成功的技术研究公司,管理公司的他,在网络、安全、数据中心和云计算方面,为许多世界五百强公司的首席执行者提供建议。他撰写了200多篇关于
安全、云计算和数据中心的文章,已经在世界范围内被印制出版,并在
多家报刊发表。此外,他还持有两项网络和安全领域的专利权。
1990年,Andreas M. Antonopoulos 开始在私人、专业和学术等诸多场合
讲授IT话题。从五名企业高管的会议室,到千人参与的大型会议,他不
断磨练着自己的演讲水平。超过400次的锻炼,不仅使他成为了为人津
津乐道的教授,还铸就了他世界级演讲大师的美名。2014年,第一所授
予数字货币学士学位的尼科西亚大学邀请他来校任教。上任后,他与别
人合作开设了这门课程。他还参与讲授了数字货币导论,后者成了为尼
科西亚大学的一门大型网络公开课(MOOC)。
作为一名比特币企业家,Andreas M. Antonopoulos 已成立了不少比特币
企业,并推出了一些社区开源项目。他担任好几家比特币和加密货币公
司的顾问。他既是一名出版作家,发表了大量关于比特币的文章和博
文;也是一档流行博客“Let’s Talk Bitcoin”的固定主持人;还是在全球
各地的技术安全会议上演说的常客。
译者:
薄荷凉幼;陈萌琦;陈姝吉;程鹏;程西园;达文西;吉鸿帆;李
丹;李润熙;李凌豪;李昕阳;刘畅;吕新浩;马峰;牛东晓;秦
彤;邱蒙;戎如香;史磊;汪海波;王宏钢;辛颖;杨兵;尹文
东;余龙;张林;张琦张大嫂;张亚超;张泽铭;赵冬帅;赵余;
YANG YANG
简介
想要加入一场颠覆金融世界的技术革命吗?《精通比特币》会为你参与
这个货币网络提供必备知识,引导你进入看似复杂的比特币世界。无论
你是正在构建下一个杀手级应用、投资创业,还是单纯对技术好奇,这
本实用的书都是你不可或缺的阅读材料。
比特币,作为第一个成功的去中心化数字货币,尽管还处在起步阶段,却已经催生了数十亿美元的全球性经济体。它对任何具备相应知识和参与热情的人都是开放的。《精通比特币》会为您提供必要的知识,但请
各位读者自备热情。
本书包括:
针对非技术用户、投资者以及企业高管,概括性地介绍比特币
针对开发人员、工程师以及软件系统架构师,介绍比特币和加密货
币的技术基础
详细介绍比特币去中心化网络、点对点体系结构、交易生命周期以
及安全原则等细节的
比特币和区块链的发明的衍生物,包括替代链、货币以及应用程序
通过用户故事、简练的类比、示例以及代码段来阐释的关键技术概
念
Andreas M. Antonopoulos 是比特币行业最为知名和受人尊敬的技术专
家、连续创业家,现担任多家技术创业公司的顾问。他同时还是一名出
色的演说家,教师以及作家,经常在世界各地的会议和团体活动中发表
演说,用通俗易懂的讲解把复杂的学科普及给广泛听众。
“论及比特币,有人问我它到底是怎样工作的?现在我有了一个极
好的答案——《精通比特币》这本书会让每位读者深刻理解比特币
的工作原理,还会帮助读者为写出下一代神奇加密货币的应用程序
做好充分准备。”
——Gavin Andresen,比特币基金会,首席科学家
“Andreas的书将帮助你投身于金融世界的软件革命。”
——Naval Ravikant,AngelList联合创始人
捐赠
在本书翻译过程中, 火币 、 OKCoin 、 云币 各捐赠了2个比特币,捐赠地址为: 18AN9XojYq5EU5x8p6pgdYk3RKo6zu9xzy ;这些比特币当前
并没有发放给参与翻译的义工。计划大体如下:
1. 此比特币地址继续接受捐赠:
18AN9XojYq5EU5x8p6pgdYk3RKo6zu9xzy
2. 捐赠的比特币将主要用于本书翻译的纠错与修订(具体奖励措施尚
未确定);如果您发现了书中的错误,请点击 此处 填写《勘误收
集表》。
3. 一年之后(即,2016 年 6 月 1 日),剩余的比特币将平均发放给
译者们,留作纪念。
4. 捐赠名单讲在此页面公布。如果您愿意,捐赠比特币时,请使用
blockchain.info 或者 bitfoo.com ,在 note 中标明您的身份,以作纪
念。
前言
关于本书
我第一次偶遇比特币是在2011年年中,当时的反应大概是“哈!书呆子
的钱嘛!”因为没能领会它的重要性,我忽视它长达六个月之久,而让
我稍感宽慰的是,许多我认识的一些聪明绝顶人也是这种反应。在一次
邮件列表讨论时,我再次接触到了比特币,于是决定阅读中本聪
(Satoshi Nakamoto)写的白皮书,研究比特币的权威解释,看看到底
是怎么一回事。我仍记得刚刚读完那九页内容的那一刻,那时我才终于
明白了:比特币不单单是一种数字货币,还是一种给货币及其他很多东
西提供基础的信任网络。对“不是货币,而是去中心化信任网络”的领
悟,让我开启了为期四个月的比特币沉醉之旅。我如饥似渴地寻找任何
关于比特币的点滴信息,变得越来越着迷,每天都花上12个小时以上紧
盯屏幕,竭尽所能地不断阅读、写作、学习和编程。从这段着魔的状态
中走出来的时候,我的体重由于前期没有规律饮食轻了20多磅,同时我
也坚定了要全心投入比特币事业的决心。
随后的两年,我创立了一系列开发比特币相关服务和产品的公司,之后
我决定写我的第一本书。书的主题就是激发了我疯狂的创造力并让我冥
思苦想的比特币,它是我在继互联网之后遇到的最为振奋人心的技术。
现在是时候跟更广大的读者分享我对这项惊人技术的热情了。阅读对象
本书主要面向程序员。如果你能使用一门编程语言,本书将会告诉你加
密货币的原理、使用方法,以及如何开发与之相关的软件。对希望理解
比特币及加密货币内在工作机制的非程序员读者们,本书前几章作为对
比特币的深入介绍依然适用。
封面故事
在群居生物物种中,切叶蚁表现出了高度复杂行为的物种特征。但是,群落中的每一只蚂蚁个体仅仅遵循一些社会互动和化学气味(即信息
素)交换的简单规则。维基百科提到:“切叶蚁形成地球上仅次于人类
的最为庞大且复杂的动物社会。”实际上,切叶蚁不吃叶子,而是使用
叶子制造一种真菌来充当蚁群主要食物来源。意识到了吗?它们在耕
作!
虽然切叶蚁形成的是阶级社会,且依靠蚁后繁衍后代,但是在蚁群中不
存在中央集权体制或领导人。通过切叶蚁我们可以看到,群落中数百万
成员所展现的高度智能且复杂的行为是社会网络中的个体互动这一性质
的凸显。
大自然向我们证明,去中心化体制具有弹性并能创造出意想不到的复杂
性和难以想象的精妙,而不需要中央集权体制、等级制度或复杂的组织
结构。
比特币网络正是这样一个高度复杂的去中心化的可信网络,能够支撑无
数财务流程。然而,比特币网络的每一个节点都遵循着一些简单的数学
准则。节点间的相互作用促成引起了组织的复杂行为,而并不是任何某
个单一节点自身具有复杂性和可信性。就像蚁群一样,比特币的弹性网
络是一个由众多遵循简单准则的简单节点所组成的弹性网络,这些简单
的节点准则聚合在一起可以完成惊人的事情,而不需要任何中枢协调。
本书惯例
本书中的印刷惯例如下: 此图标表示小贴士,建议,或一般性注解。
此图标表示预警或警告。
代码示例
本书示例是基于类Unix操作系统(例如Linux或Mac OS X)的命令行,用Python,C++编程语言来说明的。全部代码段均可在 Github主代码库
中的code子目录获得。读者可以通过GitHub创建自己的代码分支,尝试
书中示例,或者提交代码更正。
所有代码段在大多数操作系统上都可以通过最小化安装对应语言的编译
器和解释器来重现。在必要的地方,本书还提供了基本的安装指令以及
每步指令输出的结果。
为了便于打印,本书重新格式化了部分代码段和代码输出。在所有此类
例子中,每行代码以反斜杠(\)字符和换行符分开。当你需要尝试这
些示例时,请删除这两个字符的,把被分隔的两行重连起来,就可以看
到与例子中一致的结果了。
本书所有代码段尽可能地采用实值计算,因此你可以通过重复构建本书
提供的代码示例,用你自己写的代码计算出相同的结果。譬如,书中出
现的私钥和对应的公钥及地址也都是真实存在的。示例中的所有交易、区块和区块链均被记录在实际的比特币区块链中,是公共账目的一部
分,因而你可以在任何比特币系统中检查它们。
使用代码示例
本书的目的是帮助你完成工作。总的来说,你可以在你的程序和文档中
使用本书的代码示例。除非你要复制代码的关键部分,否则不需要联系我们获得许可。例如,使用程序中的几段代码,或者引用本书及代码来
回答问题是不需要获准的;而售卖或分发包含O’Reilly书中代码示例的
光盘,或者将大量书中代码合并于你的产品或文档则必须获得我们的许
可。
我们鼓励、但不强制要求您在引用本书时表明出处。书目引用格式通常
包括书名、作者、出版商、ISBN。例如:“精通比特币,Andreas?M?Antonopoulos (O'Reilly)。版权2015 Andreas?M?Antonopoulos,978-1-449-37404-4.”
本书某些版本提供了开源许可,如 CC-BY-NC ,这种情况下,开源许可
条款适用。
如果你觉得你对本书代码示例的使用超出了合理范围或上述许可,请随
时与我们联系:permissions@oreilly.com.
快速术语检索
“常用术语表”中包含了很多常见的比特币相关术语。这些术语在本书中
也多次出现。建议您给本章节做上标记,阅读时可作快速索引。
地址
比特币地址(例如:1DSrfJdB2AnWaFNgSbv3MZC2m74996JafV)由一
串字符和数字组成,以阿拉伯数字“1”开头。就像别人向你的email地址
发送电子邮件一样,他可以通过你的比特币地址向你发送比特币。
BIP
比特币改进提议 (Bitcoin Improvement Proposals 的缩写),指比特币
社区成员所提交的一系列改进比特币的提议。例如,BIP0021是一项改
进比特币统一资源标识符(URI)计划的提议。
比特币
“比特币”既可以指这种虚拟货币单位,也指比特币网络或者网络节点使
用的比特币软件。区块
一个区块就是若干交易数据的集合,它会被标记上时间戳和之前一个区
块的独特标记。区块头经过哈希运算后会生成一份工作量证明,从而验
证区块中的交易。有效的区块经过全网络的共识后会被追加到主区块链
中。
区块链
区块链是一串通过验证的区块,当中的每一个区块都与上一个相连,一
直连到创世区块。
确认
当一项交易被区块收录时,我们可以说它有一次确认。矿工们在此区块
之后每再产生一个区块,此项交易的确认数就再加一。当确认数达到六
及以上时,通常认为这笔交易比较安全并难以逆转。
难度
整个网络会通过调整“难度”这个变量来控制生成工作量证明所需要的计
算力。
难度目标
使整个网络的计算力大致每10分钟产生一个区块所需要的难度数值即为
难度目标。
难度调整
整个网络每产生2,106个区块后会根据之前2,106个区块的算力进行难度
调整。
矿工费
交易的发起者通常会向网络缴纳一笔矿工费,用以处理这笔交易。大多
数的交易需要0.5毫比特币的矿工费。哈希
二进制数据的一种数字指纹。
创世区块
创世区块指区块链上的第一个区块,用来初始化相应的加密货币。
矿工
矿工指通过不断重复哈希运算来产生工作量证明的各网络节点。
网络
比特币网络是一个由若干节点组成的用以广播交易信息和数据区块的
P2P网络。
工作量证明
工作量证明指通过有效计算得到的一小块数据。具体到比特币,矿工必
须要在满足全网目标难度的情况下求解SHA256算法。
奖励
每一个新区块中都有一定量新创造的比特币用来奖励算出工作量证明的
矿工。现阶段每一区块有25比特币的奖励。
私钥
用来解锁对应(钱包)地址的一串字符,例如
5J76sF8L5jTtzE96r66Sf8cka9y44wdpJjMwCxR3tzLh3ibVPxh。
交易
简单地说,交易指把比特币从一个地址转到另一个地址。更准确地说,一笔“交易”指一个经过签名运算的,表达价值转移的数据结构。每一
笔“交易”都经过比特币网络传输,由矿工节点收集并封包至区块中,永
久保存在区块链某处。钱包
钱包指保存比特币地址和私钥的软件,可以用它来接受、发送、储存你
的比特币。
第1章 介绍
1.1 什么是比特币?
比特币是一些概念与技术的集合,这些概念与技术构成了数字货币生态
系统的基础。人们称之为“比特币”的货币单位用于存储,也用于在比特
币网络参与者之间传输价值。比特币用户之间通过比特币协议进行通讯
主要是在互联网上,当然也可以使用其他传输网络进行交流。比特币的
协议栈以开源软件的形式实现,这些软件可以在包括笔记本电脑、智能
手机在内的多种设备上运行,这使得比特币技术非常亲民。
用户可以通过在网络上传输比特币来实现几乎传统货币能做的全部事
情,例如买卖商品、给个人或组织汇款,或提供贷款。比特币可以在专
门的交易所里购买,出售,或者与其他币种进行兑换。从一定意义上来
说,由于具有快捷、安全以及无国界的特性,比特币正是互联网货币的
完美形态。
不同于传统的货币,比特币是完全虚拟的。没有实物的货币,甚至就本
质而言,也没有数字货币。比特币隐匿于发送者和接收者间价值传递的
交易中。比特币用户拥有能够使他们在比特币网络中证明自己交易权的
密钥,解密后可使用比特币,也可以将它购买、,出售,以及与其他币
种进行兑换。由于比特币快捷、安全以及无国界的特性,在某种意义
上,比特币就是互联网货币的完美形态。
用传统货币能做到的事情,用户在网络上利用比特币都可以做到,包括
发送给新的接收者。这些密钥通常存储在每个用户的计算机的数字钱包
里。每一笔交易都需用密钥解密,这是使用比特币的唯一先决条件,它
完完全全掌握在每个用户的手中。
比特币是一个分布式的点对点网络系统。因此,没有“中央”服务器,也
没有中央控制点。比特币是通过一个名为“挖矿”的过程产生的,挖矿需要在处理比特币交易的同时参与竞赛来解决一个数学问题。在比特币网
络中的任何参与者(比如,任何人使用一个设备来运行完整的比特币协
议栈)都是潜在的矿工,用他们电脑算力来验证和记录交易。每隔10分
钟,有人能够验证过去10分钟发生的交易,作为回报,将会获得崭新的
比特币。从本质上讲,比特币挖矿分散了中央银行的货币发行,也分散
了其结算功能,并且能够在全球竞争中取代任何一家中央银行。
比特币协议包括了内置算法,该算法可以调节网络中的挖矿功能。矿工
必须完成的任务——在比特币网络中成功地记录一个区块交易——的难
度是在动态调整的,因此,无论何时有多少矿工(多少CPU)在挖矿,通常每10分钟就会有人成功。
新比特币开采出的每四年,这项协议也会减半开采速率,并限制比特币
的开采总量为一个固定值:2,100万枚。其结果是,在流通中的比特币
数量很容易根据预测曲线得出,将会在2140年达到2,100万枚。由于比
特币的发行率是递减的,从长期来看,比特币是一种通货紧缩的货币。
此外,通过超出预期发行率来“印刷”新比特币,造成通货膨胀是不可实
现的。
实质上,比特币本身也是协议,是一种网络,是一种分布式计算革新的
代名词。比特币通货仅是这种创新的首次应用。作为一个开发者,我看
到比特币类似于互联网货币,一个通过分布式计算来传播价值和保障数
字资产所有权的网络。比起初识比特币,这里将知无不言。
在本章中,我们将会从一些主要概念和术语解释开始,获取必备软件,使用比特币进行简单的交易。在接下来的章节里,我们将开始揭开使比
特币成为可能的技术面纱,解释比特币网络和比特币协议的内部运行机
制。
比特币之前的数字货币
切实可行的数字货币的出现是与密码学发展息息相关的。基本的挑
战在于,当一个人考虑到用比特来代表可以兑换商品和服务的价值
时,接受数字货币也就不足为奇。任何接受数字货币的人都面临的
两个基本问题是:
1. 我能相信这钱是真实可信的,而不是伪造的吗?
2. 我能确定没人说这笔钱是他们的,而不是我的吗?(又名“双重支付”问题)
纸币的发行机构不断的利用日益复杂的纸张和打印技术来遏制造假
问题。实物货币很容易解决双重支付问题,因为同一张纸币不可能
会同时出现在两个不同的地方。当然,传统货币也经常数字化储存
和数字化传输。在这些情况下,假币和双重支付问题是被中央权威
机构的处理方式是清除所有的电子交易记录,该中央权威在流通中
持有一种全球通货观。对于数字货币来说,不能有效利用秘制油墨
印刷技术或条形全息图,密码学为用户所主张的合法性价值提供了
信任的基础。具体地来说,加密数字签名能够使一个用户签署一项
能够提供其资产所有权证明的数字资产或数字交易。采用适当的结
构,数字签名也可以用于解决双重支付的问题。
在20世纪80年代后期,当密码学开始越来越广泛地使用并被理解
时,许多研究人员开始尝试使用密码学来建立数字通货。这些早期
的数字通货项目发行的数字货币,通常倚靠一种国家通货或像黄金
一样的贵金属。
虽然这些早期的数字通货的运行了,他们却是中心化的,因此,他
们很容易遭受到政府和黑客的攻击。早期的数字通货使用了一个中
央结算所来处理所有的定期交易,就像一个传统的银行系统。不幸
的是,在大多数情况下,这些新兴的数字货币成为了政府担忧的目
标,最终从法律程序上消失了。另一些则是在发行这些数字货币的
母公司突然违约时颓然失败了。为了坚定的抵制对手的介入,无论
这些对手是合法的政府或是犯罪分子,去中心化的数字货币需要的
是避免单节点攻击。比特币正是这样的系统,设计完全去中心化,不被任何中央政权或中央点控制,这样的货币系统是不会遭受攻
击,也不会变得腐败。
比特币代表了数十年的密码学和分布式系统的巅峰之作,这是一个
独特而强大的组合,汇集了四个关键的创新点。比特币由这些构
成:
一个去中心化的点对点网络(比特币协议)
一个公共的交易账簿(区块链)
一个去中心化的数学的和确定性的货币发行(分布式挖矿) ? 一个去中心化的交易验证系统(交易脚本)
1.2 比特币发展史
2008年,一位化名为中本聪的人,在一篇名为《比特币:一个点对点的
电子现金系统》的论文中首先提出了比特币。中本聪结合以前的多个数
字货币发明,如B-money和HashCash,创建了一个完全去中心化的电子
现金系统,不依赖于通货保障或是结算交易验证保障的中央权威。关键
的创新是利用分布式计算系统(称为“工作量证明”算法)每隔10分钟进
行一次的全网“选拔”,能够使去中心化的网络同步交易记录。这个能优
雅的解决双重支付问题,即一个单一的货币单位可以使用两次。此前,双重支付问题是数字货币的一个弱点,并通过一个中央结算机构清除所
有交易来处理。
根据中本聪的一篇涉及比特币网络运行的发表论文,比特币网络自从被
许多其他的程序员修订之后,于2009年启动。分布式计算,为比特币提
供了成倍增长的安全性和韧性,现在超过了世界顶级超级电脑的联合处
理能力。根据比特币兑美元汇率,比特币的总市场估值为50至100亿美
元。目前从全网来看,比特币处理的最大交易额为1.5亿美元,这笔交
易及时处理和转账,没有缴纳任何手续费。
中本聪在2011年4月退出公众视野,将比特币代码开发与网络建设的重
任留给了欣欣向荣的社区成员。而“中本聪”究竟是谁,时至今日仍然是
未解之谜。然而,比特币系统的运行,既不依赖于中本聪,也不依赖于
其他任何人——比特币系统依赖于完全透明的数学原理。这项发明本身
就是开创性的,它已经蔓延到了分布式计算、经济学、计量经济学领
域。
一个分布式计算问题的解决方案
中本聪的此项发明,对“拜占庭将军”问题也是一个可行的解决方
案,这是一个在分布式计算中未曾解决的问题。简单来说,这个问
题包括了试图通过在一个不可靠、具有潜在威胁的网络中,通过信
息交流来达成一个行动协议共识。中本聪的解决方案是使用工作量
证明的概念在没有中央信任机构下达成共识,这代表了分布式计算
的科学突破,并已经超越了货币广泛的适用性。它可以用来达成去中心化的网络共识来公正选举、彩票、资产登记,以及数字化公证
等等。
1.3 比特币的应用、用户和他们的故事
比特币是一项技术,但它所传递的货币从实质上来说,是一种人与人之
间价值交换的基础语言。让我们通过他们的故事,来看看使用比特币的
人和一些最常用的通货和协议。我们将会反复用到这些贯穿本书的故
事,以此来说明现实生活中数字货币的用途,以及他们是如何通过比特
币的各种技术使之成为可能的。
北美低价零售
Alice住在北加州的旧金山湾区。她已经从她的科技迷朋友口中得知了比
特币,想要开始使用它。我们会跟进她的故事,来了解比特币,获取一
些,并在帕洛阿尔托的Bob家咖啡店用比特币购买一杯咖啡。这个故事
会从零售的消费者角度向我们介绍比特币软件,交易平台,以及基本的
交易。
北美高价零售
Carol是一位旧金山艺术画廊的主人。她出售昂贵的油画来换取比特
币。这个故事将介绍高额商品的零售商们所面临的“51%”攻击的风险。
离岸合同服务
Bob是帕洛阿尔托一家咖啡店的老板,正在建设一个新网站。他曾与一
个住在印度班加罗尔的网站开发者Gopesh签订了协议。Gopesh已同意比
特币支付。这个故事将研究使用比特币进行海外购、合约服务,以及国
际电汇。
慈善捐赠
Eugenia是菲律宾一家儿童慈善机构的董事。最近,她发现了比特币,并希望利用它来和一个全新的国内外捐助群体接洽,以此为她的慈善募
捐。她还研究如何使用比特币快速优化资金配置。这个故事将会演示用
比特币来进行跨币种跨国界的全球融资,展示慈善组织所使用的公开透明账簿。
进口出口
Mohammed是迪拜一位电子进口商。他试着用比特币来进行快捷支付,进口美国和中国的电子产品到阿联酋。这个故事将示范用比特币来支付
大型企业间实物商品的国际收支。
比特币挖矿
Jing是上海一名计算机工程专业的学生。他建了一个用来挖比特币的矿
机,使用他的专业技能来为自己创收。这个故事将审查基于比特币
的“工业”:用于确保比特币网络安全和发行新货币的特殊设备。
这些故事都是根据真实行业内的真实人物原型来的,他们正在用比特币
创造新市场,创造新产业,用比特币这个新兴事物来解决全球经济问
题。
1.4 入门
加入比特币网络并开始使用通货,所有用户需要做的就是下载应用程序
或使用在线应用程序。因为比特币是一个标准,也有许多运行比特币的
客户端软件。还有一个标准客户端,也称为中本聪客户端,这是由一个
开发团队管理的一个开源项目,源自于中本聪编写的初始客户端。
比特币客户端的三种主要形式是:
完整客户端
一个完整客户端,或称“全节点”,是存储所有比特币交易的整个交易历
史(由每一个用户完成的每一笔交易,曾经所有的每一笔)的客户端,管理用户的钱包,并可以在比特币网络上直接开始交易。这类似于一个
独立的电子邮件服务器,因为它处理着协议的各个方面,而不依赖于任
何其它的服务器或第三方服务。
轻量级客户端 一个轻量级客户端存储用户的钱包,但需要依赖第三方服务器才能进行
比特币交易,才能接入比特币网络。轻量级客户端不保存所有交易的完
整副本,因此必须信赖第三方的服务器来获取交易确认。这就类似于一
个独立的电子邮件客户端,能够通过邮箱服务器来访问一个邮箱,因为
它在网络交流中依赖于一个第三方服务器。
在线客户端
在线客户端通过网页浏览器在第三方服务器上访问和储存该用户的钱
包。这类似于在线邮件,因为它完全依赖于第三方服务器。
移动客户端
智能手机的移动客户端,例如基于Android系统,既可以作完整客
户端运行,也可作为轻量级客户端或在线客户端。一些移动客户端
是与在线客户端或桌面客户端同步的,提供跨多个设备但有一个共
同的资金源的多平台钱包。
比特币客户端的选择,取决于用户想要管理资金的数目。一个完整的客
户端将为用户提供最高级的管理和独立性。这样钱包的备份和安全责任
就转移到了用户身上。另一种选择是在线客户端,其设置和使用是最简
单的,但在线客户端的取舍还在于需衡量第三方介入的风险,因为安全
性和控制权是由用户和网页服务商所共同承担的。如果一个在线钱包服
务遭受了损失,就像已发生过的那样,用户们可能会失去所有的资金。
反过来看,如果用户的一个完整客户端没有进行适当的备份,他们可能
会因为电脑的操作失误而丢失他们的资金。
这本书的目的在于,我们将演示各种可下载的比特币客户端的使用方
法,从原版客户端(中本聪客户端)到在线钱包。一些案例将使用到原
版客户端,除了作为一个完整的客户端以外,也会公开钱包的API,网
络和交易服务。如果您计划进入比特币系统探索编程的话,将会需要原
版客户端。
1.4.1 快速入门
我们在“ 1.3 比特币的应用、用户和他们的故事 ”一节中介绍了Alice,她
并不是技术性用户,最近才从一个朋友那听说了比特币。她通过浏览比
特币官方网站bitcoin.org开始了自己的比特币之旅,在官网上,她发现了很多种可供选择的比特币客户端。她根据官网提供的建议,选择了轻
量级的Multibit客户端。
Alice通过官网bitcoin.org上提供的链接,在她的电脑里下载安装了
Multibit客户端。目前Multibit电脑客户端有WindowsWindows, Mac OS
和 Linux版本。
比特币钱包必须由一个密码或密令来保护。有许多试图破解弱密码
的潜在威胁,所以要注意谨慎设置一个不会被轻易破解的密码。密
码应使用大小写字母、数字和符号的组合,避免出现生日、球队名
字等个人信息。避免使用任何能在字典里轻易找到的词语,不管这
个词语是什么语言的。如果条件允许,可以利用密码生成器生成一
个完全随机的12位以上的密码。请记住:比特币是一种随时能被转
移到世界其他任何地方的货币。如果不加以妥善保管,会很容易被
偷走。
Alice下载并安装了Multibit客户端后,打开程序就会出现一个欢迎界
面,如图1-1所示:图1-1 Multibit比特币客户端的欢迎界面
Multibit客户端会自动为Alice生成一个钱包和一个全新的比特币地址,点击图1-2所示的请求标签即可看到。图1-2 Multibit客户端请求标签中Alice的新比特币地址
界面中最重要的是Alice的比特币地址。类似于电子邮件的地址,Alice
可以分享这个地址,这样任何人都可以通过这个地址直接将比特币发送
到的新钱包里。界面上看起来一长串的字母和数字就是地址:
1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK。
地址旁是一个二维码。这个二维码是可以被智能手机摄像头扫描到该钱
包地址的条形码,即窗口右边黑白相间的方块。通过点击比特币地址或
二维码旁边的复制按钮,Alice可以将它们分别复制到剪贴板。点击二维
码可以将其放大,便于智能手机扫描。
Alice也可以打印出这个地址二维码给别人,这样就不用打一长串字母和
数字了。
比特币地址以数字1或3开头。类似于电子邮件地址,这些地址可以分享
给其他的比特币的用户,这样他们就可以直接通过这些地址发送比特币
到你的钱包里。不同于电邮地址的是,你可以任意地创建新的比特币地
址,这些地址都能成功地将资金转到你的钱包。钱包是多个地址和解锁
资金密钥的简单集合。每笔交易你都可以使用不同的地址,这有利于提
高隐私的安全性。用户可创建地址的数量几乎不受限制。
现在Alice已经准备好开始使用她的新比特币钱包了。1.4.2 获取你的第一枚比特币
现在你还无法在银行或是外币兑换处买到比特币。截至2014年,在大多
数国家,购买比特币还是相当困难的。你可以去一些专门的通货交易
所,购买比特币或是出售比特币换取当地货币,交易所是以在线通货市
场的方式来运营。包括以下几种:
Bitstamp
一个欧洲通货市场,通过电汇方式,支持包括欧元、美元在内的多币种
交易。
Coinbase
美国比特币钱包,也是买家和卖家进行比特币交易的一个平台。
Coinbase允许用户通过ACH系统来连接美国支票账户,这样易于购买和
出售比特币。
这一类的数字加密货币交易所,在国家货币和加密货币夹缝中求生存。
因此,会受各国法规和国际法规的制约,而且往往会具体到某单个国家
或经济区,并只限于该地区的国家货币。你所选择的货币交易所,只限
于你使用的本国货币,也只能是在你国范围内合法运营的交易所。类似
于在银行开户,用此类服务来设置这些必要的账户需要花费数日或数周
的时间,因为他们需要各种形式来了解你的客户,确认交易将符合反洗
钱法。一旦你拥有了交易所的一个账户,你就可以像用代理账户购买出
售外币一样的,更快捷地购买或出售比特币了。
bitcoin charts 是提供价格索引的站点,一个包括数十家货币交易所其他
市场数据的站点,在这里你可以找到更完整的数据。
新用户有以下四种方法来获取比特币:
找个有比特币的朋友,直接向他购买一些。很多比特币用户都是这
样开始的。
利用 localbitcoins.com 这样的分类服务网站来寻找你所在地区的卖
家,使用现金进行面对面的线下交易。 ? 出售某种产品或服务来换取比特币。如果你是个程序员,可以出售
你的编程技能。
使用你所在地区的比特币ATM机。利用CoinDesk里的 在线地图 来找
到你附近的比特币取款机。
Alice是经朋友介绍认识比特币的,所以在等待加州通货市场上的账号被
验证和激活的同时,她轻而易举的就获取了她的第一枚比特币。
1.4.3 发送和接收比特币
Alice已经创建好她的比特币钱包,准备接收资金了。她的钱包程序随机
生成了一个私钥(关于私钥的详细介绍见“ 4.1.3 私钥 “)和对应的比特
币地址。这时,她的比特币地址还未在全网公布,也未在在任何比特币
系统中“登记”。她的比特币地址只是一串数字,对应一个她可以掌控的
资金私钥。在该地址和账户之间还没有任何交易产生,也没有任何关
联。直到这个地址接收到在比特币账簿(区块链)中公布过的一笔交易
时,才会成为众多可能“有效”的比特币地址之一。一旦该地址接受了一
笔交易,就会变成全网所知的地址之一,Alice就可以在公开账簿中查询
余额了。
Alice和Joe约在当地的一个饭店里会面,正是Joe把比特币介绍给了Alice
的。这样Alice就可以用美金向Joe换取一些比特币,让Joe发送一些比特
币到她的账户里。她带来了打印版的比特币地址和钱包二维码。从安全
角度来说,比特币地址没什么特别机密的。她可以在任何地方公布自己
的地址,而不用担心帐户安全。
Alice只想兑换10美元的比特币,免得在这项新技术上冒险花太多钱。所
以她给了Joe 10美元和她地址的打印件,这样Joe就可以给她发送等值的
比特币了。
接下来Joe需要弄清楚汇率,以便于发送给Alice相应数额的比特币。有
很多应用和网站都会提供当前的市场汇率,下列是一些最流行的:
Bitcoin Charts
Bitcoin Chart 是一个市场数据服务网站,显示了全球众多交易所的比特
币市场汇率,以当地不同的汇率来进行结算。Bitcoin Average
Bitcoin Average是一个提供每个币种的交易量加权平均价格的简单视图
网站。
ZeroBlock
ZeroBlock是一个免费的安卓和iOS应用程序,可以显示不同交易所的比
特币价格。(见图1-3)
Bitcoin Wisdom
另一个市场数据索引服务站。图1-3 ZeroBlock,一款基于安卓和iOS系统的比特币市场汇率应用
程序
Joe使用上述的程序或网站中的其中一个,查到比特币的价格约为每个
比特币价值100美元左右。按照这个汇率,Alice给了他10美元,作为交
换,他应当给Alice 0.1个比特币,即10,000,000聪。
Joe查到一个市场价后,打开自己的手机钱包应用,选择“发送”比特
币。图1-4 Blockchain 手机钱包的比特币发送界面
例如,如果是在苹果手机上使用Blockchain手机钱包,他会看见屏幕上
要求输入:
对方的收款地址
需要发送的比特币数量
在比特币地址的输入栏,有一个看起来像二维码的小图标。Joe可以用
他的智能手机摄像头扫描条形码,而不用再输入Alice的比特币地址
(1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK)了,不用再打出这个又长
又繁琐的地址。Joe轻击二维码图标,启动智能手机的摄像头,然后扫
描Alice带来的二维码打印版。手机钱包程序会填好比特币地址,Joe可
以通过比较这个地址和Alice打印的地址中的几个数字,来确认已正确地
扫描。
接着Joe输入了交易的比特币金额,0.1比特币。他仔细检查,确保已经
输入了正确的金额,因为他马上要发送这些钱了,任何一点点的小失误
都会导致发送到错误的地址。最后,他按下了发送键来完成这笔交易。
Joe的手机钱包会创建一笔交易,将Joe的钱包里的0.10比特币发送到
Alice提供的地址,利用Joe的私钥来签名这笔交易。这就公告了比特币
全网,Joe已经授权允许从他的一个地址转账比特币到Alice的新地址。
由于交易是通过P2P网络协议传输,它会迅速在整个比特币网络传播。
不到一秒钟,网络中大多数连接良好的节点都会收到该交易信息,并首
次公布Alice的地址。
如果Alice手边有智能手机或笔记本电脑,她也能看到这笔交易。比特币
账簿—一个不断膨胀的文件记录,记载了每一笔曾发生过的比特币交易
—是公开的,意味着她可以查看所有曾经使用该地址的记录,可以查看
是否有人朝这个账户发送了比特币。她只要在blockchain.info网站的搜
索框中,输入她自己的地址,就可以轻而易举的知晓了。网页会显示出
该地址所有的交易记录 。Joe点击发送后,0.10比特币会很快转到她的
钱包里,如果Alice正看这个页面,她就会发现网页更新了这笔新交易信
息。确认
起初,Alice的地址会显示Joe发出这笔的交易为“未确认”,这意味
着这笔交易已经被广播到网络,但是尚未列入比特币交易记录账
簿,即区块链中。总的来说,交易必须由一个矿工“开采”,交易是
包括在区块中的。当新区块创建时,大约十分钟左右,该区域内的
交易就会被全网接受为“已确认”,区块中的比特币也都能使用。交
易可以立即被其他人看到,但只有当其被包含在新开采的区块中,才是“被信任的”。
第2章 比特币的原理
2.1 交易、区块、挖矿和区块链
与传统银行和支付系统不同,比特币系统是以去中心化信任为基础的。
由于比特币网络中不存在中央权威信任机构,“信任”成为了比特币用户
之间存在的一种突出特性。在本章中,我们将从一个较高层面检视比特
币,通过追踪一笔比特币系统中的单独交易,来看看它在比特币分布式
共识机制中变得“被信任”和“被接受”的情形,以及最终成功地被存储到
区块链(区块链是一个分布式的公共账簿,包含所有发生在比特币系统
中的交易)。
书中每一个例子都是比特币网络中发生的真实交易,通过将资金从一钱
包发送到另一钱包来模拟用户(Joe、Alice和Bob)间的交互。我们在追
踪一笔通过比特币网络和区块链的交易时,将用到一些区块链数据库查
询网站使每个步骤可以方便在网页上直接被呈现。提供区块链数据查询
的网站就像是一个比特币的搜索引擎,你可以搜索比特币的地址、交易
和区块,以及可以看他们之间的关系和资金流动。
常见的区块链数据查询网站包括:
Blockchain info
Bitcoin Block Explorer
insight ? blockr Block Reader
以上每一个查询网站都有搜索功能,可以通过地址,交易哈希值或区块
号,搜索到在比特币网络和区块链中对应的等价数据。我们将给每个例
子提供一个链接,可以直接带你到相关条目,方便你做详细研究。
2.1.1 比特币概述
图2-1 比特币概述
如图2-1所示的概述图中,我们可以看到比特币系统由用户(用户通过密钥控制钱包)、交易(每一笔交易都会被广播到整个比特币网络)和
矿工(通过竞争计算生成在每个节点达成共识的区块链,区块链是一个
分布式的公共权威账簿,包含了比特币网络发生的所有的交易)组成。
在本章中,我们将通过追踪在网络上传输的一笔交易,从整个比特币系
统的的视角检视各个部分之间的交互。后续章节将详细阐述钱包、挖
矿、商家系统背后的技术细节。
2.1.2 买咖啡
在之前章节里,Alice是一名刚刚获得第一枚比特币的新用户。在“ 1.4.2
获取你的第一枚比特币 ”一节中,Alice和她的朋友Joe会面时,用现金换
取了比特币。由Joe产生的这笔交易使得Alice的钱包拥有了0.10比特
币。现在Alice将第一次使用比特币在加利福尼亚州帕罗奥图的Bob咖啡
店买一杯咖啡。Bob咖啡店给他的销售网点系统新增加了一个比特币支
付选项,价格单上列的是当地货币(美元)的售价,但在收银台,顾客
可以选择用美元或比特币支付。此时,Alice点了杯咖啡,然后Bob将交
易键入到收银机,之后销售系统将按照当前市场汇率把美元总价转换为
比特币,然后同时显示两种货币的价格,并显示一个包含这笔交易支付
请求的二维码(如图2-2所示):
图2-2
总价:
1.50 USD
0.0150 BTC这个二维码中的URL是:
bitcoin:1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA?
amount=0.015
label=Bob%27s%20Cafe
message=Purchase%20at%20Bob%27s%20Cafe
根据BIP0021的定义,此URL的意思是:
A bitcoin address: 1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA
The payment amount: 0.015
A label for the recipient address: Bob's Cafe
A description for the payment: Purchase at Bob's Cafe
与一个简单包含目的比特币地址的二维码不同,当前支付请求的是
一个二维编码过的URL,它包含有一个目的地址,一笔支付金额,和一个像“Bob咖啡”这样的交易描述。这使比特币钱包应用在发送支付请求时,可以预先填好支付用的特定信息,给用户显示一种友
好易懂的描述。你可以用比特币钱包应用扫描这个二维码来看Alice
可能看到的信息。
Bob说到,“总共1.50美元,或15毫比特币”
Alice用她的智能手机扫描了显示的条形码。她的智能手机显示一笔给
Bob咖啡的0.0150比特币的支付请求,然后她按下发送键授权了这笔支
付。在几秒钟时间内(大约与信用卡授权所需时间相同)Bob将会在收
银台看到这笔交易,并完成交易。
在接下来的章节中,我们将更详细地检视这笔交易,观察Alice的钱包是
怎样构建交易,交易又是怎样在网络中广播、怎样被验证,以及Bob在
后续交易中怎样消费那笔钱。
从千分之一比特币(1毫比特币)到一亿分之一比特币(1聪比特
币),比特币网络可以处理任意小额交易。在本书中,我们将
用“比特币”这个术语来表示任意数量的比特币货币,从最小单元
(1聪)到可被挖出的所有比特币总数(21,000,000)。
2.2 比特币交易
简单来说,交易告知全网:比特币的持有者已授权把比特币转帐给其他
人。而新持有者能够再次授权,转移给该比特币所有权链中的其他人,产生另一笔交易来花掉这些比特币,后面的持有者在花费比特币也是用
类似的方式。
交易就像复式记账法账簿中的行。简单来说,每一笔交易包含一个或多
个“输入”,输入是针对一个比特币账号的负债。这笔交易的另一面,有
一个或多个“输出”,被当成信用点数记入到比特币账户中。这些输入和
输出的总额(负债和信用)不需要相等。相反,当输出累加略少于输入
量时,两者的差额就代表了一笔隐含的“矿工费”,这也是将交易放进账簿的矿工所收集到的一笔小额支付。如图2-3描述的是一笔作为记账簿
记录的比特币交易。
图2-3
交易也包含了每一笔被转移的比特币(输入)的所有权证明,它以所有
者的数字签名形式存在,并可以被任何人独立验证。在比特币术语
中,“消费”指的是签署一笔交易:转移一笔以前交易的比特币给以比特
币地址所标识的新所有者。
交易是将钱从交易输入移至输出。输入是指钱币的来源,通常是之
前一笔交易的输出。交易的输出则是通过关联一个密钥的方式将钱
赋予一个新的所有者。目的密钥被称为是安全锁(Encumbrance)。这样就给资金强加了一个要求:有签名才能在
以后的交易中赎回资金。一笔交易的输出可以被当做另一笔新交易
的输入,这样随着钱从一个地址被移动到另一个地址的同时形成了
一条所有权链(如图2-4)。
图2-4
Alice支付Bob咖啡时使用一笔之前的交易作为输入。在以前的章节中,Alice从她朋友Joe那里用现金换了点比特币。那笔交易有一些比特币被
Alice的密钥锁定(阻塞)。在她支付Bob咖啡店的新交易中使用了之前
的交易作为输入,并以支付咖啡和找零作为新的输出。交易形成了一条
链,最近交易的输入对应以前交易的输出。Alice的密钥提供了解锁之前
交易输出的签名,因此向比特币网络证明她拥有这笔钱。她将咖啡的支
付附到Bob的地址上,同时“阻塞”那笔输出,指明要求是Bob签名才能
消费这笔钱。这就描述了在Alice和Bob之间钱的转移。上图展示了从Joe
到Alice再到Bob的交易链。2.2.1 常见的交易形式
最常见的交易形式是从一个地址到另一个地址的简单支付,这种交易也
常常包含给支付者的“找零”。一般交易有一个输入和两个输出,如图2-
5所示:
图2-5
另一种常见的交易形式是集合多个输入到一个输出(如图2-6)的模
式。这相当于现实生活中将很多硬币和纸币零钱兑换为一个大额面钞。
像这样的交易有时由钱包应用产生来清理许多在支付过程收到的小数额
的找零。
图2-6
最后,另一种在比特币账簿中常见的交易形式是将一个输入分配给多个
输出,即多个接收者(如图2-7)的交易。这类交易有时被商业实体用
作分配资金,例如给多个雇员发工资的情形。
图2-7
2.3 交易的构建
Alice的钱包应用知道如何选取合适的输入和输出以建立Alice所希望的
交易。Alice只需要指定目标地址和金额,其余的细节钱包应用会在后台
自动完成。很重要的一点是,钱包应用甚至可以在完全离线时建立交
易。就像在家里写张支票,之后放到信封发给银行一样,比特币交易建
立和签名时不用连接比特币网络。只有在执行交易时才需要将交易发送
到网络。
2.3.1 获取正确的输入
Alice的钱包应用首先要找到一些足够支付给Bob所需金额的输入。大多
数钱包应用维护着一个含有用钱包自己密钥锁定的“未消费交易输出”小
型数据库。因此Alice的钱包会包含她用现金从Joe那里购买的比特币的
交易输出副本(参见在“ 1.4.2 获取你的第一枚比特币 ”一节)。完整客
户端含有整个区块链中所有交易的所有未消费输出副本。这使得钱包即
能拿这些输出构建交易,又能在收到新交易时很快地验证其输入是否正确。然而,完整客户端占太大的硬盘空间,所以大多数钱包使用轻量级
的客户端,只保存用户自己的未消费输出。
如果钱包客户端没有某一未消费交易输出,它可以通过不同的服务者提
供的各种API或完整索引节点的JSON PRC API从比特币网络中拿到这一
交易信息。例子2-1展示了用HTTP GET命令对一个特定URL建立了一个
RESTful API的请求。这个URL会返回一个地址的所有未消费交易输
出,以提供给需要这些信息的任何应用作为建立新交易的输入而进行消
费。我们用一个简单的HTTP命令行客户端 cURL来获得这个响应数据。
例2-1 查找Alice的比特币地址所有的未消费的输出
curl https:blockchain.infounspent?active=1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK
例2-2 查找返回的响应数据
{
unspent_outputs: [
{
tx_hash:186f9f998a5...2836dd734d2804fe65fa35779,tx_index:104810202,tx_output_n:0,script:76a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac,value:10000000,value_hex:00989680,confirmations:0
}
]}
例2-2的响应数据显示了在Alice的地址
1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK 上面有一个未消费输出(还
未被兑换)。这个响应包含一个交易的索引。而从Joe那里转过来的未
消费输入就包含在这个交易里面,它的价值是一千万聪(satoshi),即
0.10比特币。通过这个信息,Alice的钱包应用就可以创建新的交易将钱
转账到新地址。
点击查看Joe和Alice间的交易信息
如你所见,Alice的钱包在单个未消费的输出中有足够的比特币支付一杯
咖啡。假如不够的话,Alice的钱包应用就不得不搜寻一些小的未消费输
出,像是从一个存钱罐里找硬币一样,直到找到足够支付咖啡的数量。
在两种情境下,可能都需要找回零钱,而这些找零也会是钱包所创建的
交易的输出组成部分。我们会在下一节会有所描述。
2.3.2 创建交易输出
交易的输出会被创建成为一个包含这笔数额的脚本的形式,只能被引入
这个脚本的一个解答后才能兑换。简单点说就是,Alice的交易输出会包
含一个脚本,这个脚本说 “这个输出谁能拿出一个签名和Bob的公开地
址匹配上,就支付给谁”。因为只有Bob的钱包的私钥可以匹配这个地
址,所以只有Bob的钱包可以提供这个签名以兑换这笔输出。因此Alice
会用需要Bob的签名来包装一个输出。
这个交易还会包含第二个输出。因为Alice的金额是0.10比特币的输出形式,对0.015 比特币一杯的咖啡来说太多了,需要找Alice 0.085比特币的
零钱。Alice钱包创建给她的零钱的支付就在付给Bob的同一个交易里
面。可以说,Alice的钱包将她的金额分成了两个支付:一个给Bob,一
个给自己。她可以在以后的交易里消费这笔零钱输出。
最后,为了让这笔交易尽快地被网络处理,Alice的钱包会多付一小笔费
用。这个不是明显地包含在交易中的;而是通过输入和输出的差值所隐
含的。如果Alice创建找零时只找 0.0845比特币,而不是 0.085比特币的
话,这里就有剩下 0.0005比特币(50万聪) 。因为加起来小到 0.10,所以这个 0.10 比特币的输入就没有被完整的消费了。这个差值会就被
矿工当作交易费放到区块的交易里,最终放进区块链帐薄中。
这个交易的结果信息可以用区块链数据查询站点看到,如图2-8所示。
图2-8
点击查看Alice支付Bob咖啡的交易的信息
2.3.3 将交易放到总账簿中
这个被Alice钱包应用创建的交易大小为258字节,包含了金额未来所属
需要的全部信息。现在,这个交易必须要被传送到比特币网络中以成为
分布式账簿(区块链)的一部分。在下一节里,我们来看下一个交易如
何成为新区块的一部分,以及区块是如何被挖矿构建的。最后,我们会
看看新区块被加进区块链后,是如何随更多区块的添加而增加可信度
的。
2.3.3.1 交易的传送
因为这个交易包含处理所需的所有信息,所以这个交易是被如何或从哪
里传送到比特币网络的就无所谓了。比特币网络是由参与的比特币客户
端联接几个其他比特币客户端组成的P2P网络。比特币网络的目的是将
交易和区块传播给所有参与者。
2.3.3.2 如何传播
Alice的钱包应用可以发送新的交易给其它任意一个已联接到互联网的比
特币客户端,不论其是由有线网、WiFi、还是通过手机联接的。她的钱
包不必直接连着Bob的比特币钱包,且她不必使用咖啡厅提供的网络联
网,虽然这两者都是可能的。任何比特币网络节点(其它客户端)收到
一个之前没见过的有效交易时会立刻将它转发给联接到自身的其它节
点。因此,这个交易迅速地从P2P网络中传播开来,几秒内就能到达大
多数节点。
2.3.3.3 Bob的视角
如果Bob的比特币钱包应用是直接连接Alice的钱包应用的话,Bob的钱
包应用也许就是第一个收到这个交易的节点。然而,即使Alice的交易是从通过其它节点发过来的,一样可以在几秒钟内到达Bob钱包应用这
里。Bob的钱包会立即确认Alice的交易是一个收入支付,因为它包含能
用Bob的私钥兑换的输出。Bob的钱包应用也能够独立地用之前未消费
输入来确认这个交易是正确构建的,并且由于包含足够交易费会被下一
个区块包含进去。这时Bob就可以以一个很小的风险假定这个交易会很
快被加到区块且被确认。
一个对比特币交易的常见误解是它们必须要等10分钟后被确认加进
一个新区块,或等60分钟以得到六次确认后才是有效的。虽然这些
确认可以确保交易已被整个网络接受,但对于像一杯咖啡这样的小
额商品来说就没有必要等待那么长时间了。一个商家可以免确认来
接受比特币小额支付。这样做的风险不比接受一个不是用有效身份
证领取或没有签名的信用卡的风险更大,而后者是现在商家常做的
事情。
2.4 比特币挖矿
这个交易现在在比特币网络上传播开来。但只有被一个称为挖矿的过程
验证且加到一个区块中之后,这个交易才会成为这个共享账簿(区块
链)的一部分。关于挖矿的详细描述请见 第8章 。
比特币系统的信任是建立在计算的基础上的。交易被包在一起放进区块
中时需要极大的计算量来证明,但只需少量计算就能验证它们已被证
明。挖矿在比特币系统中起着两个作用:
挖矿在构建区块时会创造新的比特币,和一个中央银行印发新的纸
币很类似。每个区块创造的比特币数量是固定的,随时间会渐渐减少。
挖矿创建信任。挖矿确保只有在包含交易的区块上贡献了足够的计
算量后,这些交易才被确认。区块越多,花费的计算量越大,意味着更
多的信任。描述挖矿的一个好方法是将之类比为一个巨大的多人数独谜题游戏。一
旦有人发现正解之后,这个数独游戏会自动调整困难度以使游戏每次需
要大约10分钟解决。想象一个有几千行几千列的巨大数独游戏。如果给
你一个已经完成的数独,你可以很快地验证它。然而,如果这个数独只
有几个方格里有数字其余方格都为空的话,就会花费非常长的时间来解
决。这个数独游戏的困难度可以通过改变其大小(更多或更少行列)来
调整,但即使它非常大时验证它也是相当容易的。而比特币中的 谜题
是基于哈希加密算法的,其展现了相似的特性:非对称地,它解起来困
难而验证很容易,并且它的困难度可以调整。
在 “ 1.3 比特币的应用、用户和他们的故事 ”一节中,我们提到了一个叫
Jing的在上海学计算机工程的学生。Jing在比特币网络中扮演了一个矿
工的角色。大概每10分钟,Jing和其他上千个矿工一起展开一场对一个
区块的交易寻找正解的全球竞赛。为寻找这个解,也被称为工作量证
明,整个网络需要具有每秒亿万次哈希计算的能力。这个工作量证明算
法指的用SHA256加密算法不断地对区块头和一个随机数字进行哈希计
算,直到出现一个和预设值相匹配的解。第一个找到这个解的矿工会赢
得这局竞赛并会将此区块发布到区块链中。
Jing从2010年开始挖矿,当时他使用一个非常快的桌面电脑来为新区块
寻找正解。随着更多的矿工加入比特币网络中,寻找谜题正解的困难度
迅速增大。不久,Jing和其他矿工升级成更专业的硬件,比如游戏桌面
电脑或控制台专用的高端独享图像处理单元芯片(即显卡GPU)。在写
这本书的时候,解题已经变得极其困难,只有使用集成了几百个挖矿专
用算法硬件并能同时在一个单独芯片上并行工作的专用集成电路
(ASIC)挖矿才会营利。Jing同时加入了一个类似彩票奖池的、能够让
多个矿工共享计算力和报酬的矿池。Jing现在运行两个通过USB联接的
ASIC机器每天24小时不间断地挖矿。他卖掉一些挖矿所得到的比特币
来支付电费,并可以通过营利获得一些收入。作为专用挖矿软件的后
台,他的计算机里安装了一个比特币索引客户端,名称为bitcoind。
2.5 区块中的挖矿交易记录
网络中产生的一笔交易直到成为整个比特币大账簿——区块链的一部分
时才会被确认有效。平均每10分钟,矿工会将自上一个区块以来发生的
所有交易生成一个新的区块。新交易不断地从用户钱包和应用流入比特
币网络。当比特币网络上的节点看到这些交易时,会先将它们放到各自节点维护的一个临时的未经验证的交易池中。当矿工构建一个新区块
时,会将这些交易从这个交易池中拿出来放到这个新区块中,然后通过
尝试解决一个非常困难的问题(也叫工作量证明)以证明这个新区块的
合法性。挖矿过程的细节会在 “8.1 简介” 一节中详加描述。
这些交易被加进新区块时,以交易费用高的优先以及其它的一些规则进
行排序。矿工一旦从网络上收到一个新区块时,会意识到在这个区块上
的解题竞赛已经输掉了,会马上开始下一个新区块的挖掘工作。它会立
刻将一些交易和这个新区块的数字指纹放在一起开始构建下一个新区
块,并开始给它计算工作量证明。每个矿工会在他的区块中包含一个特
殊的交易,将新生成的比特币(当前每区块为25比特币)作为报酬支付
到他自己的比特币地址。如果他找到了使得新区块有效的解法,他就会
得到这笔报酬,因为这个新区块被加入到了总区块链中,他添加的这笔
报酬交易也会变成可消费的。参与矿池的Jing设置了他的软件,使得构
建新区块时会将报酬地址设为矿池的地址。然后根据各自上一轮贡献的
工作量将所得的报酬分给Jing和其他参与矿池挖矿的矿工。
Alice的交易被网络拿到后放进未验证交易池中。因为包含足够的交易
费,它被Jing的矿池放到了生成的新区块中。大约在Alice的钱包第一次
将这个交易发送出来五分钟后,Jing的ASIC矿机发现了新区块的正解并
将之发布为第277,316号区块,包含419个其它交易。Jing的ASIC矿机将
这个新区块发布到网络上后,其它矿机就会验证它,并投身到构建新区
块的竞赛中。
你可以查看包含 Alice交易记录 的这个区块的信息。
几分钟后,第277,317号新区块诞生在另一个挖矿节点中。因为这个新
区块是基于包含Alice交易的第277,316号区块的,在这个区块的基础上
增加了更多的计算,因此就加强了这些交易的可信度。包含Alice交易的
区块对这个交易来说算一次证明。基于这个区块每产生一个新区块,对这个交易来说就会增加了一次证明。当区块一个个堆上来时,这个
交易变得指数级地越来越难被推翻,因此它在网络中得到更多信任。
图2-9
在图2-9中,我们可以看到包含Alice的交易的第277,316号区块。在它之
下有377,361个区块(包括0号区块),像链子一样一个连着一个(区块
链),一直连到0号区块,即创世区块。随着时间变长,这个区块链的
高度也随之增长,每个区块和整个链的计算复杂度也随之增加。包含
Alice的交易的区块后面形成的新区块使得信任度进一步增加,因为他们
叠加了更多的计算在这个越来越长的链子上。按惯例来说,一个区块获
得六次以上“证明”时就被认为是不可撤销的了,因为要撤销和重建六个
区块需要巨量的计算。在 第8章 我们会详细描述挖矿和信任建立的过
程。
2.6 消费这笔交易
既然Alice的这笔交易已经成为区块的一部分被嵌入到了区块链中,它就
成为了整个分布式比特币账簿的一部分并对所有比特币客户端应用可见。每个比特币客户端都能独立地验证这笔交易是有效且可消费的。全
索引客户端可以追钱款的来源,从第一次有比特币在区块里生成的那一
刻开始,按交易与交易间的关系顺藤摸瓜,直到Bob的交易地址。轻量
级客户端通过确认一个交易在区块链中且在它后面有几个新区块来确认
一个支付的合法性。这种方式叫做简易支付验证(参见 “6.7 简易支付验
证(SPV)节点” )。
Bob现在可以将此交易和其它交易的结果信息作为输入,创建新的所有
权为其他人的交易。这样就实现了对此交易的消费。举个例子,Bob可
以用Alice支付咖啡的比特币转账给承包商或供应商以支付相应费用。大
多数情况下,Bob用的比特币商户端会将多个小额支付聚合成一个大的
支付,也许会将一整天的比特币收入聚合成一个交易。这样会将多个支
付合成到咖啡店财务账户的一个单独地址。图2-6为交易集合示例。
当Bob花费从Alice和其他顾客那里赚得的比特币时,他就扩展了比特币
的交易链条。而这个链条会被加到整个区块链账簿,使所有人知晓并信
任。我们假定Bob向在邦加罗尔的网站设计师Gopesh支付一个新网页的
设计费用。那么区块交易链会如图2-10所示。
图2-10
第3章 比特币客户端3.1 比特币核心:参考实现
你可以从bitcoin.org下载标准客户端,即比特币核心,也叫“中本聪客户
端”(satoshi client)。它实现了比特币系统的所有方面,包括钱包、对
整个交易账簿(区块链)完整拷贝的交易确认引擎,和点对点比特币网
络中的一个完整网络节点。
在Bitcoin网站的选择钱包页面 ,下载参考客户端比特币核心。根据操作
系统不同,你将下载不同的可执行安装工具。对于Windows,它是一个
ZIP归档文件或.exe格式的可执行文件。对于Mac OS,它是一个.dmg格
式的磁盘映像。Linux版本包括用于Ubuntu系统的PPA包,或是 tar.gz格
式的压缩包。图3-1所示的Bitcoin.org页面上列出了一些推荐的比特币客
户端。
图3-1 选择比特币客户端
3.1.1 第一次运行比特币核心如果你下载了一个安装包,比如.exe、.dmg、或PPA,你可以和安装其
它任何应用程序一样,在你的操作系统上安装它。对于Windows,运
行.exe文件,按照提示一步步操作。对于Mac OS,启动.dmg文件,然后
将Bitcoin-QT 图标拖拽到你的应用程序目录就可以了。对于Ubuntu,在
文件资源管理器中双击PPA文件,会打开程序包管理器来安装它。一旦
完成了安装,在你的应用程序列表中会有一个新的应用叫Bitcoin-QT。
双击这个图标就可以启动比特币客户端了。
第一次运行比特币核心时,它会开始下载整个区块链,这个过程可能需
要数天(见下图)。让它在后台运行,直到显示“已同步”,并且余额旁
边不再显示“数据同步中”。
比特币核心拥有交易账簿(区块链)的一份完整拷贝,里面记录了
自2009年比特币网络被发明以来发生在比特币网络上的每一笔交
易。这个数据集有几个GB(在2013年底大约是16GB),并且需要
几天的时间完成增量形式的下载(从区块0顺次下载到最新区
块)。在整个区块链数据集下载完成前,客户端将不能处理任何交
易或是更新账户余额。在下载数据集的过程中,客户端账户余额旁
会显示“数据同步中”,底部会显示“正在同步”。请确保你有足够的
磁盘空间、带宽和时间来完成初始同步。
3.1.2 从源码编译比特币核心比特币核心
对于开发者,可以选择下载包含完整源代码的ZIP包,也可以从Github
上克隆权威的源码仓库。在面 GitHub上的比特币页面 ,在侧边栏选择
下载ZIP。或者使用git命令行(git command line)在自己系统上创建源
码的本地拷贝。在下面的例子中,我们将通过unix风格的命令行,在
Linux或是Mac OS 上克隆源代码:
git clone https:github.combitcoinbitcoin.git
Cloning into 'bitcoin'...remote: Counting objects: 31864, done.
remote: Compressing objects: 100% (1200712007), done.
remote: Total 31864 (delta 24480), reused 26530 (delta 19621)
Receiving objects: 100% (3186431864), 18.47 MiB | 119 KiBs, done.
Resolving deltas: 100% (2448024480), done.
终端上的提示和输出结果可能会因版本有所不同。即使你的屏幕上
输出的内容跟这里的例子有点不一样,请遵照代码中的文档,这些
都是正常的。
在git clone操作完成后,在你本地的bitcoin目录就会有一份完整的源码
拷贝。通过在命令提示行输入cd bitcoin切换到这个目录下:
cd bitcoin
默认情况下,本地拷贝将与最新的代码同步,这可能是bitcoin的一个不
稳定或是 beta 版本。在编译这些代码之前,签出发布标签(realease
tag)以选择某一特定版本(a specific version)。 这将通过一个关键的
标签标记,让本地拷贝与代码仓库的特定快照同步。开发者用标签来标
记代码的特定发行版本号(version numBTCer)。首先,要找到可用的
标签,可以通过git tag命令:
git tag
v0.1.5v0.1.6test1
v0.2.0
v0.2.10
v0.2.11
v0.2.12
[... many more tags ...]
v0.8.4rc2
v0.8.5
v0.8.6
v0.8.6rc1
v0.9.0rc1
列出的标签是bitcoin的所有发行版本。按照约定,带有rc后缀的是预发
行版本,可以用来测试。没有后缀的稳定版本可以直接在产品环境上运
行。从上面的列表中,选择最新的发行版本,目前是v0.9.0rc1。为了让
本地代码跟这个版本一致,我们需要用git checkout 命令:
git checkout v0.9.0rc1
Note: checking out 'v0.9.0rc1'.
HEAD is now at 15ec451... Merge pull request 3605
源代码包含文档,可以在多个文件夹中找到。在命令提示行输入more
README.md可以在bitcoin目录下的README.md中查看主文档,用空
格键可以翻页。在这一章,我们将构建命令行的比特币客户端,在linux
上称作bitcoind。在您的平台上,通过输入more docbuild-unix.md,可以
阅读编译bitcoind命令行客户端的说明。Mac OSX和Windows平台的说明
可以在doc目录下找到,分别是build-osx.md或是build-msw.md。
仔细阅读build文档第一部分中build的必备条件。这些是在你编译之前你
的系统上必须具备的库文件。如果缺少这些必备条件,构建过程将会出
现错误并导致失败。如果因为缺少一个必备条件而发生这种情况,你可
以先安装它,然后在你停下的地方重新构建。假设这些必备条件已经具
备,你就可以开始构建过程,通过authgen.sh脚本,生成一组构建脚
本。
从v0.9版本开始,比特币核心的构建过程改用
autogenconfiguremake 体系。旧版本是用一个简单的Makefile,并
且和下面的例子稍微有一点不同。请遵照你想要编译版本的说明文
档。v0.9版本引入的 autogenconfiguremake 构建体系可能用于未来
所有版本的代码,是下面的例子中演示的系统
.autogen.sh
configure.ac:12: installing `srcbuild-auxconfig.guess'
configure.ac:12: installing `srcbuild-auxconfig.sub'
configure.ac:37: installing `srcbuild-auxinstall-sh'
configure.ac:37: installing `srcbuild-auxmissing'
srcMakefile.am: installing `srcbuild-auxdepcomp'
autogen.sh脚本创建了一系列的自动配置脚本,会询问你的系统以发现
正确的设置,确保你已安装必要的库来编译源码。这里面最重要的是
configure脚本,它会提供许多不同的选项来定制构建过程。输
入.configure --help 可以查看各种不同的选项:
.configure --help
`configure' configures Bitcoin Core 0.9.0 to adapt to many kinds of systems.
Usage: .configure [OPTION]... [VAR=VALUE]...
To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.
See below for descriptions of some of the useful variables.
Defaults for the options are specified in brackets.
Configuration:
-h, --help display this help and exit--help=short display options specific to this package--help=recursive display the short help of all the included packages
-V, --version display version information and exit
[... many more options and variables are displayed below ...]Optional Features:--disable-option-checking ignore unrecognized --enable--with options--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
[... more options ...]
Use these variables to override the choices made by `configure' or to help it to
find libraries and programs with nonstandard nameslocations.
Report bugs to
通过使用--enable-FEATURE和--disable-FEATURE选项,configure脚本
允许你启用或是禁用某些功能,FEATURE需要被替换成功能名称,在
上面的帮助输出中可以找到。在这一章,我们将用默认的功能来构建
bitcoind客户端。这里不会使用配置选项,但是你应该检查一遍,明白
哪些可选的功能可以作为客户端的一部分。下一次,运行configure脚本
就可以自动发现所有必要的库,然后为我们的系统创建一个定制的构建
脚本。
.configure
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking for a BSD-compatible install... usrbininstall -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... binmkdir -pchecking for gawk... no
checking for mawk... mawk
checking whether make sets (MAKE)... yes
[... many more system features are tested ...]
configure: creating .config.status
config.status: creating Makefile
config.status: creating srcMakefile
config.status: creating srctestMakefile
config.status: creating srcqtMakefile
config.status: creating srcqttestMakefile
config.status: creating sharesetup.nsi
config.status: creating shareqtInfo.plist
config.status: creating qapull-testerrun-bitcoind-for-test.sh
config.status: creating qapull-testerbuild-tests.sh
config.status: creating srcbitcoin-config.h
config.status: executing depfiles commands
如果一切顺利,configure命令将会以创建可定制的构建脚本结束。这些
构建脚本允许我们编译bitcoind。如果有缺失的库或是错误,configur命
令将会以错误信息终止。如果出现了错误,可能是因为缺少库或是有不
兼容的库。重新检查构建文档,确认你已经安装缺失的必备条件。然后
运行configure,看看错误是否消失了。下一步,你将编译源代码,这个
过程可能需要1个小时完成。在编译的过程中,你应该过几秒或是几分
钟看一下输出结果。如果出现了问题,你会看到错误。如果中断了,编
译的过程可以在任何时候恢复。输入make命令就可以开始编译了: make
Making all in src
make[1]: Entering directory `homeubuntubitcoinsrc'
make all-recursive
make[2]: Entering directory `homeubuntubitcoinsrc'
Making all in .
make[3]: Entering directory `homeubuntubitcoinsrc'
CXX addrman.o
CXX alert.o
CXX rpcserver.o
CXX bloom.o
CXX chainparams.o
[... many more compilation messages follow ...]
CXX test_bitcoin-wallet_tests.o
CXX test_bitcoin-rpc_wallet_tests.o
CXXLD test_bitcoin
make[4]: Leaving directory `homeubuntubitcoinsrctest'
make[3]: Leaving directory `homeubuntubitcoinsrctest'
make[2]: Leaving directory `homeubuntubitcoinsrc'
make[1]: Leaving directory `homeubuntubitcoinsrc'
make[1]: Entering directory `homeubuntubitcoin'
make[1]: Nothing to be done for `all-am'.
make[1]: Leaving directory `homeubuntubitcoin'
如果一切顺利,bitcoind现在已经编译完成。最后一步就是通过make命
令,安装 bitcoind 可执行文件到你的系统路径下:
sudo make install
Making install in src
Making install in .
binmkdir -p 'usrlocalbin'
usrbininstall -c bitcoind bitcoin-cli 'usrlocalbin'
Making install in test
make install-am
binmkdir -p 'usrlocalbin'
usrbininstall -c test_bitcoin 'usrlocalbin'
你可以通过询问系统下面2个可执行文件的路径,来确认bitcoin是否安
装成功。
which bitcoind
usrlocalbinbitcoind
which bitcoin-cli
usrlocalbinbitcoin-clibitcoind 默认的安装位置是usrlocalbin。当你第一次运行bitcoind时,它
会提醒你用一个安全密码给JSON-RPC接口创建一个配置文件。通过在
终端输入bitcoind就可以运行bitcoind了:
bitcoind
Error: To use the -server option, you must set a rpcpassword in the
configuration file:
homeubuntu.bitcoinbitcoin.conf
It is recommended you use the following random password:
rpcuser=bitcoinrpc
rpcpassword=2XA4DuKNCbtZXsBQRRNDEwEY2nM6M4H9Tx5dFjoAVVbK
(you do not need to remember this password)
The username and password MUST NOT be the same.
If the file does not exist, create it with owner-readable-only file permissions.
It is also recommended to set alertnotify so you are notified of problems;
for example: alertnotify=echo %s | mail -s Bitcoin Alert admin@foo.com
在你喜欢的编辑器中编辑配置文件并设置参数,将其中的密码替换成
bitcoind推荐的强密码。不要使用出现在这里的密码。在.bitcoin目录下
创建一个名为.bitcoinbitcoin.conf 的文件,然后输入用户名和密码:
rpcuser=bitcoinrpc
rpcpassword=2XA4DuKNCbtZXsBQRRNDEwEY2nM6M4H9Tx5dFjoAVVbK当你正在编辑配置文件的时候,你可能想要设置一些其他选项,例如
txindex(见 “交易数据库索引及txindex选项” )。通过输入 bitcoind --help
,可以查看所有可用的选项列表。
现在可以运行比特币核心客户端。当你第一次运行的时候,它会下载所
有的区块,重新构建比特币区块链。这是一个好几个GB的文件,可能
需要大约2天的时间全部下载完。你可以通过 SourceForge 上的BitTorrent
客户端下载区块链的部分拷贝来缩短区块链的初始化时间。
选项 -daemon 可以以后台模式运行 bitcoind。
bitcoind -daemon
Bitcoin version v0.9.0rc1-beta (2014-01-31 09:30:15 +0100)
Using OpenSSL version OpenSSL 1.0.1c 10 May 2012
Default data directory homebitcoin.bitcoin
Using data directory bitcoin
Using at most 4 connections (1024 file descriptors available)
init message: Verifying wallet...
dbenv.open LogDir=bitcoindatabase ErrorFile=bitcoindb.log
Bound to [::]:8333
Bound to 0.0.0.0:8333
init message: Loading block index...
Opening LevelDB in bitcoinblocksindex
Opened LevelDB successfully
Opening LevelDB in bitcoinchainstate
Opened LevelDB successfully
[... more startup messages ...]3.2 通过命令行使用比特币核心的JSON-
RPC API接口
比特币核心客户端实现了JSON-RPC接口,这个接口也可以通过命令行
帮助程序bitcoin-cli访问。命令行可以使用API进行编程,让我们有能力
进行交互实验。开始前,调用help命令查看可用的比特币RPC命令列
表:
bitcoin-cli help
addmultisigaddress nrequired [key,...] ( account )
addnode node add|remove|onetry
backupwallet destination
createmultisig nrequired [key,...]
createrawtransaction [{txid:id,vout:n},...] {address:amount,...}
decoderawtransaction hexstring
decodescript hex
dumpprivkey bitcoinaddress
dumpwallet filename
getaccount bitcoinaddress
getaccountaddress account
getaddednodeinfo dns ( node )
getaddressesbyaccount account
getbalance ( account minconf )
getbestblockhash
getblock hash ( verbose )
getblockchaininfogetblockcount
getblockhash index
getblocktemplate ( jsonrequestobject )
getconnectioncount
getdifficulty
getgenerate
gethashespersec
getinfo
getmininginfo
getnettotals
getnetworkhashps ( blocks height )
getnetworkinfo
getnewaddress ( account )
getpeerinfo
getrawchangeaddress
getrawmempool ( verbose )
getrawtransaction txid ( verbose )
getreceivedbyaccount account ( minconf )
getreceivedbyaddress bitcoinaddress ( minconf )
gettransaction txid
gettxout txid n ( includemempool )
gettxoutsetinfo
getunconfirmedbalance
getwalletinfo
getwork ( data )
help ( command )
importprivkey bitcoinprivkey ( label rescan )
importwallet filename
keypoolrefill ( newsize )
listaccounts ( minconf )
listaddressgroupingslistlockunspent
listreceivedbyaccount ( minconf includeempty )
listreceivedbyaddress ( minconf includeempty )
listsinceblock ( blockhash target-confirmations )
listtransactions ( account count from )
listunspent ( minconf maxconf [address,...] )
lockunspent unlock [{txid:txid,vout:n},...]
move fromaccount toaccount amount ( minconf comment )
ping
sendfrom fromaccount tobitcoinaddress amount ( minconf comment commentto)
sendmany fromaccount {address:amount,...} ( minconf comment )
sendrawtransaction hexstring ( allowhighfees )
sendtoaddress bitcoinaddress amount ( comment comment-to )
setaccount bitcoinaddress account
setgenerate generate ( genproclimit )
settxfee amount
signmessage bitcoinaddress message
signrawtransaction hexstring ( [{txid:id,vout:n,scriptPub-
Key:hex,redeemScript:hex},...] [privatekey1,...] sighashtype )
stop
submitblock hexdata ( jsonparametersobject )
validateaddress bitcoinaddress
verifychain ( checklevel numBTClocks )
verifymessage bitcoinaddress signature message
walletlock
walletpassphrase passphrase timeout
walletpassphrasechange oldpassphrase newpassphrase3.2.1 获得比特币核心客户端状态的信息
命令: getinfo
比特币 getinfo RPC命令显示关于比特币网络节点、钱包、区块链数据库
状态的基础信息。使用 bitcoin-cli 运行它:
bitcoin-cli getinfo
{
version : 90000,protocolversion : 70002,walletversion : 60000,balance : 0.00000000,blocks : 286216,timeoffset : -72,connections : 4,proxy : ,difficulty : 2621404453.06461525,testnet : false,keypoololdest : 1374553827,keypoolsize : 101,paytxfee : 0.00000000,errors :
}数据以JSON格式显示,JSON是一种可以很容易被编程语言“消耗”,但
同时对人类可读性也很高的格式。在这些数据中,我们看到比特币软件
客户端的版本编号(90000),协议编号(70002),钱包编号
(60000)。我们看到钱包中的当前余额是0。我们看到当前的区块高
度,这可以告诉我们有多少区块对此客户端已知(286216)。我们同样
看到关于比特币网络和关于此客户端的各种数据。我们将在其他章节中
更具体地探索这些设置。
bitcoind客户端需要花费可能超过一天的时间从其他比特币客户端
下载区块以“赶上”当前区块链高度。你可以使用getinfo命令查看已
知区块的数字以检查同步进度。
3.2.2 钱包设置及加密
命令: encryptwallet 、 walletpassphrase
在你向前生成秘钥和其他命令之前,你应当先用密码加密钱包。对于本
例,将使用 encryptwallet 命令,密码为“foo”。很明显,在你自己操作的
时候记得使用强且复杂的密码替换“foo”。
bitcoin-cli encryptwallet foo
wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet.
The keypool has been flushed, you need to make a new backup.
你可以再次使用 getinfo 命令以验证钱包是否已经加密。这次你将发现有
个叫做 unlocked_until 的新条目。这是一个计数器,告诉你保持钱包处于
解锁状态的解密密码将在内存中存储多久。最初计数器设置为0,意味
着钱包是被锁定的:
bitcoin-cli getinfo
{
version : 90000,[... other information...]
unlocked_until : 0,errors :
}
想解锁钱包,要使用 walletpassphrase 命令。 walletpassphrase 命令需要两个
参数——密码,和多久钱包会再次被自动锁定的秒数数字(计时器):
bitcoin-cli walletpassphrase foo 360
你可以确认钱包是解锁状态然后通过再次运行 getinfo 查看超过时限:
bitcoin-cli getinfo{
version : 90000,[... other information ...]
unlocked_until : 1392580909,errors :
}
3.2.3 钱包备份、纯文本导出及恢复
命令: backupwallet 、 importwallet 、 dumpwallet
下一步,我们将练习创建钱包的备份文件,然后从备份文件重新加载钱
包。使用 backupwallet 命令备份,提供文件名作为命令参数。这里我们将
钱包备份为文件 wallet.backup :
bitcoin-cli backupwallet wallet.backup
现在,为了重新加载备份文件,我们使用 importwallet 命令。如果你的钱
包处于锁定状态,你将需要先将钱包解锁(参考下一节的 walletpassphrase)以导入备份文件:
bitcoin-cli importwallet wallet.backup
dumpwallet 命令用来将钱包转储为人类可读的文本文件:
bitcoin-cli dumpwallet wallet.txt
more wallet.txt
Wallet dump created by Bitcoin v0.9.0rc1-beta (2014-01-31 09:30:15 +0100)
Created on 2014-02- 8dT20:34:55Z
Best block at time of backup was 286234
(0000000000000000f74f0bc9d3c186267bc45c7b91c49a0386538ac24c0d3a44), mined on 2014-02- 8dT20:24:01Z
KzTg2wn6Z8s7ai5NA9MVX4vstHRsqP26QKJCzLg4JvFrp6mMaGB9 2013-07- 4dT04:30:27Z
change=1 addr=16pJ6XkwSQv5ma5FSXMRPaXEYrENCEg47F
Kz3dVz7R6mUpXzdZy4gJEVZxXJwA15f198eVui4CUivXotzLBDKY 2013-07- 4dT04:30:27Z
change=1 addr=17oJds8kaN8LP8kuAkWTco6ZM7BGXFC3gk
[... many more keys ...]
3.2.4 钱包地址及接收交易
命令: getnewaddress 、 getreceivedbyaddress 、 listtransactions 、getaddressesbyaccount 、 getbalance
比特币参考客户端维护了一个地址池,地址池的大小可以用 getinfo 命令
keypoolsize 参数获取。这些地址是自动生成的,可以被用作公开接收地
址或零钱地址。使用 getnewaddress 命令可以获得其中的一个地址:
bitcoin-cli getnewaddress
1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL
现在我们可以使用这个地址从一个外部钱包(假设你在其他交易所、在
线钱包或其他bitcoind钱包有一些比特币)向我们的bitcoind钱包发送一
小笔比特币。在本例中,我们将向下面的地址中发送50mBTC(0.050比
特币)。
我们可以询问bitcoind客户端此地址已经接收到的比特币数额,以及指
定该数额要被加到余额中所需要的确认数。在本例中,我们指定只需要
0个确认。在从另一个钱包发送比特币数秒之后,我们将在这个钱包看
到反应。我们用 getreceivedbyaddress 命令、这个地址及设置确认数为0:
bitcoin-cli getreceivedbyaddress 1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL 0
0.05000000
如果我们忽略这个命令后面的0,我们将只能在至少 minconf 个确认之后
才能看到数额, minconf 是想要某笔交易出现在余额中所设置的最少确认
数。 minconf 设置在bitcoind配置文件指定。由于这笔发送比特币的交易仅在数秒之前完成,它还没有被确认,因而我们将看到余额是0:
bitcoin-cli getreceivedbyaddress 1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL
0.00000000
整个钱包接收到的交易可以通过使用 listtransactions 命令展示出来:
bitcoin-cli listtransactions
[
{
account : ,address:1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL,category : receive,amount : 0.05000000,confirmations : 0,txid : 9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309ac
bae2c14ae3,time : 1392660908,timereceived : 1392660908
}
]我们可以使用 getaddressesbyaccount 命令列出整个钱包的所有地址:
bitcoin-cli getaddressesbyaccount
[
1LQoTPYy1TyERbNV4zZbhEmgyfAipC6eqL,17vrg8uwMQUibkvS2ECRX4zpcVJ78iFaZS,1FvRHWhHBBZA8cGRRsGiAeqEzUmjJkJQWR,1NVJK3JsL41BF1KyxrUyJW5XHjunjfp2jz,14MZqqzCxjc99M5ipsQSRfieT7qPZcM7Df,1BhrGvtKFjTAhGdPGbrEwP3xvFjkJBuFCa,15nem8CX91XtQE8B1Hdv97jE8X44H3DQMT,1Q3q6taTsUiv3mMemEuQQJ9sGLEGaSjo81,1HoSiTg8sb16oE6SrmazQEwcGEv8obv9ns,13fE8BGhBvnoy68yZKuWJ2hheYKovSDjqM,1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL,1KHUmVfCJteJ21LmRXHSpPoe23rXKifAb2,1LqJZz1D9yHxG4cLkdujnqG5jNNGmPeAMD
]
最后, getbalance 命令将显示所有经过至少 minconf 个确认的交易加和后的
余额:
bitcoin-cli getbalance
0.05000000
如果交易还未被确认,getbalance返回的余额将为0。配置
项“minconf”决定了交易在余额中体现的最少确认数。
3.2.5 探索及解码交易
命令: gettransaction 、 getrawtransaction 、 decoderawtransaction
我们将使用 gettransaction 命令探索前面列出的入账交易。我们使用
gettransaction 命令通过交易哈希值获取一笔交易,交易哈希值出现在前
面的txid条目:
bitcoin-cli gettransaction
9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3
{
amount : 0.05000000,confirmations : 0,txid:9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3,time : 1392660908,timereceived : 1392660908,details : [
{
account : ,address:1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL,category : receive,amount : 0.05000000 }
]
}
交易ID在交易确认之前并不权威。区块链中找不到交易哈希值并不
意味着此笔交易没有进行。这被称作“交易延展性”,因为交易哈希
值在区块确认之前是可以更改的。在确认之后txid是不变且权威
的。
用 gettransaction 命令显示的交易格式为简化格式。若要得到整个交易代
码并且将之解码,我们将使用两个命令: getrawtransaction 和
decoderawtransaction 。第一, getrawtransaction 把交易哈希值(txid)当做一
个参数,并且把整个交易以一个“原始”的十六进制字符串的形式返回,而这也正是交易在比特币网络上存在的形式:
bitcoin-cli getrawtransaction
9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae30100000001d717279515f88e2f56ce4e8a31e2ae3e9f00ba1d0add648e80c480ea22e0c7d3000000008b483045022100a4ebbeec83225dedead659bbde7da3d026c8b8e12e61a2df0dd0758e227383b302203301768ef878007e9ef7c304f70ffaf1f2c975b192d34c5b9b2ac1bd193dfba2014104793ac8a58ea751f9710e39aad2e296cc14daa44fa59248be58ede65e4c4b884ac5b5b6dede05ba84727e34c8fd3ee1d6929d7a44b6e111d41cc79e05dbfe5ceaffffffff02404b4c00000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac1f312906000000001976a914107b7086b31518935c8d28703d66d09b3623134388ac00000000
要解码这个十六进制字符串,我们使用 decoderawtransaction 命令。复制粘
贴这个十六进制字符串作为 decoderawtransaction 的第一个参数以将整个内容解读为JSON数据格式(由于格式原因,在下面例子中十六进制字符
串被缩短):
bitcoin-cli decoderawtransaction 0100000001d717...388ac00000000
{
txid:9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3,version : 1,locktime : 0,vin : [
{
txid:d3c7e022ea80c4808e64dd0a1dba009f3eaee2318a4ece562f8ef815952717d7,vout : 0,scriptSig : {
asm :
3045022100a4ebbeec83225dedead659bbde7da3d026c8b8e12e61a2df0dd0758e227383b302203301768ef878007e9ef7c304f70ffaf1f2c975b192d34c5b9b2ac1bd193dfba20104793ac8a58ea751f9710e39aad2e296cc14daa44fa59248be58ede65e4c4b?
884ac5b5b6dede05ba84727e34c8fd3ee1d6929d7a44b6e111d41cc79e05dbfe5cea,hex:
483045022100a4ebbeec83225dedead659bbde7da3d026c8b8e12e61a2df0dd0758e227383b302203301768ef878007e9ef7c304f70ffaf1f2c975b192d34c5b9b2ac1bd193dfba2014104793ac8a58ea751f9710e39aad2e296cc14daa44fa59248be58ede65e4c4b884ac5b5b6dede05ba84727e34c8fd3ee1d6929d7a44b6e111d41cc79e05dbfe5cea
},sequence : 4294967295
}
],vout : [
{
value : 0.05000000,n : 0,scriptPubKey : {
asm : OP_DUP OP_HASH160
07bdb518fa2e6089fd810235cf1100c9c13d1fd2 OP_EQUALVERIFY OP_CHECKSIG,hex :76a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac,reqSigs : 1,type : pubkeyhash, addresses : [
1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL
]
}
},{
value : 1.03362847,n : 1,scriptPubKey : {
asm : OP_DUP OP_HASH160
107b7086b31518935c8d28703d66d09b36231343 OP_EQUALVERIFY OP_CHECKSIG,hex : 76a914107b7086b31518935c8d28703d66d09b3623134388ac,reqSigs : 1,type : pubkeyhash,addresses : [
12W9goQ3P7Waw5JH8fRVs1e2rVAKoGnvoy
]
}
}
]
}
交易解码展示这笔交易的所有成分,包括交易的输入及输出。在这个例
子中,我们可以看到这笔给我们新地址存入50mBTC的交易使用了一个
输入并且产生两个输出。这笔交易的输入是前一笔确认交易的输出(展
示位以d3c7开头的vin txid)。两个输出则是50mBTC存入额度及返回给
发送者的找零。我们可以使用相同命令(例如 gettransaction )通过检查由本次交易的txid
索引的前一笔交易进一步探索区块链。通过从一笔交易跳到另外一笔交
易,我们可以追溯一连串的交易,因为币值一定是从一个拥有者的地址
传送到另一个拥有者的地址。
一旦我们接收到的交易以记录在区块中的方式被确认, gettransaction 命
令将返回附加信息,显示包含交易的区块的哈希值(标识符)。
bitcoin-cli gettransaction
9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3
{
amount : 0.05000000,confirmations : 1,blockhash :
000000000000000051d2e759c63a26e247f185ecb7926ed7a6624bc31c2a717b,blockindex : 18,blocktime : 1392660808,txid : 9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3,time : 1392660908,timereceived : 1392660908,details : [
{
account : ,address : 1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL,category : receive,amount : 0.05000000
}
]
}这里,我们在区块哈希值(这笔交易所在区块的哈希值)条目看到新信
息,以及值为18的区块索引(表明我们的交易为此区块的第18笔交
易)。
交易数据库索引及txindex选项
比特币核心默认建立包含仅与用户钱包相关交易的数据库。若你想
使用类似 gettransaction 的命令访问所有交易,你需要配置比特币核
心去建立一个完整的交易索引,这个可以通过txindex选项实现。在
比特币核心配置文件中将 txindex 赋值为1(通常在安装目录的
.bitcoinbitcoin.conf 中可以找到)。一旦你改变了此参数,你需要
重启bitcoind,并等待其重建索引。
3.2.6 探索区块
命令: getblock 、 getblockhash
既然我们知道我们的交易在哪个区块中,我们可以使用 getblock 命令,并把区块哈希值作为参数来查询对应的区块:
bitcoin-cli getblock 000000000000000051d2e759c63a26e247f185ecb7926ed7a6624b?
c31c2a717b true
{
hash : 000000000000000051d2e759c63a26e247f185ecb7926ed7a6624bc31c2a717
b,confirmations : 2,size : 248758,height : 286384,version : 2,merkleroot :
9891747e37903016c3b77c7a0ef10acf467c530de52d84735bd55538719f9916,tx : [
46e130ab3c67d31d2b2c7f8fbc1ca71604a72e6bc504c8a35f777286c6d89bf0,2d5625725b66d6c1da88b80b41e8c07dc5179ae2553361c96b14bcf1ce2c3868, 923392fc41904894f32d7c127059bed27dbb3cfd550d87b9a2dc03824f249c80,f983739510a0f75837a82bfd9c96cd72090b15fa3928efb9cce95f6884203214,190e1b010d5a53161aa0733b953eb29ef1074070658aaa656f933ded1a177952,ee791ec8161440262f6e9144d5702f0057cef7e5767bc043879b7c2ff3ff5277,4c45449ff56582664abfadeb1907756d9bc90601d32387d9cfd4f1ef813b46be,3b031ed886c6d5220b3e3a28e3261727f3b4f0b29de5f93bc2de3e97938a8a53,14b533283751e34a8065952fd1cd2c954e3d37aaa69d4b183ac6483481e5497d,57b28365adaff61aaf60462e917a7cc9931904258127685c18f136eeaebd5d35,8c0cc19fff6b66980f90af39bee20294bc745baf32cd83199aa83a1f0cd6ca51,1b408640d54a1409d66ddaf3915a9dc2e8a6227439e8d91d2f74e704ba1cdae2,0568f4fad1fdeff4dc70b106b0f0ec7827642c05fe5d2295b9deba4f5c5f5168,9194bfe5756c7ec04743341a3605da285752685b9c7eebb594c6ed9ec9145f86,765038fc1d444c5d5db9163ba1cc74bba2b4f87dd87985342813bd24021b6faf,bff1caa9c20fa4eef33877765ee0a7d599fd1962417871ca63a2486476637136,d76aa89083f56fcce4d5bf7fcf20c0406abdac0375a2d3c62007f64aa80bed74,e57a4c70f91c8d9ba0ff0a55987ea578affb92daaa59c76820125f31a9584dfc,9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3,[... many more transactions ...]
],time : 1392660808,nonce : 3888130470,bits : 19015f53,difficulty : 3129573174.52228737,chainwork :
000000000000000000000000000000000000000000001931d1658fc04879e466,previousblockhash :
0000000000000000177e61d5f6ba6b9450e0dade9f39c257b4d48b4941ac77e7,nextblockhash :
0000000000000001239d2c3bf7f4c68a4ca673e434702a57da8fe0d829a92eb6这个区块包含367笔交易,并且如你所见,列出的第18笔交易( 9ca8f9…)就是存入50mBTC到我们地址的txid我们可以通过heigh条目来判断:
这就是整个区块链中第286,384个区块。
我们同样可以使用 getblockhash 命令通过区块高度来检索一个区块,这样
需要将区块高度作为参数,并返回那个区块的区块哈希值。
bitcoin-cli getblockhash 0000000000019d6689c085ae165831e934ff763ae46a2a6c17?
2b3f1b60a8ce26f
bitcoin-cli getblockhash
这里,我们获得了“创世区块”的区块哈希值,这是被中本聪所挖的第一
个区块,高度为0。所获得的区块信息如下:
bitcoin-cli getblock 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1?
b60a8ce26f
{
hash : 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26?f,confirmations : 286388,size : 285,height : 0,version : 1,merkleroot : 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7af? deda33b,tx : [
4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
],time : 1231006505,nonce : 2083236893,bits : 1d00ffff,difficulty : 1.00000000,chainwork :
0000000000000000000000000000000000000000000000000000000100010001,nextblockhash :
00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048
}
getblock 、 getblockhash 和 gettransaction 命令可以按照一定编程准则,去探
索区块链数据库。
3.2.7 基于UTXO(未花费的交易输出)的建立、签名与提交
命令: listunspent 、 gettxout 、 createrawtransaction 、 decoderawtransaction 、signrawtransaction 、 sendrawtransaction
比特币的交易是基于花费“输出”上的,即上一笔交易的支出,整个交易
在地址之间转移所有权。我们的钱包现在收到了一笔向我们钱包地址发
来的钱(输出)。一旦它被确定之后,那笔钱就属于我们了。
首先,我们可以使用 listunspent 命令去查看我们钱包中所有剩余的从之
前交易中已确认的支出:
bitcoin-cli listunspent[
{
txid :
9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3,vout : 0,address : 1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL,account : ,scriptPubKey : 76a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac,amount : 0.05000000,confirmations : 7
}
]
我们发现交易 9ca8f9 建立了一个被指派到 1hvzSo 地址的输出(“vout”一项
为0)对于50mBTC数量的比特币在这个时间点已经收到了7次确认。通
过参考交易之前的txit和vout指数,交易系统将先前的输出变为本次的输
入。我们现在可以创立一个花费第0个vout的易 9ca8f9 的账单。利用他的
输入分配成新的输出,即给新地址赋值。
首先,让我们仔细观察输出的结果。我们可以使用 gettxout 命令来得到
未花费的输出的详细细节。交易输出通常可以参考txid和vout两个指
标。以下就是我们通过 gettxout 命令得到的结果:
bitcoin-cli gettxout
9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3 0
{
bestblock :
0000000000000001405ce69bd4ceebcdfdb537749cebe89d371eb37e13899fd9,confirmations : 7,value : 0.05000000, scriptPubKey : {
asm : OP_DUP OP_HASH160 07bdb518fa2e6089fd810235cf1100c9c13d1fd2
OP_EQUALVERIFY OP_CHECKSIG,hex : 76a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac,reqSigs : 1,type : pubkeyhash,addresses : [
1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL
]
},version : 1,coinbase : false
}
在这里我们看到由50mBTC分配到我们的账户地址 1hvz… 中。如果我们想
用掉剩余的比特币,我们要重新建立一笔新的交易。首先,我们为这笔
交易建立一个新的地址,告诉它将去往哪里:
bitcoin-cli getnewaddress 1LnfTndy3qzXGN19Jwscj1T8LR3MVe3JDb
我们将25mBTC送往我们钱包中新的地址 1LnfTn… 。在这笔新的交易中,我们将要花费50mBTC并且放入25mBTC到这个新地址中。因为我们必
须花费所有之前交易的输出,同时我们必然产生一些找零。我们将产生的找零放回1hvz…的地址之中,即将找零放回到原先产生比特币的地址
之中。最后,我们必须为这次交易支出一些费用——我们将0.5mBTC作
为交易费,最终再存入24.5mBTC的找零。新的输出(25mBTC+
24.5mBTC=49.5mBTC)和输入(50 mBTC)之间的差额就是奖励给矿
工的交易费。
我们用 createrawtransaction 命令去建立一笔交易。我们将交易的收入(50
已确认未支出的mBTC)和两笔交易的输出(送往新地址的比特币和从
原先账户找回的零钱)作为 createrawtransaction 的参数。
bitcoin-cli createrawtransaction '[{txid :
9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3, vout : 0}]'
'{1LnfTndy3qzXGN19Jwscj1T8LR3MVe3JDb: 0.025,1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL: 0.0245}'
0100000001e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862aecf53ebd69f9a89c0000000000ffffffff02a0252600000000001976a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac50622500000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac00000000
createrawtransaction 命令产生了一个原始十六进制字符串,其中编码了这
笔交易的诸多细节。我们首先要通过 decoderawtransaction 命令来解码这个
字符串,以确认所有的细节准确无误:
bitcoin-cli decoderawtransaction
0100000001e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862aecf53ebd69f9a89c0000000000ffffffff02a0252600000000001976a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac50622500000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac00000000
{
txid : 0793299cb26246a8d24e468ec285a9520a1c30fcb5b6125a102e3fc05d4f3cba,version : 1,locktime : 0,vin : [
{
txid :9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3,vout : 0,scriptSig : {
asm : ,hex :
},sequence : 4294967295
}
],vout : [
{
value : 0.02500000,n : 0,scriptPubKey : {
asm : OP_DUP OP_HASH160
d90d36e98f62968d2bc9bbd68107564a156a9bcf OP_EQUALVERIFY OP_CHECKSIG,hex : 76a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac,reqSigs : 1,type : pubkeyhash,addresses : [
1LnfTndy3qzXGN19Jwscj1T8LR3MVe3JDb
]
}
},{
value : 0.02450000,n : 1,scriptPubKey : {
asm : OP_DUP OP_HASH160
07bdb518fa2e6089fd810235cf1100c9c13d1fd2 OP_EQUALVERIFY OP_CHECKSIG,hex : 76a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac,reqSigs : 1, type : pubkeyhash,addresses : [
1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL
]
}
}
]
}
结果无误!我们的交易“消耗了”从我们已确认的交易中未花费的输出,然后将它变成两笔输出,一个是走向了新地址的25mBTC,另一个是从
原来地址返回的24.5mBTC零钱。这之间0.5mBTC的差额作为交易费,以奖励挖出包含我们这笔交易区块的矿工。
你有可能注意到,交易中包含一个空的条目 scriptSig ,因为我们并没有
给它签名。如果没有签名,那么交易是没有意义的;同时我们也不能证
明我们拥有未花费的输出的来源地址的所有权。通过签名,我们移除了
输出上的障碍同时证明了我们的输出可靠。我们使用 signrawtransaction 命
令去签名交易。它需要原始十六进制的字符串作为参数:
一个加密的钱包在签名之前必须解密,因为签名需要利用钱包中的
秘钥。
bitcoin-cli walletpassphrase foo 360 bitcoin-cli signrawtransaction 0100000001e34ac1e2baac09c366fce1c2245536bda8?
f7db0f6685862aecf53ebd69f9a89c0000000000ffffffff02a0252600000000001976a914d90?
d36e98f62968d2bc9bbd68107564a156a9bcf88ac50622500000000001976a91407bdb518fa2e?
6089fd810235cf1100c9c13d1fd288ac00000000
{
hex :
0100000001e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862aecf53ebd69f9a89c000000006a47304402203e8a16522da80cef66bacfbc0c800c6d52c4a26d1d86a54e0a1b76d661f020c9022010397f00149f2a8fb2bc5bca52f2d7a7f87e3897a273ef54b277e4af52051a06012103c9700559f690c4a9182faa8bed88ad8a0c563777ac1d3f00fd44ea6c71dc5127ffffffff02a0252600000000001976a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac50622500000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac00000000,complete : true
}
输入 signrawtransaction 命令后,得到另一串十六进制的原始加密交易。我
们要对它进行解密,然后去查看发生的变化,请输入 decoderawtransaction
命令:
bitcoin-cli
decoderawtransaction0100000001e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862aecf53ebd69f9a89c000000006a47304402203e8a16522da80cef66bacfbc0c800c6d52c4a26d1d86a54e0a1b76d661f020c9022010397f00149f2a8fb2bc5bca52f2d7a7f87e3897a273ef54b277e4af52051a06012103c9700559f690c4a9182faa8bed88ad8a0c563777ac1d3f00fd44ea6c71dc5127ffffffff02a0252600000000001976a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac50622500000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac00000000
{
txid : ae74538baa914f3799081ba78429d5d84f36a0127438e9f721dff584ac17b346,version : 1,locktime : 0,vin : [
{
txid :
9ca8f969bd3ef5ec2a8685660fdbf7a8bd365524c2e1fc66c309acbae2c14ae3,vout : 0,scriptSig : {
asm :
304402203e8a16522da80cef66bacfbc0c800c6d52c4a26d1d86a54e0a1b76d661f020c9022010397f00149f2a8fb2bc5bca52f2d7a7f87e3897a273ef54b277e4af52051a0601
03c9700559f690c4a9182faa8bed88ad8a0c563777ac1d3f00fd44ea6c71dc5127, hex :
47304402203e8a16522da80cef66bacfbc0c800c6d52c4a26d1d86a54e0a1b76d661f020c9022010397f00149f2a8fb2bc5bca52f2d7a7f87e3897a273ef54b277e4af52051a06012103c9700559f690c4a9182faa8bed88ad8a0c563777ac1d3f00fd44ea6c71dc5127
},sequence : 4294967295
}
],vout : [
{
value : 0.02500000,n : 0,scriptPubKey : {
asm : OP_DUP OP_HASH160
d90d36e98f62968d2bc9bbd68107564a156a9bcf OP_EQUALVERIFY OP_CHECKSIG,hex : 76a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac,reqSigs : 1,type : pubkeyhash,addresses : [
1LnfTndy3qzXGN19Jwscj1T8LR3MVe3JDb
]
}
},{
value : 0.02450000,n : 1,scriptPubKey : {
asm : OP_DUP OP_HASH160
07bdb518fa2e6089fd810235cf1100c9c13d1fd2 OP_EQUALVERIFY OP_CHECKSIG,hex : 76a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac,reqSigs : 1,type : pubkeyhash,addresses : [
1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL ]
}
}
]
}
现在,交易中的收入包含了 scritSig ,一串证明钱包地址 1hvz… 所有权的
数字签名,同时移除了支出上的障碍,然后我们可以对钱包中的钱进行
消费。签名可以让这笔交易被比特币交易网络中的任何节点验证,使他
们变得可靠。
现在,该是提交新交易到比特币网络的时候了。我们使用由原始十六进
制 signrawtransaction 命令生成的 sendrawtransaction 命令。以下就是和刚才解
码时类似的字符串:
bitcoin-cli
sendrawtransaction0100000001e34ac1e2baac09c366fce1c2245536bda8f7db0f6685862aecf53ebd69f9a89c000000006a47304402203e8a16522da80cef66bacfbc0c800c6d52c4a26d1d86a54e0a1b76d661f020c9022010397f00149f2a8fb2bc5bca52f2d7a7f87e3897a273ef54b277e4af52051a06012103c9700559f690c4a9182faa8bed88ad8a0c563777ac1d3f00fd44ea6c71dc5127ffffffff02a0252600000000001976a914d90d36e98f62968d2bc9bbd68107564a156a9bcf88ac50622500000000001976a91407bdb518fa2e6089fd810235cf1100c9c13d1fd288ac00000000ae74538baa914f3799081ba78429d5d84f36a0127438e9f721dff584ac17b346
当使用 sendrawtransaction 命令发布交易到比特币网络时,它会返回交易的
哈希值。我们现在可以通过 gettransaction 命令查询交易ID:
bitcoin-cli gettransaction
ae74538baa914f3799081ba78429d5d84f36a0127438e9f721dff584ac17b346
{ amount : 0.00000000,fee : -0.00050000,confirmations : 0,txid : ae74538baa914f3799081ba78429d5d84f36a0127438e9f721dff584ac17b346,time : 1392666702,timereceived : 1392666702,details : [
{
account : ,address : 1LnfTndy3qzXGN19Jwscj1T8LR3MVe3JDb,category : send,amount : -0.02500000,fee : -0.00050000
},{
account : ,address : 1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL,category : send,amount : -0.02450000,fee : -0.00050000
},{
account : ,address : 1LnfTndy3qzXGN19Jwscj1T8LR3MVe3JDb,category : receive,amount : 0.02500000
},{
account : ,address : 1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL,category : receive,amount : 0.02450000
} ]
}
和以前一样,我们同样可以通过使用 getrawtransaction 和 decodetransaction 命
令来检查交易中的细节。这些命令会得到一个在发送到比特币网络之前
进行编码和解码并且十分精准的原始十六进制字符串。
3.3 其他替代客户端、资料库、工具包
除了参考客户端(bitcoind),还可以使用其他的客户端和资料库去连
接比特币网络和数据结构。这些工具都由一系列的编程语言执行,用他
们各自的语言为比特币程序提供原生的交互。
其他的执行方式包括:
libbitcoin和sx tools
一款C++,通过命令行完成的全节点多线程客户端与程序库
bitcoinj
一款全节点java客户端和程序库
btcd
一款全节点GO 语言的比特币客户端
Bits of Proof(BOP)
一款Java企业级平台的比特币工具
picocoin 一款轻量级比特币执行客户端
pybitcointools
一款Python语言的比特币程序库
pycoin
另一款Python语言的比特币程序库
在其他的编程语言中,还有许多形式的比特币(程序)库。开发者也尽
其所能,一直在尽力创造新的比特币工具。
3.3.1 Libbitcoin和sx Tools
Libbitcoin程序是一款基于C++层面,可扩展、多线程、模块化的执行工
具。它可以支持全节点客户端和一款叫做sx的命令行工具,并可以提供
我们本章所讨论的比特币命令相同的功能。Sx工具同时提供了管理和操
作工具,是bitcoind所不能提供的,包括type-2型确定性密钥和密码助记
工具。
安装sx
若要安装sx工具以及相关libbitcoin库,请在Linux操作系统中下载并安装
在线安装包:
wget http:sx.dyne.orginstall-sx.sh
sudo bash .install-sx.sh
现在你应当已经安装好了sx工具。输入没有参数的sx命令来显示帮助文档,帮助文档列出了所有可用的命令(详见附录4)。
sx工具提供了许多实用的编码与解码地址的命令,可以从不同的编
码方式转化,也可以转化成不同的方式。通过他们,可以探索更多
的编码方式,比如Base58,Base58Check,hex,等等。
3.3.2 pycoin
pycoin 最初由Richard Kiss创立并维护,是一款基于Python库,并可以支
持比特币密钥的操作和交易的客户端,甚至可以支持编译语言从而处理
非标准交易。
Pycoin库同时支持Python2(2.7x)与Python3,以及一些便于使用的命令
行工具,比如ku和tx。如果在Python3的虚拟环境下安装 pycoin0.42,请
输入以下命令:
python3 -m venv tmppycoin
. tmppycoinbinactivate
pip install pycoin==0.42
Downloadingunpacking pycoin==0.42
Downloading pycoin-0.42.tar.gz (66kB): 66kB downloaded
Running setup.py (path:tmppycoinbuildpycoinsetup.py) egg_info for pack-age
pycoin
Installing collected packages: pycoin
Running setup.py install for pycoin
Installing tx script to tmppycoinbin
Installing cache_tx script to tmppycoinbin Installing bu script to tmppycoinbin
Installing fetch_unspent script to tmppycoinbin ......
您现在查看是摘要介绍页, 详见PDF附件(12515KB,639页)。





