1. 1. [第1章] 介绍
    1. 1.1. 什么是比特币
    2. 1.2. 比特币发展史
    3. 1.3. 比特币客户端
  2. 2. [第2章] 比特币的原理
    1. 2.1. 交易的构建
    2. 2.2. 举例: 一个构建好的交易
    3. 2.3. 将交易放到总账簿中
    4. 2.4. 挖矿
  3. 3. [第3章] 比特币客户端
    1. 3.1. 比特币核心
  4. 4. [第4章] 密钥、地址、钱包
    1. 4.1. 公钥加密和加密货币
    2. 4.2. 私钥和公钥
    3. 4.3. Base58 和 Base58Check 编码
    4. 4.4. 密钥的格式
    5. 4.5. 比特币钱包
    6. 4.6. 高级密钥和地址
  5. 5. [第5章] 交易
    1. 5.1. 比特币交易的生命周期
    2. 5.2. 交易结构
    3. 5.3. 交易的输出和输入
    4. 5.4. 交易费
    5. 5.5. 交易链条和孤立交易
    6. 5.6. 比特币交易脚本和脚本语言
    7. 5.7. 标准交易
  6. 6. [第6章] 比特币网络
    1. 6.1. P2P网络架构
    2. 6.2. 节点类型及分工
    3. 6.3. 扩展比特币网络
    4. 6.4. 网络发现
    5. 6.5. 全节点
    6. 6.6. 简易支付验证 (SPV)节点
    7. 6.7. Bloom过滤器
    8. 6.8. 交易池
    9. 6.9. 警告消息
  7. 7. [第7章] 区块链
    1. 7.1. 区块结构
    2. 7.2. 区块标识符
    3. 7.3. 创世区块
    4. 7.4. 区块的连接
    5. 7.5. Merkle 树
  8. 8. [第8章] 挖矿与共识
    1. 8.1. 简介
    2. 8.2. 比特币经济学和货币创造
    3. 8.3. 去中心化共识
    4. 8.4. 交易的独立校验
    5. 8.5. 挖矿节点
    6. 8.6. 整合交易至区块
    7. 8.7. 交易块龄,矿工费和优先级
    8. 8.8. 创币交易
    9. 8.9. 构造区块头
    10. 8.10. 构建区块
    11. 8.11. 校验新区块
    12. 8.12. 区块链的组装与选择
    13. 8.13. 区块链分叉
    14. 8.14. 随机值升位方案
    15. 8.15. 矿池
    16. 8.16. 共识攻击
  9. 9. [第9章] 竞争币、竞争块链和应用程序
    1. 9.1. 竞争币和竞争块链的分类
    2. 9.2. 元币平台
    3. 9.3. 竞争币/山寨币
    4. 9.4. 评估竞争币的价值
    5. 9.5. 非货币型竞争区块链
    6. 9.6. 加密货币的未来
  10. 10. [第10章] 比特币安全
    1. 10.1. 安全准则
    2. 10.2. 信任根源
    3. 10.3. 用户最佳安全实践

《精通比特币》笔记

[第1章] 介绍

什么是比特币

  • 一个去中心化的点对点网络(比特币协议)
  • 一个公共的交易账簿(区块链)
  • 一个去中心化的数学的和确定性的货币发行(分布式挖矿)
  • 一个去中心化的交易验证系统(交易脚本)

比特币发展史

  • 2008 年由中本聪提出
  • 2011 年中本聪淡出公众视野,比特币网络的开发与建设维护留给社区负责
  • 比特币的运行依赖于完全透明的数学原理,即一个分布式计算问题的解决方案

    中本聪的此项发明,对“拜占庭将军”问题也是一个可行的解决方案,这是一个在分布式计算中未曾解决的问题。简单来说,这个问题包括了试图通过在一个不可靠、具有潜在威胁的网络中,通过信息交流来达成一个行动协议共识。中本聪的解决方案是使用工作量证明的概念在没有中央信任机构下达成共识,这代表了分布式计算的科学突破,并已经超越了货币广泛的适用性。它可以用来达成去中心化的网络共识来公正选举、彩票、资产登记,以及数字化公证等等。

比特币客户端

  • 完整客户端: 一个完整客户端,或称“全节点”,是存储所有比特币交易的整个交易历史(由每一个用户完成的每一笔交易,曾经所有的每一笔)的客户端,管理用户的钱包,并可以在比特币网络上直接开始交易。类似于 server。
  • 轻量级客户端: 一个轻量级客户端存储用户的钱包,但需要依赖第三方服务器才能进行比特币交易,才能接入比特币网络。轻量级客户端不保存所有交易的完整副本,因此必须信赖第三方的服务器来获取交易确认。类似于 client。
  • 在线客户端: 在线客户端通过网页浏览器在第三方服务器上访问和储存该用户的钱包。类似于 web app。

    移动客户端: 智能手机的移动客户端,既可以作完整客户端运行,也可作为轻量级客户端或在线客户端。


[第2章] 比特币的原理

交易的构建

交易告知全网:比特币的持有者已授权把比特币转帐给其他人。

  • 一笔交易可以包含多个“输入”和多个“输出”,这些输入和输出的总额(负债和信用)不需要相等。相反,当输出累加略少于输入量时,两者的差额就代表了一笔隐含的“矿工费”,这也是将交易放进账簿的矿工所收集到的一笔小额支付。
  • 交易也包含了每一笔被转移的比特币(输入)的所有权证明,它以所有者的数字签名形式存在,并可以被任何人独立验证。
  • 比特币交易建立和签名时不用连接比特币网络。只有在执行交易时才需要将交易发送到网络。

    在比特币术语中,“消费”指的是签署一笔交易:转移一笔以前交易的比特币给以比特币地址所标识的新所有者。

    大多数钱包应用维护着一个含有用钱包自己密钥锁定的“未消费交易输出”小型数据库,用以找到一些足够支付所需金额的输入

举例: 一个构建好的交易

1
2
3
4
5
6
7
8
9
10
11
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可能看到的信息。

将交易放到总账簿中

  • 交易的传送: 比特币网络的目的是将交易和区块传播给所有参与者。
  • 如何传播: 任何比特币网络节点(其它客户端)收到一个之前没见过的有效交易时会立刻将它转发给联接到自身的其它节点。因此,这个交易迅速地从P2P网络中传播开来,几秒内就能到达大多数节点。
  • 接收方的视角: 即使发送方的交易是从通过其它节点发过来的,一样可以在几秒钟内到达接收方钱包应用这里。接收方的钱包会立即确认该交易是一个收入支付,因为它包含能用接收方的私钥兑换的输出。接收方的钱包应用也能够独立地用之前未消费输入来确认这个交易是正确构建的,并且由于包含足够交易费会被下一个区块包含进去。这时接收方就可以以一个很小的风险假定这个交易会很快被加到区块且被确认。

    一个对比特币交易的常见误解是它们必须要等10分钟后被确认加进一个新区块,或等60分钟以得到六次确认后才是有效的。虽然这些确认可以确保交易已被整个网络接受,但对于像一杯咖啡这样的小额商品来说就没有必要等待那么长时间了。一个商家可以免确认来接受比特币小额支付。这样做的风险不比接受一个不是用有效身份证领取或没有签名的信用卡的风险更大,而后者是现在商家常做的事情。

