《精通比特币》学习笔记

区块链是比特币的底层技术,要学习区块链首先要学习比特币,作为最好的比特币入门书《精通比特币》是必看书名。本文是作者个人学习此书对重点内容的摘抄,仅供参考。

核心知识点

1. 简介
1.1 比特币
比特币是一种虚拟的数字货币,没有实体的存在,它藏匿于一个历史交易账本里,比特币的拥有者通过密钥实现对比特币的交易使用。总体来说比特币由这些构成:
 一个去中心化的点对点网络(比特币协议)
此网络存在于互联网基础之上的P2P网络,允许任何点随时加入或退出此网络。
 一个公共的交易账簿(区块链)
此账本是用hash值把存放交易记录的数据块串联起来的链式结构,记录到账本上的数据无法篡改。
 一个去中心化的数学的和确定性的货币发行(分布式挖矿)
比特币的发行是通过“挖矿”这个操作来实现的,挖矿的本质就是在一组规则下竞争对下一个块的记账权,谁率先实现了要求的计算,谁就可以获得本次挖矿产生的比特币。每隔10分钟会产生一次记账权,每四年单次记账的比特币奖励会减半,预计2140年近乎达到全部的2100万个比特币全部被发行完成。
 一个去中心化的交易验证系统(交易脚本)。
比特币官方地址:https://bitcoin.org/zh_CN
比特币github地址:https://github.com/bitcoin/bitcoin
比特币开发者文档:https://bitcoin.org/en/developer-documentation
1.2 比特币客户端和钱包
如果说比特币是钱的话,你的钱包地址就是你的银行卡号,不论是别人给你汇钱,还是你给别人汇钱,都需要用到这个地址。
 完整客户端(如官方的bitcoin core):记录了全部交易数据;
 轻量级客户端(如官方electrum);
 在线客户端(如blockchain);
 移动客户端(如比特派)

比特币钱包基本功能:
 生成比特币地址
 接收比特币
 发出比特币
 生成并导出私钥
 对自己的每笔交易,进行签名核实
 保护你的资产

2. 比特币原理
2.1 交易
常见的区块链数据查询网站包括:
blockchain https://blockchain.info/
Bitcoin Block Explorer https://blockexplorer.com/
insight https://insight.bitpay.com/
blockr Block Reader
提交交易===》传播和验证===》查询==》消费

发送方通过钱包输入目的地址和要转的比特币数
===》钱包查询本地或者网络上的与钱包内的地址相关的UTXO(未消费交易输出)并组合出交易信息(交易的输出部分是一段脚本)
===》几秒之内交易信息就达到全网推送
==》接收方的钱包会验证此交易是否是合理的(输入是“未消费交易输出”,输出是自己的私钥可以兑换的,交易费用是合理的)即可认可缴费成功(很大概率成功,因是小消费几乎不用担心交易不被写入区块链)。

挖矿:使用hash256算法对区块头+一个随机数计算hash值,直到结果达到预设的解(前X为为0),第一个找的满足条件的随机数的矿工获胜,并把此新区块发布到全网络。

3. 比特币客户端
主要讲了bitcoin.org的比特币标准客户端,也叫“中本聪客户端”。它实现了比特币的所有方面,包括钱包、整个区块链完整的数据拷贝,是比特币网络的一个完整节点。
本章重点讲解了bitcoin的核心命令,包括钱包、交易、区块、utxo等方面的命令。
除了bitcoin之外还有其他客户端或程序库:bitcoinj(java语言)、btcd(go语言)、pycoin(python语言);除了这些客户端,可以调用类似https://blockchain.info/的查询网站的api接口。

  1. 秘钥地址钱包
    私钥、公钥和比特币地址的一一对应关系:

4.1 私钥、公钥:
随机选取的256位的二进制数(64位的16进制数);私钥制造签名,让大家用来判断特定的比特币地址里的钱是此人的。比特币备份就是要备份私钥,因为私钥可以产生公钥和地址。私钥丢失意味着此地址里的比特币也丢失。钱包里面生成一个新地址就对应有一个私钥和公钥,默认只显示公钥而已。
公钥由私钥通过椭圆曲线乘法得到(大多数的比特币程序都是通过openssl加密库进行椭圆曲线计算),反向不可逆,即不可有公钥计算得到私钥。
4.2 比特币地址:
Bitcoin地址的生成:

地址 = base58( [prefix] + [hash160(公钥)] + [checksum] )
其中,[prefix]1个字节,用于区分不同的网络,如0代表bitcoin的主网络main, 111代表testnet等。base58编码实际上就是对一个大整数反复除以58,依次记录余数所对应的base58字符,最后将这些字符逆序,生成一个字符串。不同网络的[prefix]不同,所以地址首位不同:
 主网络中,[prefix]为0时,除至最后的余数必为0, 对应的base58编码为’1’, 所以常规地址的首位一定是’1’.
 testnet中,[prefix]为111, 除至最后的余数为44或45, 对应的base58编码为’m’或’n’, 因此testnet网络的地址首位是‘m’或’n’。
 多重签名地址用的是script hash, [prefix]为5,base58编码后,地址首位为’3’。
比特币btc地址开头总是1,长度27位到34位。
域名币nmc地址开头是M或者N,长度34位。
莱特币ltc地址开头总是L,长度34位。
软妹币ssc地址开头是R或者S,长度34位。
4.3 秘钥的编码和压缩
4.4 编码格式
公钥和私钥都有各种编码格式,主要是方便人工阅读;但是他们对应的256位的数字是一样的,他们之间很容易被相互转换。举例:
Hex 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD
WIF 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn
WIF-compressed KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ

4.5 公钥的压缩和非压缩:
公钥是在椭圆曲线上的一个点,由一对坐标(x,y)组成。公钥通常表示为520位的数字:前缀04 紧接着两个256 比特的数字。其中一个256 比特数字是公钥的x 坐标,另一个256 比特数字是y 坐标。前缀04 表示非压缩格式。
因为有x可以通过解方程获得y的坐标,所以压缩格式只存储x,以02或者03开头+256位的x的值;(02表示偶数、负数;03表示奇数、正数)。

对于同一个私钥,因公钥有两种表示(他们对应的数字不一样),相应得到的地址也不一样。目前大部分的比特币客户端逐渐采用压缩格式,但要解决之前旧的版本的钱包产生的非压缩格式的公钥对应的地址的识别问题。于是出现了“钱包导入格式”WIF(wallet Import Format)。
WIF的私钥是说私钥后面加上后缀01,由此私钥只能生成压缩格式的公钥。当从一个实现了压缩格式公钥的比特币钱包导出私钥时,钱包导入格式(WIF)将会被修改为WIF 压缩格式,该格式将会在私钥的后面附加一个字节大小的后缀01。最终的Base58Check 编码格式的私钥被称作WIF(“压缩”)私钥,以字母“K”或“L”开头。而以“5”开头的是从较老的钱包中以WIF(非压缩)格式导出的私钥。格式举例:
Hex 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD
WIF 5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn
Hex-compressed 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD01
WIF-compressed KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ

4.6 比特币钱包
比特币钱包只包含私钥而不是比特币。每一个用户有一个包含多个私钥的钱包。钱包中包含成对的私钥和公钥。用户用这些私钥来签名交易,从而证明它们拥有交易的输出(也就是其中的比特币)。比特币是以交易输出的形式来储存在区块链中(通常记为vout 或txout)。
非确定性钱包(随机钱包):
早起比特币客户端中随机生成多个相互没有关系的私钥,需要全部备份,不利不利于隐私保护。
确定性钱包(种子钱包):
通过单向离散方程从共同的种子种生成私钥,用种子可以回收所有已经产生的钱包,因此备份容易。
助记码():
用一组12-24个有顺序的单词当钱包的备份;BIP0039 定义助记码和种子的创建过程如下:
1.创造一个128 到256 位的随机顺序(熵)。
2.提出SHA256 哈希前几位,就可以创造一个随机序列的校验和。
3.把校验和加在随机顺序的后面。
4.把顺序分解成11 位的不同集合,并用这些集合去和一个预先已经定义的2048个单词字典做对应。
5.生成一个12 至24 个词的助记码。
举例:
负熵输入(128bits) 0c1e24e5917779d297e14d45f14e1a1a
助记码(12 个单词) army van defense carry jealous true garbage claim echo media make crunch
种子(512 bits) 3338a6d2ee71c7f28eb5b882159634cd46a898463e9d2d0980f8e80dfbba5b0fa0291e5fb88

什么是HD钱包:http://8btc.com/article-2020-1.html
分层确定性(Hierarchical Deterministic)钱包,原理:
 首先,要用一个随机数来生成主(根)私钥,这和任何一个比特币钱包生成任何一个私钥没任何区别;
 然后,再用一个确定的、不可逆的算法,基于主私钥生成任意数量的子私钥;

HD 钱包全称为 分层确定性 (Hierarchical Deterministic) 比特币钱包
相比传统的比特币钱包,HD钱包提供了一些好处:
备份更容易
传统钱包的问题是一个钱包可能存有一堆密钥地址,每个地址都有一些比特币。这样备份钱包的时候,需要备份所有的密钥。但如果之后生成了一个新地址,你就需要重新备份一次。事实上,每次生成新地址的时候,你都需要做一次备份。 HD钱包允许你从一个主(根)密钥创建海量的子密钥。这意味着,一旦你控制了主密钥,你就可以生成所有的子密钥,主密钥和子密钥形成树状结构。所以你就不需要频繁的备份钱包,你只需要在创建钱包的时候备份一次就可以了,因为你可以从主密钥重新创建所有的子密钥。
私钥离线存放更安全
HD钱包还带来了一些新特性,比如不需要任何私钥,就可以从一个父公钥生成所有的子公钥。具体来说,你的主私钥是以纸钱包的方式备份的,并且离线存放在一个安全的地方。你手头有主公钥,用这个公钥,你就可以生成所有的子公钥。 举个实际的例子,我们要开一个网店,接受比特币付款。你可以离线存放你的私钥,只把公钥放在公网的服务器上。你的网站可以使用这个公钥为网站上的每一个商品生成一个收款地址,或者给你的每个顾客生成一个唯一的地址,甚至为每次交易生成一个地址(如何使用,取决于你的想象)。 并且因为私钥是离线存放的,没人可以黑进你的服务器偷走比特币。
权限控制
HD钱包有个额外好处,它让你可以控制你的组织里谁可以控制哪些密钥。 和一个商业组织的组织结构类似,HD钱包也是以树形结构组织密钥的。你可以给你的组织里的每个分支部门创建密钥,把私钥交给这个分支部门,这个部门就可以花它的分支上的币,而你,因为有主私钥,所以你可以看到并花费整个树上的币。
记账
想让会计看到所有的交易,但不想让他花你的钱?没问题,你可以给他任何一级上的公钥,他就可以看到该级下的所有交易,并且不能花任何的币。
4.7 高级秘钥和地址
私钥加密:备份钱包主要是备份私钥,但为安全备份的私钥也要加密一般用AES加密。
纸钱包和加密纸钱包:把私钥打印到纸张上,保证私钥再互联网上没有。
P2SH和多重签名地址:以1开头的地址的主人是秘钥的所有者;以3位开头的地址是P2SH地址(pay to script hash),多用于多重签名地址。
比特币靓号:开头等位置含义可读信息的比特币地址。生成一个靓号地址是一项通过蛮力的过程:尝试一个随机密钥,检查结果地址是否符合要求,重复这个过程直到成功找到为止。超过七个字符的靓号地址一般需要专用硬件来生成。