挖矿

  • 挖矿在构建区块时会创造新的比特币: 和一个中央银行印发新的纸币很类似。每个区块创造的比特币数量是固定的,随时间会渐渐减少。
  • 挖矿创建信任: 挖矿确保只有在包含交易的区块上贡献了足够的计算量后,这些交易才被确认。区块越多,花费的计算量越大,意味着更多的信任。

    比特币中的 “谜题” 是基于哈希加密算法的,其展现了相似的特性:非对称地,它解起来困难而验证很容易,并且它的困难度可以调整。

    这个工作量证明算法指的用SHA256加密算法不断地对区块头和一个随机数字进行哈希计算,直到出现一个和预设值相匹配的解。第一个找到这个解的矿工会赢得这局竞赛并会将此区块发布到区块链中。

    每个矿工会在他的区块中包含一个特殊的交易,将新生成的比特币(当前每区块为25比特币)作为报酬支付到他自己的比特币地址。如果他找到了使得新区块有效的解法,他就会得到这笔报酬,因为这个新区块被加入到了总区块链中,他添加的这笔报酬交易也会变成可消费的。


[第3章] 比特币客户端

比特币核心

即从 bitcoin.org 下载标准客户端,也叫“中本聪客户端”(satoshi client)。它实现了比特币系统的所有方面,包括钱包、对整个交易账簿(区块链)完整拷贝的交易确认引擎,和点对点比特币网络中的一个完整网络节点。


[第4章] 密钥、地址、钱包

公钥加密和加密货币

  • 在比特币系统中,我们用公钥加密创建一个密钥对。密钥对包括一个私钥,和由其衍生出的唯一的公钥。公钥用于接收比特币,而私钥用于比特币支付时的交易签名。
  • 公钥和私钥之间的数学关系,使得私钥可用于生成特定消息的签名。此签名可以在不泄露私钥的同时对公钥进行验证。
  • 支付比特币时,比特币的当前所有者需要在交易中提交其公钥和签名(每次交易的签名都不同,但均从同一个私钥生成)。比特币网络中的所有人都可以通过所提交的公钥和签名进行验证,并确认该交易是否有效,即确认支付者在该时刻对所交易的比特币拥有所有权。

    大多数比特币钱包工具为了方便会将私钥和公钥以密钥对的形式存储在一起。然而,公钥可以由私钥计算得到,所以只存储私钥也是可以的。

私钥和公钥

  • 私钥: 就是一个随机选出的数字而已。一个比特币地址中的所有资金的控制取决于相应私钥的所有权和控制权。
  • 公钥: 通过椭圆曲线算法可以从私钥计算得到公钥,这是不可逆转的过程。

    K = k * G 。其中k是私钥,G是被称为生成点的常数点,而K是所得公钥。其反向运算,被称为“寻找离散对数”,即已知公钥K来求出私钥k——是非常困难的,就像去试验所有可能的k值,即暴力搜索。

  • 比特币地址: 一个由数字和字母组成的字符串,可以与任何想给你比特币的人分享。比特币地址可由公钥经过单向的加密哈希算法得到,由公钥生成的比特币地址以数字“1”开头。

    以公钥 K 为输入,计算其SHA256哈希值,并以此结果计算 RIPEMD160 哈希值,得到一个长度为160比特(20字节)的数字:A = RIPEMD160(SHA256(K)) 公式中,K是公钥,A是生成的比特币地址。

Base58 和 Base58Check 编码

  • Base58 是一种基于文本的二进制编码格式,用在比特币和其它的加密货币中。这种编码格式不仅实现了数据压缩,保持了易读性,还具有错误诊断功能。
  • Base58Check是一种常用在比特币中的Base58编码格式,增加了错误校验码来检查数据在转录中出现的错误。

密钥的格式

公钥和私钥的都可以有多种编码格式。一个密钥被不同的格式编码后,虽然结果看起来可能不同,但是密钥所编码数字并没有改变。

  • 私钥的格式: 私钥可以以许多不同的格式表示,所有这些都对应于相同的256位的数字。
    • Hex (eg. 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD)
    • WIF (eg. 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn)
    • WIF-compressed (eg. KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ)
  • 公钥的格式
    • 非压缩格式公钥
    • 压缩格式公钥

      一个公钥是一个椭圆曲线上的点(x, y)。而椭圆曲线实际是一个数学方程,曲线上的点实际是该方程的一个解。因此,如果我们知道了公钥的x坐标,就可以通过解方程y2 mod p = (x3 + 7) mod p得到y坐标。这种方案可以让我们只存储公钥的x坐标,略去y坐标,从而将公钥的大小和存储空间减少了256比特。每个交易所需要的字节数减少了近一半,随着时间推移,就大大节省了很多数据传输和存储。

      未压缩格式公钥使用04作为前缀,而压缩格式公钥是以02或03作为前缀。为了区分y坐标的两种可能值,我们在生成压缩格式公钥时,如果y是偶数,则使用02作为前缀;如果y是奇数,则使用03作为前缀。

比特币钱包

钱包是私钥的容器,通常通过有序文件或者简单的数据库实现。

  • 非确定性(随机)钱包: 在最早的一批比特币客户端中,钱包只是随机生成的私钥集合。这种类型的钱包被称作零型非确定钱包。

    这种钱包现在正在被确定性钱包替换,因为它们难以管理、备份以及导入。这种情况直接与避免地址重复使用的原则相冲突——每个比特币地址只能用一次交易。地址通过关联多重交易和对方的地址重复使用会减少隐私。

  • 确定性(种子)钱包: 确定性,或者“种子”钱包包含通过使用单项离散方程而可从公共的种子生成的私钥。

    在确定性钱包中,种子足够收回所有的已经产生的私钥,所以只用在初始创建时的一个简单备份就足以搞定。并且种子也足够让钱包输入或者输出。这就很容易允许使用者的私钥在钱包之间轻松转移输入。

  • 助记码词汇: 助记码词汇是英文单词序列代表(编码)用作种子对应所确定性钱包的随机数。单词的序列足以重新创建种子,并且从种子那里重新创造钱包以及所有私钥。

    助记码代码可以让使用者复制钱包更容易一些,因为它们相比较随机数字顺序来说,可以很容易地被读出来并且正确抄写。

  • 分层确定性钱包(BIP0032/BIP0044): 分层确定性钱包包含从数结构所生成的钥匙。这种母钥匙可以生成子钥匙的序列。这些子钥匙又可以衍生出孙钥匙,以此无穷类推。

    有两个主要的优势。第一,树状结构可以被用来表达额外的组织含义。第二,它可以允许让使用者去建立一个公共密钥的序列而不需要访问相对应的私钥。

高级密钥和地址

  • 加密私钥(BIP0038): 使用一个口令加密私钥并使用Base58Check对加密的私钥进行编码,这样加密的私钥就可以安全地保存在备份介质里,安全地在钱包间传输,保持密钥在任何可能被暴露情况下的安全性。
  • P2SH (Pay-to-Script Hash)和多重签名地址
    • P2SH: 指定比特币交易中受益人作为哈希的脚本,而不是公钥的所有者。
    • 多重签名地址: P2SH 的一种实现,底层脚本需要多个签名来证明所有权,此后才能消费资金。
  • 比特币靓号地址: 包含了可读信息的有效比特币地址。
  • 纸钱包: 打印在纸张上的比特币私钥。

[第5章] 交易

比特币交易是比特币系统中最重要的部分。 根据比特币系统的设计原理,系统中任何其他的部分都是为了确保比特币交易可以被生成、能在比特币网络中得以传播和通过验证,并最终添加入全球比特币交易总账簿(比特币区块链)。比特币交易的本质是数据结构,这些数据结构中含有比特币交易参与者价值转移的相关信息。