5. 交易
5.1 概述
比特币交易是比特币系统中最重要的部分。根据比特币系统的设计原理,系统中任何其他的部分都是为了确保比特币交易可以被生成、能在比特币网络中得以传播和通过验证,并最终添加入全球比特币交易总账簿(比特币区块链)。比特币交易的本质是数据结构,这些数据结构中含有比特币交易参与者价值转移的相关信息。一张支票是指定一个特定账户作为资金来源的,但是比特币交易指定以往的一笔交易作为其资金来源,而不是一个特定账户。由于这笔交易是经过签名且不含任何机密信息、私钥或密码,因此它可被任何潜在的便利网络公开地传播。信用卡交易包含敏感信息,而且依赖加密网络连接完成信息传输,但比特币交易可在任意网络环境下被发送。在几秒钟之内,一笔有效的交易就会像指数级扩散的波一样在网络中传播,直到所有连接到网络的节点都接收到它。

  1. 交易锁定时间
    交易的锁定时间定义了能被加到区块链里的最早的交易时间。在大多数交易里,它被设置成0,用来表示立即执行;如果锁定时间不是0 并且小于5 亿,就被视为区块高度;如果锁定时间大于5 亿,则它被当作是一个Unix 纪元时间戳。

  2. UTXO (未经使用的交易输出)
    是不能再分割、被所有者锁住或记录于区块链中的并被整个网络识别成货币单位的一定量的比特币货币。实际上并不存在储存比特币地址或账户余额的地点,只有被所有者锁住的、分散的UTXO。比特币钱包通过扫描区块链并聚合所有属于该用户的UTXO 来计算该用户的余额。在比特币的世界里既没有账户,也没有余额,只有分散到区块链里的UTXO。一个UTXO 可以是一“聪”的任意倍。被交易消耗的UTXO 被称为交易输入,由交易创建的UTXO 被称为交易输出。通过这种方式,一定量的比特币价值在不同所有者之间转移,并在交易链中消耗和创建UTXO。一笔比特币交易通过使用所有者的签名来解锁UTXO,并通过使用新的所有者的比特币地址来锁定并创建UTXO。给某人发送比特币实际上是创造新的UTXO,注册到那个人的地址。UTXO 被每一个全节点比特币客户端在一个储存于内存中的数据库所追踪,该数据库也被称为“UTXO 集”或者“UTXO 池”。
    查询某地址相关的UTXO:https://blockchain.info/unspent?active=1Dorian4RoXcnBv9hnQ4Y2C1an6NJ4UrjX

  3. coinbase 交易:
    这是每个区块中的首个交易。这种交易存在的原因是作为对挖矿的奖励而产生全新的可用于支付的比特币给“赢家”矿工。

  4. 交易费
    当作是为了包含(挖矿)一笔交易到下一个区块中的一种鼓励,也可当作是对于欺诈交易和任何种类的系统滥用。交易费将提高处理优先级,没有交易费的交易可能被记录,也可能永远不会被记录。交易的数据结构没有交易费的字段,交易费= 求和(所有输入) - 求和(所有输出)。钱包应用会通过测量交易的大小,乘以每千字节需要的交易费,来计算适当的交易费。
  5. 孤立交易池
    当一条交易链被整个网络传送时,他们并不能总是按照相同的顺序到达目的地。节点会首先收到一个子交易,而不能找到他参考的父交易,节点不会立即抛弃这个子交易,而是放到一个临时池中,并等着接收它的父交易,与此同时广播这个子交易给其他节点。如果池中的孤立交易数量达到了MAX_ORPHAN_TRANSACTIONS,一个或多个的、被随机选出的孤立交易会被池抛弃,直到池的大小回到限制以内。

5.2 脚本概述
比特币脚本是一种基于逆波兰表示法的基于堆栈的执行语言。堆栈允许两类操作:推送和弹出。数字(常数)被推送至堆栈,操作符向堆栈推送(或移除)一个或多个参数,对它们进行处理向堆栈推送一个结果,最终产生一个真或假的结果。
下面是脚本“2 3 OP_ADD 5 OP_EQUAL”的执行过程:

比特币脚本语言包含许多操作,但都故意限定为一种重要的方式——没有循环或者复杂流控制功能以外的其他条件的流控制。这样就保证了脚本语言的图灵非完备性,这意味着脚本的复杂性有限,交易可执行的次数也可预见。
每一个比特币客户端会通过执行锁定和解锁脚本来验证一笔交易,在脚本验证之前将解锁脚本和锁定脚本串联而成的组合脚本举例:

锁定脚本是放输出上的,指出了花费此输出的条件。锁定脚本一般和一个接收地址或公钥有关,因此又称为脚本公钥代码。解锁脚本是针对一个锁定脚本提供的一个解,一般含义此用户的私钥生成的数字签名,因此曾被称为ScriptSig。举例:锁定脚本:3 OP_ADD 5 OP_EQUAL ,则解锁脚本为:2
5.3 五大标准脚本
P2PKH、P2PK、多重签名MS(限15 个密钥)、P2SH 和OP_Return。
1. P2PKH(Pay-to-Public-Key-Hash):
锁定脚本:OP_DUP OP_HASH160 OP_EQUAL OP_CHECKSIG
解锁脚本:

  1. P2PK(Pay-to-Public-Key):
    相比P2PKH,公钥本身已经存储在锁定脚本中,目前在coinbase交易中常见。
  2. 多重签名
    在脚本中的公钥个数为N,则至少需提供其中的M 个公钥才可以解锁。通用的M-N 多重签名锁定脚本形式为:M N OP_CHECKMULTISIG

  3. 数据输出(OP_RETURN 操作符)
    用比特币存储做电子存证,部分人反对,因为这是伪交易,不能被消费,讲永远占据UTXO集。在0.9 版的比特币核心客户端上,通过采用OP_Return 操作符最终实现了妥协,允许在输出中增加40个字节的非交易输出,并不存储在UTXO集中。。OP_RETURN 常为一个金额为0 的比特币输出,因为任何与该输出相对应的比特币都会永久消失。一笔标准交易(通过了isStandard()函数检验的)只能有一个OP_RETURN输出。但是单个OP_RETURN 输出能与任意类型的输出交易进行组合。

  4. P2SH(Pay-to-Script-Hash)
    针对多重签名,如果锁定脚本使用之前的方式,则会非常长,P2SH不在存储这些脚本,而是存储这些脚本的hash值,而接收方需要提供哈希值一致的锁定脚本,以及相应的解锁脚本。
     锁定脚本:
    OP_HASH160 54c557e07dde5bb6cb791c7a540e0a4796f5e97e OP_EQUAL
     对应的解锁脚本:
    Sig1 Sig2

与直接使用复杂脚本以锁定输出的方式相比,P2SH 具有以下特点:
 在交易输出中,复杂脚本由简短电子指纹取代,使得交易代码变短。
 脚本能被编译为地址,支付指令的发出者和支付者的比特币钱包不需要复杂
 工序就可以执行P2SH。
 P2SH 将构建脚本的重担转移至接收方,而非发送方。
 P2SH 将长脚本数据存储的负担从输出方(存储于UTXO 集,影响内存)转移至输入方(仅存储于区块链)。
 P2SH 将长脚本数据存储的重担从当前(支付时)转移至未来(花费时)。

基于Base58 编码的P2SH地址以“3”开头,以“3”为前缀给予客户这是一种特殊类型的地址的暗示,该地址与一个脚本相对应而非与一个公钥相对应,但是它的效果与比特币地址支付别无二致。

6. 网络
6.1 概述
比特币采用了基于国际互联网(Internet)的P2P(peer-to-peer)网络架构。P2P 协议之外,比特币网络中也包含其他协议。例如Stratum 协议就被应用于挖矿、以及轻量级或移动端比特币钱包之中。我们使用“扩展比特币网络(extended bitcoin network)”指代所有包含比特币P2P 协议、矿池挖矿协议、Stratum 协议以及其他连接比特币系统组件相关协议的整体网络结构。

6.2 节点类型及分工
一个全节点(full node)包括四个完整功能的比特币网络节点:钱包、矿工、完整区块链、网络路由节点:

一些节点只保留了区块链的一部分,它们通过一种名为“简易支付验证(SPV)”的方式来完成交易验证。这样的节点被称为“SPV 节点”,又叫“轻量级节点”。

6.3 网络发现
节点通常采用TCP 协议、使用8333 端口(该端口号通常是比特币所使用的,除8333 端口外也可以指定使用其他端口)与已知的对等节点建立连接。由于节点可以随时加入和离开,通讯路径是不可靠的。因此,节点必须持续进行两项工作:在失去已有连接时发现新节点,并在其他节点启动时为其提供帮助。节点启动时只需要一个连接,因为第一个节点可以将它引荐给它的对等节点,而这些节点又会进一步提供引荐。一个节点,如果连接到大量的其他对等节点,这既没必要,也是对网络资源的浪费。在启动完成后,节点会记住它最近成功连接的对等节点。
如果已建立的连接没有数据通信,所在的节点会定期发送信息以维持连接。如果节点持续某个连接长达90 分钟没有任何通信,它会被认为已经从网络中断开,网络将开始查找一个新的对等节点。

6.4 区块的同步
对等节点们会交换一个getblocks 消息,其中包含他们本地区块链的顶端区块哈希值。如果某个对等节点识别出它接收到的哈希值并不属于顶端区块,而是属于一个非顶端区块的旧区块,那么它就能推断出:其自身的本地区块链比其他对等节点的区块链更长。拥有更长区块链的对等节点会识别出第一批可供分享的500 个区块,通过使用inv(inventory)消息把这些区块的哈希值传播出去。
缺少数据块的节点收到了来自对等节点的inv 消息,其中包含了区块链中后500 个区块的哈希值。于是它开始向所有与之相连的对等节点请求区块,并通过分摊工作量的方式防止单一对等节点被批量请求所压垮。