比特币交易的生命周期

  1. 创建比特币交易: 比特币交易可以被任何人在线上或线下创建,即便创建这笔交易的人不是这个账户的授权签字人。一旦一笔比特币交易被创建,它会被资金所有者(们)签名。如果它是合法创建并签名的,则该笔交易现在就是有效的,它包含了转移这笔资金所需要的所有信息。有效的比特币交易必须能接入比特币网络,从而使之能被传送,直至抵达下一个登记在公共总账薄(区块链)的挖矿节点。
  2. 广播交易至比特币网络: 一笔交易需要传递至比特币网络,才能被传播,也才能加入区块链中。由于这笔交易是经过签名且不含任何机密信息、私钥或密码,因此它可被任何潜在的便利网络公开地传播。

    因为比特币将金钱变成了一种数据结构,所以在本质上是不可能阻止任何人创建并执行比特币交易的。

  3. 比特币交易在比特币网络中的传播: 一旦一笔比特币交易被发送到任意一个连接至比特币网络的节点,这笔交易将会被该节点验证。如果交易被验证有效,该节点将会将这笔交易传播到这个节点所连接的其他节点;同时,交易发起者会收到一条表示交易有效并被接受的返回信息。如果这笔交易被验证为无效,这个节点会拒绝接受这笔交易且同时返回给交易发起者一条表示交易被拒绝的信息。

交易结构

一笔比特币交易是一个含有输入值和输出值的数据结构,该数据结构植入了将一笔资金从初始点(输入值)转移至目标地址(输出值)的代码信息。

交易的输出和输入

比特币交易的基本单位是未经使用的一个交易输出,简称UTXO。UTXO是不能再分割、被所有者锁住或记录于区块链中的并被整个网络识别成货币单位的一定量的比特币货币。

当一个用户接收比特币时,金额被当作UTXO记录到区块链里。这样,一个用户的比特币会被当作UTXO分散到数百个交易和数百个区块中。实际上,并不存在储存比特币地址或账户余额的地点,只有被所有者锁住的、分散的UTXO。比特币钱包通过扫描区块链并聚合所有属于该用户的UTXO来计算该用户的余额。

对于输出和输入链来说,有一个例外,它是一种特殊的交易类型,称为Coinbase交易。这是每个区块中的首个交易。这种交易存在的原因是作为对挖矿的奖励而产生全新的可用于支付的比特币给“赢家”矿工。这也就是为什么比特币可以在挖矿过程中被创造出来。

  • 交易输出:
    • 一定量的比特币,被命名为“聪”,是最小的比特币单位
    • 一个锁定脚本,也被当作是“障碍”,提出支付输出所必须被满足的条件以“锁住”这笔总额。在大多数情况下,锁定脚本会把输出锁在一个特定的比特币地址上,从而把一定数量的比特币的所有权转移到新的所有者上。
  • 交易输入:
    • 一个指向特定的UTXO的指针,并被交易哈希和在区块链中记录UTXO的序列号作为参考。
    • 一个解锁脚本,用来满足UTXO的支付条件。解锁脚本通常是一个签名,用来证明对于在锁定脚本中的比特币地址拥有所有权。

交易费

  • 大多数交易包含交易费,这是为了在网络安全方面给比特币矿工一种补偿。
  • 交易费可当作是为了包含(挖矿)一笔交易到下一个区块中的一种鼓励,也可当作是对于欺诈交易和任何种类的系统滥用,在每一笔交易上通过征收一笔小成本的税而造成的一种妨碍。
  • 交易费被挖出这个区块的矿工得到,并且记录在这个交易的区块链中。
  • 交易费 = 求和(所有输入) - 求和(所有输出)

    举例来说,如果你消耗了一个20比特币的UTXO来完成1比特币的付款,你必须包含一笔19比特币的找零回到你的钱包。否则,那剩下的19比特币会被当作交易费,并且会被挖出你的交易到一个区块中的矿工收走。

交易链条和孤立交易

  • 交易形成一条链,这条链的形式是一笔交易消耗了先前的交易(父交易)的输出,并为随后的交易(子交易)创造了输出。

    有的时候组成整个链条的所有交易依赖于他们自己——比如父交易、子交易和孙交易——而他们又被同时创造出来,来满足复杂交易的工作流程。这需要在一个交易的父交易被签名之前,有一个合法的子交易被签名。

  • 当一条交易链被整个网络传送时,他们并不能总是按照相同的顺序到达目的地。

    有时,子交易在父交易之前到达。节点不会立即抛弃这个子交易,而是放到一个临时池中,并等着接收它的父交易,与此同时广播这个子交易给其他节点。没有父交易的交易池被称作孤立交易池。一旦接收到了父交易,所有与这个父交易创建的UTXO有关的孤块会从池中释放出来,递归地重新验证,然后整条交易链就会被交易池包括进去,并等待着被区块所挖走。

比特币交易脚本和脚本语言

  • 脚本创建(锁定与解锁): 比特币的交易验证引擎依赖于两类脚本来验证比特币交易:一个锁定脚本和一个解锁脚本。
    • 锁定脚本是一个放在一个输出值上的“障碍”,同时它明确了今后花费这笔输出的条件。
    • 解锁脚本是一个“解决”或满足被锁定脚本在一个输出上设定的花费条件的脚本,同时它将允许输出被消费。
  • 脚本语言: 比特币交易脚本语言,也称为脚本,是一种基于逆波兰表示法的基于堆栈的执行语言。
  • 图灵非完备性: 比特币脚本语言包含许多操作,但都故意限定为一种重要的方式——没有循环或者复杂流控制功能以外的其他条件的流控制。这样就保证了脚本语言的图灵非完备性,这意味着脚本的复杂性有限,交易可执行的次数也可预见。施加的这些限制确保该语言不被用于创造无限循环或其它类型的逻辑炸弹。
  • 非主权验证: 比特币交易脚本语言是无国家主权的,没有国家能凌驾于脚本之上,也没有国家会在脚本被执行后对其进行保存。所有需要执行脚本的所有信息都已包含在脚本中。

标准交易

  • P2PKH(Pay-to-Public-Key-Hash): 比特币网络上的大多数交易都是P2PKH交易,此类交易都含有一个锁定脚本,该脚本由公钥哈希实现阻止输出功能,公钥哈希即为广为人知的比特币地址。由P2PKH脚本锁定的输出可以通过键入公钥和由相应私钥创设的数字签名得以解锁。
  • P2PK(Pay-to-Public-Key): 与P2PKH模式含有公钥哈希的模式不同,在P2PK脚本模式中,公钥本身已经存储在锁定脚本中,而且代码长度也更短。
  • 多重签名: 多重签名脚本设置了这样一个条件,假如记录在脚本中的公钥个数为N,则至少需提供其中的M个公钥才可以解锁。
  • 数据输出(OP_RETURN操作符): OP_Return允许开发者在交易输出上增加40字节的非交易数据。然后,与伪交易型的UTXO不同,OP_Return创造了一种明确的可复查的非交易型输出,此类数据无需存储于UTXO集。OP_Return输出被记录在区块链上,它们会消耗磁盘空间,也会导致区块链规模的增加,但它们不存储在UTXO集中,因此也不会使得UTXO内存膨胀,更不会以消耗代价高昂的内存为代价使全节点都不堪重负。

    比特币的分发和时间戳账户机制(也即区块链),其潜在运用将大大超越支付领域。许多开发者试图充分发挥交易脚本语言的安全性和可恢复性优势,将其运用于电子公证服务、证券认证和智能协议等领域。

  • P2SH(Pay-to-Script-Hash): 在P2SH支付中,复杂的锁定脚本被电子指纹所取代,电子指纹为密码学哈希。当一笔交易试图支付UTXO时,要解锁支付脚本,它必须含有与哈希相匹配的脚本。P2SH的含义是,向与该哈希匹配的脚本支付,当输出被支付时,该脚本将在后续呈现。它旨在使复杂脚本的运用能与直接向比特币地址支付一样简单。
    • 在交易输出中,复杂脚本由简短电子指纹取代,使得交易代码变短。
    • 脚本能被编译为地址,支付指令的发出者和支付者的比特币钱包不需要复杂工序就可以执行P2SH。
    • P2SH将构建脚本的重担转移至接收方,而非发送方。
    • P2SH将长脚本数据存储的负担从输出方(存储于UTXO集,影响内存)转移至输入方(仅存储于区块链)。
    • P2SH将长脚本数据存储的重担从当前(支付时)转移至未来(花费时)。
    • P2SH将长脚本的交易费成本从发送方转移至接收方,接收方在使用该笔资金时必须含有赎回脚本。

      需要注意的是,因为赎回脚本只有在你试图发送一个P2SH输出时才会在比特币网络中出现,假如你将输出与一个无效的交易哈希锁定,则它将会被忽略。你将不能使用该笔资金,因为交易中含有赎回脚本,该脚本因是一个无效的脚本而不能被接受。这样的处理机制也衍生出一个风险,你能将比特币锁定在一个未来不能被花费的P2SH中。因为比特币网络本身会接受这一P2SH,即便它与无效的赎回脚本所对应(因为该赎回脚本哈希没有对其所表征的脚本给出指令)。