6.5 简易支付验证(SPV)节点(SPV 客户端或轻量级客户端)
SPV 节点只需下载区块头,而不用下载包含在每个区块中的交易信息。由此产生的不含交易信息的区块链,大小只有完整区块链的1/1000。
完整节点因为有全部交易数据,可以独立验证某个交易的花销是否在之前的UTXO中。但spv节点自己没有完整交易数据,所有只能靠看其他节点是否都认可它就跟着认可,即看此交易的merkel数和块工作量证明的正确后,再看是否有至少6个区块已经链接到此区块的后面了。
6.6 Bloom 过滤器,
用以解决SPV 节点的隐私风险问题。Bloom 过滤器通过一个采用概率而不是固定模式的过滤机制,允许SPV 节点只接收交易信息的子集,同时不会精确泄露哪些是它们感兴趣的地址。
SPV 节点会初始化一个不会匹配任何关键词的“空白”Bloom 过滤器。接下来,SPV 节点会创建一个包含钱包中所有地址信息的列表,并创建一个与每个地址相对应的交易输出相匹配的搜索模式。
用一个小型的十六位数组和三个哈希函数来演示Bloom过滤器的应用原理。

随后,SPV 节点会向对等节点发送一条包含需在该连接中使用的过滤器的filterload 消息。当过滤器建好之后,对等节点将每个交易的输出值代入过滤器中验证。那些正匹配(hash后的位置为1的表示匹配,不唯一的舍弃)的交易会被传送回SPV 节点。为回应来自SPV 节点的getdata 信息,对等节点会发出一条只含有和过滤器匹配的区块的区块头信息,以及与之相匹配的交易的merkle 树。这一对等节点还会发出一条相匹配的交易的tx 消息。
6.7 交易池
比特币网络中几乎每个节点都会维护一份未确认交易的临时列表,被称为内存池或交易池。节点们利用这个池来追踪记录那些被网络所知晓、但还未被区块链所包含的交易。如果一个交易的输入与某未知的交易有关,如与缺失的父交易相关,该孤立交易就会被暂时储存在简易支付验证(SPV) 中直到父交易的信息到达。当一个交易被添加到交易池中,会同时检查孤立交易池,看是否有某个孤立交易引用了此交易的输出(子交易)。任何匹配的孤立交易会被进行验证。如果
验证有效,它们会从孤立交易池中删除,并添加到交易池中,使以其父交易开始的链变得完整。交易池和孤立交易池(如有实施)都是存储在本地内存中,并不是存储在永久性存储设备(如硬盘)里。UTXO 池可能会被安置在本地内存,或者作为一个包含索引的数据库表安置在永久性存储设备中。交易池和孤立交易池代表的是单个节点的本地视角。取决于节点的启动时间或重启时间,不同节点的两池内容可能有很大差别。相反地,UTXO 池代表的是网络的突显共识,因此,不同节点间UTXO 池的内容差别不大。此外,交易池和孤立交易池只包含未确认交易,而UTXO 池之只包含已确认交易。
???父交易和子交易可以存在于同一个区块里吗?
6.8 警告消息
警告消息并不经常使用,但在大多数节点上都有此功能。警告消息是比特币的“紧急广播系统”,比特币核心开发人员可以借此功能给所有比特币节点发送紧急文本消息。这一功能是为了让核心开发团队将比特币网络的严重问题通知所有的比特币用户,例如一个需要用户采取措施的的严重bug。警告系统迄今为止只被用过几次,最严重的一次是在2013 年,一个关键的数据库缺陷导致比特币区块链中出现了一个多区块分叉。警告通过公钥进行加密签名。对应的私钥是由核心开发团队的一些特定成员所持有。这样的数字签名可以确保虚假警告不会在网络中传播。收到警告消息的节点会验证该消息,检查是否过期,并传播给其所有对等节点,从而保证了整个网络中的快速传播。

7. 区块链
7.1 简介
比特币核心客户端使用Google 的LevelDB 数据库存储区块链元数据。“高度”来表示区块与首区块之间的距离;以及“顶部”或“顶端”来表示最新添加的区块。虽然每个区块只有一个父区块,但可以暂时拥有多个子区块。一个区块出现多个子区块的情况被称为“区块链分叉”。 超过这六块后,区块在区块链中的位置越深,被改变的可能性就越小。在100 个区块以后,区块链已经足够稳定,这时coinbase 交易(包含新挖出的比特币的交易)可以被支付。几千个区块(一个月)后的区块链将变成确定的历史,永远不会改变。

7.2 区块结构
区块头机构表:
大小 字段 描述
4 字节 版本版本号, 用于跟踪软件/协议的更新
32 字节 父区块哈希值 引用区块链中父区块的哈希值
32 字节 Merkle 根 该区块中交易的merkle 树根的哈希值
4 字节 时间戳 该区块产生的近似时间(精确到秒的Unix 时间戳)
4 字节 难度 目标该区块工作量证明算法的难度目标
4 字节 Nonce 用于工作量证明算法的计数器

7.3 区块标识符:区块头哈希值和区块高度
通过SHA256 算法对区块头进行二次哈希计算而得到的32位的数字指纹,区块哈希值实际上并不包含在区块的数据结构里,只在子块的头里面有父块的哈希值,因为且任何节点通过简单地对区块头进行哈希计算都可以独立地获取该区块哈希值,没有必要进行额外存储。
创世区块的哈希值为:
000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
https://blockchain.info/block/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
https://blockexplorer.com/block/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

创世区块在其Coinbase 交易的输入中包含这样一句话“The Times 03/Jan/2009 Chancellor on brink of second bailoutforbanks.” 2009年1月3日,财政大臣正站在第二轮救助银行业的边缘。
7.4 区块的链接

7.5 Merkle 树
Merkle 树是一种哈希二叉树,它是一种用作快速归纳和校验大规模数据完整性的数据结构。因为Merkle 树是二叉树,所以它需要偶数个叶子节点。如果仅有奇数个交易需要归纳,那最后的交易就会被复制一份以构成偶数个叶子节点,这种偶数个叶子节点的树也被称为平衡树。