[第6章] 比特币网络

P2P网络架构

P2P是指位于同一网络中的每台计算机都彼此对等,各个节点共同提供网络服务,不存在任何“特殊”节点。P2P网络具有:

  • 可靠性
  • 去中心化
  • 开放性

    除了比特币P2P协议之外,比特币网络中也包含其他协议。我们使用“扩展比特币网络(extended bitcoin network)”指代所有包含比特币P2P协议、矿池挖矿协议、Stratum协议以及其他连接比特币系统组件相关协议的整体网络结构。

节点类型及分工

每个比特币节点都是路由、区块链数据库、挖矿、钱包服务的功能集合。

  • 全节点: 保有一份完整的、最新的区块链拷贝的节点。全节点能够独立自主地校验所有交易,而不需借由任何外部参照。
  • SPV节点: 又叫“轻量级节点”,只保留了区块链的一部分,通过一种名为“简易支付验证(SPV)”的方式来完成交易验证。
  • 挖矿节点: 通过运行在特殊硬件设备上的工作量证明(proof-of-work)算法,以相互竞争的方式创建新的区块。

    一些挖矿节点同时也是全节点,保有区块链的完整拷贝;还有一些参与矿池挖矿的节点是轻量级节点,它们必须依赖矿池服务器维护的全节点进行工作。

  • 用户钱包: 也可以作为全节点的一部分,这在桌面比特币客户端中比较常见。当前,越来越多的用户钱包都是SPV节点,尤其是运行于诸如智能手机等资源受限设备上的比特币钱包应用。

    在比特币P2P协议中,除了这些主要的节点类型之外,还有一些服务器及节点也在运行着其他协议,例如特殊矿池挖矿协议、轻量级客户端访问协议等。

扩展比特币网络

扩展比特币网络既包括了运行比特币P2P协议的网络,又包含运行特殊协议的网络节点。比特币P2P主网络上连接着许多矿池服务器以及协议网关,它们把运行其他协议的节点连接起来。这些节点通常都是矿池挖矿节点(参见第8章)以及轻量级钱包客户端,它们通常不具备区块链的完整备份。

网络发现

  • 当新的网络节点启动后,为了能够参与协同运作,它必须发现网络中的其他比特币节点。新的网络节点必须发现至少一个网络中存在的节点并建立连接。由于比特币网络的拓扑结构并不基于节点间的地理位置,因此各个节点之间的地理信息完全无关。
  • 比特币客户端会维持一个列表,那里列出了那些长期稳定运行的节点。这样的节点被称为“种子节点(seed nodes)”。新节点并不一定需要与种子节点建立连接,但连接到种子节点的好处是可以通过种子节点来快速发现网络中的其他节点。
  • 当建立一个或多个连接后,新节点将一条包含自身IP地址的addr消息发送给其相邻节点。相邻节点再将此条addr消息依次转发给它们各自的相邻节点,从而保证新节点信息被多个节点所接收、保证连接更稳定。另外,新接入的节点可以向它的相邻节点发送getaddr消息,要求它们返回其已知对等节点的IP地址列表。通过这种方式,节点可以找到需连接到的对等节点,并向网络发布它的消息以便其他节点查找。
  • 由于节点可以随时加入和离开,通讯路径是不可靠的。因此,节点必须持续进行两项工作:在失去已有连接时发现新节点,并在其他节点启动时为其提供帮助。

    总结: 比特币网络会随时根据变化的节点及网络问题进行动态调整,不需经过中心化的控制即可进行规模增、减的有机调整。

全节点

一个全节点连接到对等节点之后,第一件要做的事情就是构建完整的区块链。如果该节点是一个全新节点,那么它就不包含任何区块链信息,它只知道一个区块——静态植入在客户端软件中的创世区块。新节点需要下载从0号区块(创世区块)开始的数十万区块的全部内容,才能跟网络同步、并重建全区块链。

简易支付验证 (SPV)节点

  • SPV节点只需下载区块头,而不用下载包含在每个区块中的交易信息。
  • 简易支付验证是通过参考交易在区块链中的深度,而不是高度,来验证它们。

    例如,一个全节点要检查第300,000号区块中的某个交易,它会把从该区块开始一直回溯到创世区块的300,000个区块全部都链接起来,并建立一个完整的UTXO数据库,通过确认该UTXO是否还未被支付来证实交易的有效性。SPV节点则不能验证UTXO是否还未被支付。相反地,SPV节点会在该交易信息和它所在区块之间用merkle路径(见“7.7 Merkle 树”)建立一条链接。然后SPV节点一直等待,直到序号从300,001到300,006的六个区块堆叠在该交易所在的区块之上,并通过确立交易的深度是在第300,006区块~第300,001区块之下来验证交易的有效性。

  • SPV节点安全性
    • SPV节点不能验证某个交易(譬如同一个UTXO的双重支付)不存在,这是因为SPV节点没有一份关于所有交易的记录。这个漏洞会被针对SPV节点的拒绝服务攻击或双重支付型攻击所利用。为了防御这些攻击,SPV节点需要随机连接到多个节点,以增加与至少一个可靠节点相连接的概率。这种随机连接的需求意味着SPV节点也容易受到网络分区攻击或Sybil攻击。在后者情况中,SPV节点被连接到虚假节点或虚假网络中,没有通向可靠节点或真正的比特币网络的连接。
    • 由于SPV节点需要读取特定交易从而选择性地验证交易,这样就又产生了隐私风险。与全区块链节点收集每一个区块内的全部交易所不同的是,SPV节点对特定数据的请求可能无意中透露了钱包里的地址信息。

      在绝大多数的实际情况中,具有良好连接的SPV节点是足够安全的,它在资源需求、实用性和安全性之间维持恰当的平衡。当然,如果要保证万无一失的安全性,最可靠的方法还是运行完整区块链的节点。

Bloom过滤器

Bloom过滤器是一个允许用户描述特定的关键词组合而不必精确表述的基于概率的过滤方法。它能让用户在有效搜索关键词的同时保护他们的隐私。在SPV节点里,这一方法被用来向对等节点发送交易信息查询请求,同时交易地址不会被暴露。