HA = SHA256(SHA256(交易A))
HAB = SHA256(SHA256(HAHB))
此图中只需要知道四个蓝色的值就可以判断绿色HK是否在此交易树中。当N 个数据元素经过加密后插入Merkle 树时,你至多计算2*log2(N)次就能检查出任意某数据元素是否在该树中, Merkle 树是自底向上构建的。
7.6 Merkle 树和简单支付验证(SPV)
Merkle 树被SPV 节点广泛使用。SPV 节点不保存所有交易也不会下载整个区块,仅仅保存区块头。它们使用认证路径或者Merkle 路径来验证交易存在于区块中,而不必下载区块中所有交易。
一个SPV 节点欲知它钱包中某个比特币地址即将到达的支付,该节点会在节点间的通信链接上建立起bloom 过滤器,限制只接受含有目标比特币地址的交易。Merkle 区块消息包含区块头和一条连接目标交易与Merkle 根的Merkle 路径。

8. 挖矿与共识
8.1 简介
挖矿是新比特币发行的过程,也是避免双重支付保护比特币安全的过程,还是奖励矿工维持比特币良好生态的过程。矿工可以获得两种类型的奖励:创建新区块的新币奖励,以及区块中所含交易的交易费。
每个区块大约用时10分钟,每经过21万个区块(大约四年)奖励就会减半。预计2140年大约2100万个区块会被挖掘完成,不在生成新的比特币(再生成奖励就会小于1聪了),矿工的挖矿动力将会来自交易费。
8.2 共识机制
共识是数以千计的独立节点遵守了简单的规则通过异步交互自发形成的产物。比特币的去中心化共识由所有网络节点的4 种独立过程相互作用而产生:
▷ 交易验证:每个全节点依据综合标准对每个交易进行独立验证。
▷ 工作量证明:通过完成工作量证明算法的验算,挖矿节点将交易记录独立打包进新区块
▷ 新区快的验证:每个节点独立的对新区块进行校验并组装进区块链
▷ 区块的分叉处理:每个节点对区块链进行独立选择,在工作量证明机制下选择累计工作量最大的区块链。
8.3 第一步:收集交易(交易的验证)
每一个节点在校验每一笔交易时,都需要对照一个长长的标准列表:
▷交易的语法和数据结构必须正确。
▷输入与输出列表都不能为空。
▷交易的字节大小是小于MAX_BLOCK_SIZE 的。
▷每一个输出值,以及总量,必须在规定值的范围内(小于2,100 万个币,大于0)。
▷没有哈希等于0,N 等于-1 的输入(coinbase 交易不应当被中继)。
▷nLockTime 是小于或等于INT_MAX 的。
▷交易的字节大小是大于或等于100 的。
▷交易中的签名数量应小于签名操作数量上限。
▷解锁脚本(scriptSig)只能够将数字压入栈中,并且锁定脚本(scriptPubkey)
必须要符合isStandard 的格式(该格式将会拒绝非标准交易)。
▷池中或位于主分支区块中的一个匹配交易必须是存在的。
▷对于每一个输入,如果引用的输出存在于池中任何的交易,该交易将被拒绝。
▷对于每一个输入,在主分支和交易池中寻找引用的输出交易。如果输出交易缺
少任何一个输入,该交易将成为一个孤立的交易。如果与其匹配的交易还没有出
现在池中,那么将被加入到孤立交易池中。
▷对于每一个输入,如果引用的输出交易是一个coinbase 输出,该输入必须至
少获得COINBASE_MATURITY (100)个确认。
▷对于每一个输入,引用的输出是必须存在的,并且没有被花费。
▷使用引用的输出交易获得输入值,并检查每一个输入值和总值是否在规定值的范围内(小于2100 万个币,大于0)。
▷如果输入值的总和小于输出值的总和,交易将被中止。
▷如果交易费用太低以至于无法进入一个空的区块,交易将被拒绝。
▷每一个输入的解锁脚本必须依据相应输出的锁定脚本来验证。
这些条件能够在比特币标准客户端下的AcceptToMemoryPool、CheckTransaction 和CheckInputs 函数中获得更详细的阐述
8.4 第二步:准备备选区块(常规交易部分)
备选区块有三部分组成:
第一部分:50k的高优先级区块。
挖矿节点会为每个交易计算一个优先级,公式如下:交易的比特数(聪) * 输入UTXO的深度值 / 区块的大小 ;一般交易1比特,深度超过144个(1天前的交易),区块256字节的交易优先级比较高。及时这样的交易没有交易费也可能被记录。
第二部分:性价比高的交易。
安装千字节交易费进行排序,高的有限被选中;
第三部分:没有交易费的交易
在第二部分没有达到MAX_BLOCK_SIZE的情况下可能会被包含进去。
备注:交易不会过期,随着时间的推移,交易的优先级会变高,如果高到进入前50k,即使没有交易费和会被包含到新区块中。如果长时间没有被记录,钱包可以重新发出高交易费的交易申请。
8.5 第二步:准备备选区块(coinbase 交易部分)
与常规交易不同,创币交易没有输入,不消耗UTXO。它只包含一个被称作coinbase 的输入,仅仅用来创建新的比特币。创币交易有一个输出,支付到这个矿工的比特币地址,支付金额=新区块奖励值+本区块交易费用收益值。交易结构对比:

8.6 第二步:准备备选区块(区块头部分)
难度目标,其被标为”难度位”或简称”bits”。在区块277,316 中,它的值为0x1903a30c。在这个区块里,0x19 为幂,而0x03a30c 为系数。转化为十六进制后为:
target =0x0000000000000003A30C0000000000000000000000000000000000
0000000000 。这个数字的二进制表示中前60 位都是0 难度被设定在,无论挖矿能力如何,新区块产生速率都保持在10 分钟一个。难度的调整公式是由最新2,016 个区块的花费时长与20,160 分钟(两周,即这些区块以10 分钟一个速率所期望花费的时长)比较得出的。New Difficulty = Old Difficulty * (Actual Time of Last 2016Blocks / 20160 minutes) 为了防止难度的变化过快,每个周期的调整幅度必须小于一个因子(值为4)。如果要调整的幅度大于4 倍,则按4 倍调整。由于在下一个2,016 区块的周期不平衡的情况会继续存在,所以进一步的难度调整会在下一周期进行。因此平衡哈希计算能力和难度的巨大差异有可能需要花费几个2,016 区块周期才会完成。
8.7 第三步:挖矿
挖矿节点在竞争新区块的工作量证明的同时,也在时刻监听着网络中是否新区块被计算出,并接受着新的交易并放到交易池中。如果新区块产生,挖矿节点把新区块链入本地链,并过滤交易池里已经被包含过的交易,把剩下的交易组织到下一个本地备选区块中,继续下一轮的竞争。
8.8 第四步:新区块的传播和验证
这些标准可以在比特币核心客户端的CheckBlock 函数和CheckBlockHead 函数中获得,它包括:
▷ 区块的数据结构语法上有效
▷ 区块头的哈希值小于目标难度(确认包含足够的工作量证明)
▷ 区块时间戳早于验证时刻未来两个小时(允许时间错误)
▷ 区块大小在长度限制之内
▷ 第一个交易(且只有第一个)是coinbase 交易
▷ 使用检查清单验证区块内的交易并确保它们的有效性
8.9 第五步:区块链分叉

从理论上来说,两个区块的分叉是有可能的,这种情况发生在因先前分叉而相互对立起来的矿工,又几乎同时发现了两个不同区块的解。然而,这种情况发生的几率是很低的。单区块分叉每周都会发生,而双块分叉则非常罕见。
比特币将区块间隔设计为10 分钟,是在更快速的交易确认和更低的分叉概率间作出的妥协。更短的区块产生间隔会让交易清算更快地完成,也会导致更加频繁地区块链分叉。与之相对地,更长的间隔会减少分叉数量,却会导致更长的清算时间。
8.10 挖矿和算力竞赛
现在的竞争已经不再是比较单一芯片的能力,而是一个矿场能塞进多少芯片,并处理好散热和供电问题。
随着算力的增大,nonce值查找更快了,导致找到很大的nonce也没满足,这时候可以更改coinbase交易引起merkel树根变化,或者修改时间戳,从而又可以重新从1开始试nonce的取值。
8.11 矿池
矿池如何衡量每个人的贡献,既能公平分配奖励,又避免作弊的可能?答案是在设置一个较低难度的前提下,使用比特币的工作量证明算法来衡量每个矿工的贡献。因此,即使是池中最小的矿工也经常能分得奖励,这足以激励他们为矿池做出贡献。通过设置一个较低的取得份额的难度,矿池可以计量出每个矿工完成的工作量。每当矿工发现一个小于矿池难度的区块头hash,就证明了它已经完成了寻找结果所需的hash 计算。
矿池服务器通过聚集交易,添加coinbase 交易(和额外的随机值空间),计算MERKLE 根,并连接到上一个块hash 来建立一个候选区块。这个候选区块的头部作为模板分发给每个矿工。矿工用这个区块模板在低于比特币网络的难度下采矿,并发送成功的结果返回矿池服务器赚取份额。
P2Pool 是一个点对点的矿池,没有中心管理人。P2Pool 通过将矿池服务器的功能去中心化,实现一个并行的类似区块链的系统,名叫份额链。一个份额链是一个难度低于比特币区块链的区块链系统。份额链允许池中矿工在一个去中心化的池中合作,以每30 秒一个份额区块的速度在份额链上采矿,并获得份额。在集中式矿池已经接近产生51%攻击的担忧下,P2Pool 的份额增长显著。
8.12 共识攻击
当一个或者一群拥有了整个系统中大量算力的矿工出现之后,他们就可以通过攻击比特币的共识机制来达到破坏比特币网络的安全性和可靠性的目的。共识攻击的一个典型场景就是“51%攻击”。想象这么一个场景,一群矿工控制了整个比特币网络51%的算力,他们联合起来打算攻击整个比特币系统。由于这群矿工可以生成绝大多数的块,他们就可以通过故意制造块链分叉来实现“双重支付”或者通过拒绝服务的方式来阻止特定的交易或者攻击特定的钱包地址。双重支付只能在攻击者拥有的钱包所发生的交易上进行,因为只有钱包的拥有者才能生成一个合法的签名用于双重支付交易。共识攻击中除了“双重支付”攻击,还有一种攻击场景就是拒绝对某个特定的比特币地址提供服务。一些安全研究组织利用统计模型得出的结论是,算力达到全网的30%就足以发动51%攻击了。