交易池

  • 交易池: 比特币网络中几乎每个节点都会维护一份未确认交易的临时列表,被称为内存池或交易池。节点们利用这个池来追踪记录那些被网络所知晓、但还未被区块链所包含的交易。
  • 孤立交易池: 有些节点的实现还维护一个单独的孤立交易池。如果一个交易的输入与某未知的交易有关,如与缺失的父交易相关,该孤立交易就会被暂时储存在孤立交易池中直到父交易的信息到达。
  • 交易池和孤立交易池(如有实施)都是存储在本地内存中,并不是存储在永久性存储设备(如硬盘)里。
  • UTXO池: 有些比特币客户端的实现还维护一个UTXO数据库,也称UTXO池,是区块链中所有未支付交易输出的集合。

    交易池和孤立交易池代表的是单个节点的本地视角。取决于节点的启动时间或重启时间,不同节点的两池内容可能有很大差别。相反地,UTXO池代表的是网络的突显共识,因此,不同节点间UTXO池的内容差别不大。此外,交易池和孤立交易池只包含未确认交易,而UTXO池之只包含已确认交易。

警告消息

  • 警告消息是比特币的“紧急广播系统”,比特币核心开发人员可以借此功能给所有比特币节点发送紧急文本消息。这一功能是为了让核心开发团队将比特币网络的严重问题通知所有的比特币用户。
  • 警告通过公钥进行加密签名。对应的私钥是由核心开发团队的一些特定成员所持有。这样的数字签名可以确保虚假警告不会在网络中传播。

    警告系统迄今为止只被用过几次,最严重的一次是在2013年,一个关键的数据库缺陷导致比特币区块链中出现了一个多区块分叉。


[第7章] 区块链

区块链是由包含交易信息的区块从后向前有序链接起来的数据结构。它可以被存储为flat file(一种包含没有相对关系记录的文件),或是存储在一个简单数据库中。比特币核心客户端使用Google的LevelDB数据库存储区块链元数据。

“高度”来表示区块与首区块之间的距离;以及“顶部”或“顶端”来表示最新添加的区块。

  • 对每个区块头进行SHA256加密哈希,可生成一个哈希值。 通过这个哈希值,可以识别出区块链中的对应区块。同时,每一个区块都可以通过其区块头的“父区块哈希值”字段引用前一区块(父区块)。也就是说,每个区块头都包含它的父区块哈希值。这样把每个区块链接到各自父区块的哈希值序列就创建了一条一直可以追溯到第一个区块(创世区块)的链条。
  • 每个区块只有一个父区块,但可以暂时拥有多个子区块。 一个区块出现多个子区块的情况被称为“区块链分叉”。区块链分叉只是暂时状态,只有当多个不同区块几乎同时被不同的矿工发现时才会发生。最终,只有一个子区块会成为区块链的一部分,同时解决了“区块链分叉”的问题。
  • 由于区块头里面包含“父区块哈希值”字段,所以当前区块的哈希值因此也受到该字段的影响。 如果父区块的身份标识发生变化,子区块的身份标识也会跟着变化,从而导致孙区块以及后续链条上的所有区块的身份标识发生变化。一旦一个区块有很多代以后,这种瀑布效应将保证该区块不会被改变,除非强制重新计算该区块所有后续的区块。正是因为这样的重新计算需要耗费巨大的计算量,所以一个长区块链的存在可以让区块链的历史不可改变,这也是比特币安全性的一个关键特征。

区块结构

区块是一种被包含在公开账簿(区块链)里的聚合了交易信息的容器数据结构。它由一个包含元数据的区块头和紧跟其后的构成区块主体的一长串交易组成。区块头是80字节,而平均每个交易至少是250字节,而且平均每个区块至少包含超过500个交易。

  • 区块大小 (4字节): 用字节表示的该字段之后的区块大小
  • 区块头 (80字节): 组成区块头的几个字段
  • 交易计数器 (1-9 (可变整数)): 交易的数量
  • 交易 (可变的): 记录在区块里的交易信息

区块标识符

  • 区块头哈希值: 区块主标识符是它的加密哈希值,一个通过SHA256算法对区块头进行二次哈希计算而得到的数字指纹。区块哈希值可以唯一、明确地标识一个区块,并且任何节点通过简单地对区块头进行哈希计算都可以独立地获取该区块哈希值。
  • 区块高度: 第一个区块,其区块高度为0,每一个随后的区块,高度+1。

    区块可以通过两种方式被识别:区块哈希值或者区块高度。和区块哈希值不同的是,区块高度并不是唯一的标识符。虽然一个单一的区块总是会有一个明确的、固定的区块高度,但反过来却并不成立,一个区块高度并不总是识别一个单一的区块。两个或两个以上的区块可能有相同的区块高度,在区块链里争夺同一位置,即区块分叉。

创世区块

  • 区块链里的第一个区块创建于2009年,被称为创世区块。它是区块链里面所有区块的共同祖先,这意味着你从任一区块,循链向后回溯,最终都将到达创世区块。
  • 因为创世区块被编入到比特币客户端软件里,所以每一个节点都始于至少包含一个区块的区块链,这能确保创世区块不会被改变。

区块的连接

当一个节点从网络接收传入的区块时,它会验证这些区块,然后链接到现有的区块链上。为建立一个连接,一个节点将检查传入的区块头并寻找该区块的“父区块哈希值”。

Merkle 树

  • Merkle树是一种哈希二叉树,它是一种用作快速归纳和校验大规模数据完整性的数据结构。这种二叉树包含加密哈希值。
  • 在比特币网络中,Merkle树被用来归纳一个区块中的所有交易,同时生成整个交易集合的数字指纹,且提供了一种校验区块是否存在某交易的高效途径。
  • Merkle树被SPV节点广泛使用。SPV节点不保存所有交易也不会下载整个区块,仅仅保存区块头。它们使用认证路径或者Merkle路径来验证交易存在于区块中,而不必下载区块中所有交易。

    简而言之,SPV节点会收到少于1KB的有关区块头和Merkle路径的数据,其数据量比一个完整的区块(目前大约有1MB)少了一千倍有余。


[第8章] 挖矿与共识

简介

  • 挖矿是增加比特币货币供应的一个过程。 矿工们通过为比特币网络提供算力来换取获得比特币奖励的机会。
  • 挖矿保护着比特币系统的安全,防止欺诈交易,避免“双重支付”,“双重支付”是指多次花费同一笔比特币。
  • 矿工们验证每笔新的交易并把它们记录在总帐簿上。 每10分钟就会有一个新的区块被“挖掘”出来,每个区块里包含着从上一个区块产生到目前这段时间内发生的所有交易,这些交易被依次添加到区块链中。我们把包含在区块内且被添加到区块链上的交易称为“确认”交易,交易经过“确认”之后,新的拥有者才能够花费他在交易中得到的比特币。
  • 矿工们在挖矿过程中会得到两种类型的奖励:创建新区块的新币奖励,以及区块中所含交易的交易费。 然而随着挖矿奖励的递减,以及每个区块中包含的交易数量增加,交易费在矿工收益中所占的比重将会逐渐增加。在2140年之后,所有的矿工收益都将由交易费构成。

    新比特币的生成过程被称为挖矿是因为它的奖励机制被设计为速度递减模式,类似于贵重金属的挖矿过程。矿工通过创造一个新区块得到的比特币数量大约每四年(或准确说是每210,000个块)减少一半。

比特币经济学和货币创造

  • 通过创造出新区块,比特币以一个确定的但不断减慢的速率被铸造出来。 大约每十分钟产生一个新区块,每一个新区块都伴随着一定数量从无到有的全新比特币。每开采210,000个块,大约耗时4年,货币发行速率降低50%。在比特币运行的第一个四年中,每个区块创造出50个新比特币。到2140年左右,会存在接近2,100万比特币。在那之后,新的区块不再包含比特币奖励,矿工的收益全部来自交易费。
  • 总量有限并且发行速度递减创造了一种抗通胀的货币供应模式。 法币可被中央银行无限制地印刷出来,而比特币永远不会因超额印发而出现通胀。

    最重要并且最有争议的一个结论是一种事先确定的发行速率递减的货币发行模式会导致货币通货紧缩(简称通缩)。通缩是一种由于货币的供应和需求不匹配导致的货币增值的现象。它与通胀相反,价格通缩意味着货币随着时间有越来越强的购买力。
    许多经济学家提出通缩经济是一种无论如何都要避免的灾难型经济。因为在快速通缩时期,人们预期着商品价格会下跌,人们将会储存货币,避免花掉它。这种现象充斥了日本经济“失去的十年”,就是因为在需求坍塌之后导致了滞涨状态。
    比特币专家们认为通缩本身并不坏。更确切地说,我们将通缩与需求坍塌联系在一起是因为过去出现的一个特例。在法币届,货币是有可能被无限制印刷出来的,除非遇到需求完全崩塌并且毫无发行货币意愿的情形,因此经济很难进入滞涨期。而比特币的通缩并不是需求坍塌引起的,它遵循一种预定且有节制的货币供应模型。

去中心化共识

  • 每个全节点依据综合标准对每个交易进行独立验证
  • 通过完成工作量证明算法的验算,挖矿节点将交易记录独立打包进新区块
  • 每个节点独立的对新区块进行校验并组装进区块链
  • 每个节点对区块链进行独立选择,在工作量证明机制下选择累计工作量最大的区块链

    中本聪的主要发明就是去中心化的自发共识机制

交易的独立校验

  • 每一个节点在校验每一笔交易时,都需要对照一个长长的标准列表,这些条件会随着时间发生变化,为了处理新型拒绝服务攻击,有时候也为交易类型多样化而放宽规则
  • 在收到交易后,每一个节点都会在全网广播前对这些交易进行校验,并以接收时的相应顺序,为有效的新交易建立一个池(交易池)。

挖矿节点

在比特币网络中,一些节点被称为专业节点矿工。矿工间的竞争以新区块的传播而结束,如同宣布谁是最后的赢家。对于矿工们来说,获得一个新区块意味着某个参与者赢了,而他们则输了这场竞争。

整合交易至区块

  • 验证交易后,比特币节点会将这些交易添加到自己的内存池中。 内存池也称作交易池,用来暂存尚未被加入到区块的交易记录。与其他节点不同的是,挖矿节点会把这些交易整合到一个候选区块中。
  • 当挖矿结点从比特币网络收到了新区块时,标志着新区块产出竞赛的终结,与此同时也是下一个区块产出竞赛的开始。 节点会检查内存池中的全部交易,并移除已经在新区块中出现过的交易记录,确保任何留在内存池中的交易都是未确认的,等待被记录到新区块中。挖矿节点立刻构建一个新的空区块,做为下一区块的候选区块。称作候选区块是因为它还没有包含有效的工作量证明,不是一个有效的区块,而只有在矿工成功找到一个工作量证明解之后,这个区块才生效。

交易块龄,矿工费和优先级

  • 挖矿节点需要为内存池中的每笔交易分配一个优先级,并选择较高优先级的交易记录来构建候选区块。
  • 交易的优先级是由交易输入所花费的UTXO的“块龄”决定,交易输入值高、“块龄”大的交易比那些新的、输入值小的交易拥有更高的优先级。如果区块中有足够的空间,高优先级的交易行为将不需要矿工费。

    UTXO的“块龄”是自该UTXO被记录到区块链为止所经历过的区块数,即这个UTXO在区块链中的深度。

  • 区块中用来存储交易的前50K字节是保留给较高优先级交易的,不管它们是否包含了矿工费。这种机制使得高优先级交易即便是零矿工费,也可以优先被处理。
  • 然后,挖矿节点会选出那些包含最小矿工费的交易,并按照“每千字节矿工费”进行排序,优先选择矿工费高的交易来填充剩下的区块。

    有些矿工会竭尽全力将那些不含矿工费的交易整合到区块中,而其他矿工也许会选择忽略这些交易。

  • 比特币交易中没有过期、超时的概念,一笔交易现在有效,那么它就永远有效。
    • 如果一笔交易只在全网广播了一次,那么它只会保存在一个挖矿节点的内存中。因为内存池是以未持久化的方式保存在挖矿节点存储器中的,所以一旦这个节点重新启动,内存池中的数据就会被完全擦除。
    • 即便一笔有效交易被传播到了全网,如果它长时间未处理,它将从挖矿节点的内存池中消失。如果交易本应该在一段时间内被处理而实际没有,那么钱包软件应该重新发送交易或重新支付更高的矿工费。

创币交易

  • 每个区块中的第一笔交易是笔特殊交易,称为创币交易或者coinbase交易。这个交易是由挖矿节点构造并用来奖励矿工们所做的贡献的。挖矿节点会创建“向矿工账户地址支付25.09094928个比特币”这样一个交易,把生成交易的奖励发送到自己的钱包。
  • 与常规交易不同,创币交易没有输入,不消耗UTXO。它只包含一个被称作coinbase的输入,仅仅用来创建新的比特币。创币交易有一个输出,支付到这个矿工的比特币地址。

构造区块头

  • 版本(4 字节): 版本号,用来跟踪软件或协议的升级
  • 前区块哈希(32 字节): 链中前一个区块(父区块)的哈希值
  • Merkle根(32 字节): 一个哈希值,表示这个区块中全部交易构成的merkle树的根
  • 时间戳(4 字节): 以Unix纪元开始到当下秒数记录的区块生成的时刻
  • 难度目标(4 bytes): 该区块的工作量证明算法难度目标
  • Nonce(4 bytes): 一个用于工作量证明算法的计数器

    区块头完成全部的字段填充后,挖矿就可以开始进行了。挖矿的目标是找到一个使区块头哈希值小于难度目标的nonce。挖矿节点通常需要尝试数十亿甚至数万亿个不同的nonce取值,直到找到一个满足条件的nonce值。

构建区块

  • 工作量证明算法
    • 用概率的角度来看,如果哈希函数的输出是平均分布的,我们可以期望每16次得到一个以0开头的哈希值。我们每计算一次,nonce加1,成功的nonce为16。这个正确的结果同时也是工作量证明(Proof of Work),因为它证明我们的确花时间找到了这个nonce。验证这个哈希值只需要一次计算,而我们找到它却花了16次。如果目标值更小(难度更大),那我们需要多得多的哈希计算才能找到合适的nonce,但其他人验证它时只需要一次哈希计算。此外,知道目标值后,任何人都可以用统计学来估算其难度,因此就能知道找到这个nonce需要多少工作。
  • 难度表示
    • 难度目标被标为”难度位”或简称”bits”。
    • 计算难度目标的公式为:target = coefficient * 2^(8 * (exponent – 3))

      在区块277,316中,它的值为 0x1903a30c。这个标记的值被存为系数/指数格式,前两位十六进制数字为幂,接下来得六位为系数。在这个区块里,0x19为幂,而0x03a30c为系数。计算结果为 target =0x0000000000000003A30C00000000000000000000000000000000000000000000,也就是说高度为277,316的有效区块的头信息哈希值是小于这个目标值的。在这个难度上,一个每秒可以处理1万亿个哈希计算的矿工(1 tera-hash per second 或 1 TH/sec)平均每8,496个区块才能找到一个正确结果,换句话说,平均每59天,才能为某一个区块找到正确的哈希值。

  • 难度目标与难度调整
    • 难度被设定在,无论挖矿能力如何,新区块产生速率都保持在10分钟一个。
    • 如果网络发现区块产生速率比10分钟要快时会增加难度。如果发现比10分钟慢时则降低难度。
    • 为了防止难度的变化过快,每个周期的调整幅度必须小于一个因子(值为4)。如果要调整的幅度大于4倍,则按4倍调整。
    • 目标难度与交易的数量和金额无关。这意味着哈希算力的强弱,即让比特币更安全的电力投入量,与交易的数量完全无关。

      目标难度和挖矿电力消耗与将比特币兑换成现金以支付这些电力之间的关系密切相关。高性能挖矿系统就是要用当前硅芯片以最高效的方式将电力转化为哈希算力。挖矿市场的关键因素就是每度电转换为比特币后的价格。因为这决定着挖矿活动的营利性,也因此刺激着人们选择进入或退出挖矿市场。

  • 成功构建区块
    • 挖矿节点在求得解后,会将其放入区块头,并立刻将这个区块发给它的所有相邻节点。这些节点在接收并验证这个新区块后,也会继续传播此区块。当这个新区块在网络中扩散时,每个节点都会将它作为新区块加到自身节点的区块链副本中。当挖矿节点收到并验证了这个新区块后,它们会放弃之前对构建这个相同高度区块的计算,并立即开始计算区块链中下一个区块的工作。