9. 竞争币、竞争块链和应用程序
比特币是一个开源项目,其源代码也作为其他的一些软件项目的基础。由比
特币衍生出来的最常见的形式,就是替代性去中心化货币,简称“竞争币”, 竞争块链使用的是和比特币一样
的创建块的机制, 有时也会采用货币或代币的支付机制,但它们的主要目的不
是为了维持一个货币系统。
9.1 元币
构建在比特币之上的数字货币,
染色币由特殊的钱包管理,这类钱包存储和解析依附在染色币上的元信息。用户在使用这类钱包的时候,可以通过增加有着某种特殊含义的标签的方式,将一般的比特币“染色”为染色币。比如说,这种标签的内容可以表示股票证明、优惠券信息、实际财产、商品或者可收集的代币等等。如何书写和解读这类标签,完全取决于给这枚比特币“染色”的人,他可以决定附着在这部分比特币上的元信息属性。
合约币是另一个建立在比特币系统之上的协议层。合约币拥有用户货币、可交易代币、金融手段、去中心化财产交易和其他一些功能。合约币利用比特币脚本语言中的OP_RETURE 操作符记录元信息来增加比特币交易的额外信息。

9.2 竞争币/山寨币
绝大多数的山寨币都来自比特币源代码的克隆,少数则没有使用比特币的任何源码,仅仅是借鉴了块链的模型后自己实现。竞争币或竞争块链(下一节会讲到)都是运行在自己块链上的独立的块链实现。之所以以命名区分,主要是因为竞争币主要用做货币,而竞争块链则不是。

我一般通过某款竞争币的决定性特性和市场规模来对其进行价值评估。
以下是关于竞争币和比特币的不同之处的几个问题:
▷ 这款竞争币有没有引入重大的创新?
▷ 如果有,那么这项创新是不是足够吸引使用比特币的用户转移过来?
▷ 这款竞争币是不是致力于某一细分领域或应用?
▷这款竞争币可以吸引到足够多的矿工来抵御一致性攻击吗?
还有一些有关关键财务和市场指标的问题:
▷ 这款竞争币的市场总值是多少?
▷ 整个系统的用户/钱包规模大概是多少?
▷ 接受其支付的商家有多少?
▷ 整个系统每日的交易数是多少?
▷ 交易总量是多少?
莱特币是最早的一批竞争币中的一员,自2011 年发布至今,已经成为继比特币
之后的第二成功的电子货币。它的主要创新在于两点,一是使用了scrypt 作为
工作量证明算法(继承自前文提到的Tenebrix),二是更快的货币参数。
▷ 出块速度:2 分半
▷ 货币总量:到2140 年达到8,400 万
▷ 一致性算法:scrypt
狗狗币是基于莱特币的一款竞争币,于2013 年12 月发布。

第一款引入scrypt 算法作为一致性机制的竞争币是为了便于CPU 挖矿,避免ASIC 矿机可能导致的算力集中化的问题。在那之后,对于一致性机制的创新一直很活跃。诸多竞争币陆续引进了包括scrypt,scrypt-N, Skein, Groestl, SHA3, X11, Blake 在内的算法来实现工作量证明的一致性机制。而在2013 年,作为工作量证明的一种替代机制——权益证明的出现,成为现代竞争币的基础。

为解决比特币挖矿的资源浪费,各种竞争币提出了新的共识:整合了BOINC 网格计算的工作量证明算法、含有蛋白质结构研究功能的工作量证明算法含有素数计算功能的工作量证明算法

利用大数据分析可以很容易地得到某一比特币地址的消费习惯。一些竞争币试图通过增强匿名性来解决这个问题。CryptoNote 是一种提供了电子货币基础的匿名性的参考实现,于2013 年10 月发布。它可以被克隆继而衍生出其他实现,并且内建了一个周期性的重置机制使其不能用作货币。很多竞争币是基于CryptoNote 实现的。

9.3 非货币型竞争区块链
域名币是比特币源代码的首个克隆产物,它是一种使用区块链的去中心化平台,用来注册和转让键-值对.域名币也可以用来注册其他命名空间下的名称和键-值对,例如存储邮件地址、密钥、SSL 证书、文件签名、投票系统和股票凭证之类,以及许多其他应用。域名币系统也有它自己的货币(符号为NMC),用于支付域名注册及转让的交易费用。域名币的客户端与比特币核心十分类似,因为前者的代码是从后者衍生而来的。在安装过程中,域名币客户端会下载其区块链的完整拷贝,下载完成之后便可进行查询和注册域名了。域名币客户端有3 条可用命令:
name_new 查询并提前注册一个域名
name_firstupdate 公开注册一个域名
name_update 改变域名的信息或刷新域名

Bitmessage 是一个实现了去中心化安全消息服务的比特币竞争币区块链,其本质上是一个无服务器的加密电子邮件系统。Bitmessage 可以让用户通过一个Bitmessage 地址来编写和发送消息。

以太坊是一种图灵完备的平台,基于区块链账簿,用于合约的处理和执行。它不是比特币的一个克隆,而是完完全全独立的一种设计和实现。本质上,合约其实是运行在以太坊系统中各个节点上的程序。这些程序可以存储数据、支付及收取、存储ether 以及执行无穷范围(因此才叫图灵完备)的计算行为,在系统中充当去中心化的自治软件代理。

10. 比特币安全
比特币网络的安全性是基于工作量证明而非访问控制,可以对所有人开放,也无需对比特币流量进行加密。比特币的支付网络并不需要加密或防窃听保护。要想充分利用比特币特有的去中心化安全模型,你必须避免中心化架构的常见诱惑:1)中心化钱包 2)离线的中心化交易。如果你的应用程序或明或暗地信赖于区块链以外的东西,就该引起重视,因为它可能会引入漏洞。依次取出应用程序的每个组件,并评估它被攻破时对整体安全的影响。如果你的应用程序的安全性在该组件沦陷后大打折扣,那就说明你已经对这些组件过度信任了。

阅读更多

更多精彩内容