校验新区块

  • 比特币共识机制的第三步是通过网络中的每个节点独立校验每个新区块。当新区块在网络中传播时,每一个节点在将它转发到其节点之前,会进行一系列的测试去验证它。这确保了只有有效的区块会在网络中传播。
  • 当一个节点接收到一个新的区块,它将对照一个长长的标准清单对该区块进行验证,若没有通过验证,这个区块将被拒绝。

    矿工们必须构建一个完美的区块,基于所有节点共享的规则,并且根据正确工作量证明的解决方案进行挖矿,他们要花费大量的电力挖矿才能做到这一点。如果他们作弊,所有的电力和努力都会浪费。这就是为什么独立校验是去中心化共识的重要组成部分。

区块链的组装与选择

比特币去中心化的共识机制的最后一步是将区块集合至有最大工作量证明的链中。一旦一个节点验证了一个新的区块,它将尝试将新的区块连接到到现存的区块链,将它们组装起来。

节点维护三种区块:

  • 连接到主链上的
  • 从主链上产生分支的(备用链)
  • 在已知链中没有找到已知父区块的

    在验证过程中,一旦发现有不符合标准的地方,验证就会失败,这样区块会被节点拒绝,所以也不会加入到任何一条链中。

任何时候,主链都是累计了最多难度的区块链。主链也会有一些分支,这些分支中的区块与主链上的区块互为“兄弟”区块。这些区块是有效的,但不是主链的一部分。 保留这些分支的目的是如果在未来的某个时刻它们中的一个延长了并在难度值上超过了主链,那么后续的区块就会引用它们。

区块链分叉

  • 因为区块链是去中心化的数据结构,所以不同副本之间不能总是保持一致。区块有可能在不同时间到达不同节点,导致节点有不同的区块链视角。
  • 每一个节点总是选择并尝试延长代表累计了最大工作量证明的区块链,也就是最长的或最大累计难度的链。只要所有的节点选择最长累计难度的区块链,整个比特币网络最终会收敛到一致的状态。
  • 比特币将区块间隔设计为10分钟,是在更快速的交易确认和更低的分叉概率间作出的妥协。更短的区块产生间隔会让交易清算更快地完成,也会导致更加频繁地区块链分叉。与之相对地,更长的间隔会减少分叉数量,却会导致更长的清算时间。

随机值升位方案

  • 2012年以来,比特币挖矿发展出一个解决区块头基本结构限制的方案。
  • 在比特币的早期,矿工可以通过遍历随机数(Nonce)获得符合要求的hash来挖出一个块。
  • 难度增长后,矿工经常在尝试了40亿个值后仍然没有出块。然而,这很容易通过读取块的时间戳并计算经过的时间来解决。因为时间戳是区块头的一部分,它的变化可以让矿工用不同的随机值再次遍历。当挖矿硬件的速度达到了4GH/秒,这种方法变得越来越困难,因为随机数的取值在一秒内就被用尽了。
  • 当出现ASIC矿机并很快达到了TH/秒的hash速率后,挖矿软件为了找到有效的块,需要更多的空间来储存nonce值。可以把时间戳延后一点,但将来如果把它移动得太远,会导致区块变为无效。区块头需要一个新的“差异性”的信息来源。解决方案是使用coinbase交易作为额外的随机值来源,因为coinbase脚本可以储存2-100字节的数据,矿工们开始使用这个空间作为额外随机值的来源,允许他们去探索一个大得多的区块头值范围来找到有效的块。
  • 如果未来矿工可以尝试所有的可能性,他们还可以通过修改时间戳来解决。同样,coinbase脚本中也有更多额外的空间可以为将来随机数的扩展做准备。

矿池

  • 在这个激烈竞争的环境中,个体矿工独立工作(也就是solo挖矿)没有一点机会。他们找到一个区块以抵消电力和硬件成本的可能性非常小,以至于可以称得上是赌博,就像是买彩票。就算是最快的消费型ASIC也不能和那些在巨大机房里拥有数万芯片并靠近水电站的商业矿场竞争。
  • 现在矿工们合作组成矿池,汇集数以千计参与者们的算力并分享奖励。通过参加矿池,矿工们得到整体回报的一小部分,但通常每天都能得到,因而减少了不确定性。
  • 大部分矿池是“托管的”,意思是有一个公司或者个人经营一个矿池服务器。矿池服务器的所有者叫矿池管理员,同时他从矿工的收入中收取一个百分比的费用。
  • P2P矿池: P2Pool通过将矿池服务器的功能去中心化,实现一个并行的类似区块链的系统,名叫份额链。比起用一个矿池服务器记录矿工的份额和奖励,份额链允许所有矿工通过类似比特币区块链系统的去中心化的共识机制跟踪所有份额。

共识攻击

  • 当一个或者一群拥有了整个系统中大量算力的矿工出现之后,他们就可以通过攻击比特币的共识机制来达到破坏比特币网络的安全性和可靠性的目的。
  • 共识攻击的一个典型场景就是“51%攻击”。由于这群矿工可以生成绝大多数的块,他们就可以通过故意制造块链分叉来实现“双重支付”或者通过拒绝服务的方式来阻止特定的交易或者攻击特定的钱包地址。
  • 为了避免这类攻击,售卖大宗商品的商家应该在交易得到全网的6个确认之后再交付商品。或者,商家应该使用第三方的多方签名的账户进行交易,并且也要等到交易账户获得全网多个确认之后再交付商品。一条交易的确认数越多,越难被攻击者通过51%攻击篡改。

    实际上,算力达到全网的30%就足以发动51%攻击了。之所以命名为51%攻击,只是因为在攻击者的算力达到51%这个阈值的时候,其发起的攻击尝试几乎肯定会成功。


[第9章] 竞争币、竞争块链和应用程序

竞争币和竞争块链的分类

  • 竞争币: 由比特币衍生出来的最常见的形式,就是替代性去中心化货币,简称“竞争币”,这类货币使用跟比特币同样的创建块链的方式来实现自己的电子货币系统。
  • 竞争块链: 通过实现一致性和分布式账簿机制来给诸如合同、名字注册和其他一些应用提供服务。竞争块链使用的是和比特币一样的创建块的机制,有时也会采用货币或代币的支付机制,但它们的主要目的不是为了维持一个货币系统。

元币平台

元币和元块链是在比特币之上实现的软件层,也可以认为是覆盖在比特币系统之上的平台/协议,或者是在一个币中币的实现。这些功能层拓展了核心比特币协议,使得在比特币交易和比特币地址中编码附加信息成为可能。

  • 染色币: 染色币由特殊的钱包管理,这类钱包存储和解析依附在染色币上的元信息。用户在使用这类钱包的时候,可以通过增加有着某种特殊含义的标签的方式,将一般的比特币“染色”为染色币。比如说,这种标签的内容可以表示股票证明、优惠券信息、实际财产、商品或者可收集的代币等等。被染色的比特币也可用通过删除附着信息的方式,也能将“被染色的”比特币恢复为普通比特币。
  • 万事达币: 万事达币是另一个建立在比特币之上的协议,该协议支持多个平台对比特币系统的扩展。万事达币使用名为MST的代币来指导交易,但它并不是一种通货。相反的,它服务于其他应用平台,比如用户货币,智能财产代币,去中心化的财产交易和合约系统等等。就像HTTP协议是TCP协议的应用层一样,Mastercoin是比特币协议的应用层协议。
  • 合约币: 合约币是另一个建立在比特币系统之上的协议层。合约币拥有用户货币、可交易代币、金融手段、去中心化财产交易和其他一些功能。合约币利用比特币脚本语言中的OP_RETURE操作符记录元信息来增加比特币交易的额外信息。合约币使用名为XCP的代币维持整个系统的运行。

竞争币/山寨币

  • 绝大多数的山寨币都来自比特币源代码的克隆,少数则没有使用比特币的任何源码,仅仅是借鉴了块链的模型后自己实现。
  • 大多数的竞争币跟比特币区别非常小,并没有多少研究价值。但在这些通过毫无创意的抄袭和圈钱模式产生的竞争币中间,依然有一些值得一提的非常重要的创新。下面所列出的就是这些竞争币区别于比特币的三点主要不同:
    • 货币策略不同
    • 基于工作量证明的一致性机制不同
    • 一些特殊的功能,比如更强的匿名性等等

评估竞争币的价值

  • 以下是关于竞争币和比特币的不同之处的几个问题
    • 这款竞争币有没有引入重大的创新?
    • 如果有,那么这项创新是不是足够吸引使用比特币的用户转移过来?
    • 这款竞争币是不是致力于某一细分领域或应用?
    • 这款竞争币可以吸引到足够多的矿工来抵御一致性攻击吗?
  • 还有一些有关关键财务和市场指标的问题:
    • 这款竞争币的市场总值是多少?
    • 整个系统的用户/钱包规模大概是多少?
    • 接受其支付的商家有多少?
    • 整个系统每日的交易数是多少?
    • 交易总量是多少?

非货币型竞争区块链

  • 域名币: 域名币是比特币源代码的首个克隆产物,它是一种使用区块链的去中心化平台,用来注册和转让键-值对。
  • Bitmessage: Bitmessage是一个实现了去中心化安全消息服务的比特币竞争币区块链,其本质上是一个无服务器的加密电子邮件系统。Bitmessage可以让用户通过一个Bitmessage地址来编写和发送消息。
  • 以太坊: 以太坊是一种图灵完备的平台,基于区块链账簿,用于合约的处理和执行。它不是比特币的一个克隆,而是完完全全独立的一种设计和实现。以太坊内置一种叫做ether的货币,该货币是付合约执行之费用所必须的。以太坊区块链记录的东西叫做合约,所谓合约,就是一种低级二进制码,也是一种图灵完备语言。本质上,合约其实是运行在以太坊系统中各个节点上的程序。这些程序可以存储数据、支付及收取、存储ether 以及执行无穷范围(因此才叫图灵完备)的计算行为,在系统中充当去中心化的自治软件代理。

加密货币的未来

总体来看,加密货币的未来甚至比比特币还要光明。这是因为,比特币引入了这样一种全新的形式,那就是去中心化的组织和共识,而且这种形式已经催生了大量不可思议的创新。在以前,很多人类活动都需要一个中心化的机构或组织来实现权威或可信控制点的功能,现在,这些都可以去中心化了。区块链和共识系统的发明,还会显著降低大型系统在组织及协调上的花销,同时也将消除权力攫取、腐败及管制俘获的可趁之机。


[第10章] 比特币安全

安全准则

比特币的核心准则是去中心化,这一点对安全性具有重要意义。

  • 比特币这样的去中心化系统则将责任和控制权都移交给了用户。
  • 由于网络的安全性是基于工作量证明而非访问控制,比特币网络可以对所有人开放,也无需对比特币流量进行加密。
  • 一笔比特币交易只授权向指定接收方发送一个指定数额,并且不能被修改或伪造。它不会透露任何个人信息,例如当事人的身份,也不能用于权限外的支付。

在一个传统的支付网络中,它是中心化的。以信用卡系统为例。

  • 支付是终端开放式的,因为它包含了用户的个人标识(信用卡号)。
  • 在初次支付后,任何能获得该标识的人都可以从所有者那里反复“提取”资金。因此,该支付网络必须采取端对端加密的方式,以确保没有窃听者或中间人可以在资金流通或存储过程中将交易数据截获。
  • 当客户数据被泄露时,顾客的个人身份信息将被盗窃者们一览无余。客户这时必须立即采取措施,以防失窃帐户被盗窃者用于欺诈。

    比特币的去中心化安全模型很大程度上将权力移交到用户手上,随之而来的是用户们保管好密钥的责任。这对于大多数用户来说并非一件易事,特别是在像智能手机或笔记本电脑这种能能时刻联网的通用设备上。虽然比特币的去中心化模型避免了常见的信用卡盗用等情况,但很多用户由于无法保管好密钥从而被黑客攻击。

信任根源

  • 传统的安全体系基于一个称为信任根源的概念,它指的总体系统或应用程序中一个可信赖的安全核心。 安全体系像一圈同心圆一样围绕着信任根源来进行开发,像层层包裹的洋葱一样,信任从内至外依次延伸。每一层都构建于更可信的内层之上,通过访问控制,数字签名,加密和其他安全方式确保可信。
  • 在比特币里,共识系统创建了一个可信的完全去中心化的公开账本,一个正确验证过的区块使用创世块作为信任的根源,建立一条直至当前区块的可信任链。

    无数个黑客攻击比特币交易所的例子都是因为轻视了这一点,他们的安全体系和设计甚至无法通过基本的审查。这种中心化的实现方式将信任置于比特币区块链之外的诸多组件之上,例如热钱包,中心化的账本数据库,简易加密的密钥,以及许多类似的方案。

用户最佳安全实践

  • 比特币物理存储: 比特币密钥不过是串长数字而已。这意味着它们可以以物理形式存储起来,如印在纸上或蚀刻成金属硬币上。这样保护密钥就变成了简单地保护印着比特币密钥的物理实体。将比特币离线保存被称为冷存储,它是最有效的安全技术之一。
  • 硬件钱包: 从长远来看,比特币安全将越来越多地以硬件防篡改钱包的形式出现。硬件钱包只提供了有限的接口,从而可以给非专业用户提供近乎万无一失的安全等级。
  • 平衡风险: 数据文件丢失的情况时有发生。为了保护好比特币钱包,用户必须非常注意不要剑走偏锋,这样不至于会搞丢比特币。
  • 分散风险: 用户应该将风险分散到不同类型的比特币钱包。
  • 多重签名管理: 当一个公司或个人持有大量比特币时,他们应该考虑采用多重签名的比特币地址。多重签名比特币地址需要多个签名才能支付,从而保证资金的安全。
  • 存活能力: 一个非常重要却又常常被忽视的安全性考虑是可用性,尤其是在密钥持有者丧失工作能力或死亡的情况下。如果你有很多的比特币,你应该考虑与一个值得信赖的亲属或律师分享解密的细节。一个更复杂的比特币生还计划,可以通过设置多重签名,做好遗产规划,并通过专门的“数字资产执行者”律师处理后事。