公认的区块链1.0的最好的书,在线阅读Mastering Bitcoin

介绍

什么是比特币

比特币是由一系列概念和技术作为基础构建的数字货币生态系统。

比特币可以做传统货币能做的所有事,例如买卖商品、给个人或组织汇款、贷款。用户可以在专门的交易所里买卖比特币或兑换其他货币。

不同于传统货币,比特币是完全虚拟的。用户只要有证明其控制权的密钥,用密钥解锁,就可以发送比特币。这些密钥通常存储在计算机的数字钱包里。

比特币是通过“挖矿”产生的,挖矿就是验证比特币交易的同时参与竞赛来解决一个数学问题。任何参与者(比如运行一个完整协议栈的人)都可以做矿工,用他们的电脑算力来验证和记录交易。

比特币协议还规定,每四年新币的开采量减半,同时限制比特币的最终开采总量为2,100万枚。这样,流通中的比特币数量非常接近一条曲线,并将在2140年比特币将达到2,100万枚。由于比特币的开采速度随时间递减,从长期来看,比特币是一种通货紧缩货币。

比特币的构成:

  • 去中心化的点对点网络
  • 公共的交易账簿
  • 去中心化的数学的和确定性的货币发行
  • 去中心化的交易验证系统

比特币发展史

2008年,一个化名为中本聪的人,在《比特币:一个点对点的电子现金系统》的论文中首先提出了比特币。中本聪结合以前的多个数字货币发明,如B-money和HashCash,创建了一个完全去中心化的电子现金系统,不依赖于通货保障或是结算交易验证保障的中央权威。他提出的算法的关键在于“工作量证明”。

根据中本聪发表的一篇涉及比特币网络运行的论文,比特币网络自从被许多其他的程序员修订之后,于2009年启动。

中本聪在2011年4月退出公众视野,将比特币代码开发与网络建设的重任留给了欣欣向荣的社区成员。

入门

比特币客户端的三种主要形式是:

完整客户端

一个完整客户端,或称“全节点”,是存储所有比特币交易的整个交易历史(由每一个用户完成的每一笔交易,曾经所有的每一笔)的客户端,管理用户的钱包,并可以在比特币网络上直接开始交易。它处理着协议的各个方面,而不依赖于任何其它的服务器或第三方服务。

轻量级客户端

一个轻量级客户端存储用户的钱包,但需要依赖第三方服务器才能进行比特币交易,才能接入比特币网络。轻量级客户端不保存所有交易的完整副本,因此必须信赖第三方的服务器来获取交易确认。

在线客户端

在线客户端通过网页浏览器在第三方服务器上访问和储存该用户的钱包。

比特币的原理

与传统银行和支付系统不同,比特币系统是以去中心化信任为基础的。由于比特币网络中不存在中央权威信任机构,“信任”成为了比特币用户之间存在的一种突出特性。

比特币概述

image-20231020094420587

如图所示,比特币系统由以下构成:

用户(用户通过密钥控制钱包)

交易(每一笔交易都会被广播到整个比特币网络)

矿工(通过竞争计算生成在每个节点达成共识的区块链,区块链是一个分布式的公共权威账簿,包含了比特币网络发生的所有的交易)

买咖啡的例子

这是一个真实发生的买咖啡的例子:

1
2
3
4
bitcoin:1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA?
amount=0.015&
label=Bob%27s%20Cafe&
message=Purchase%20at%20Bob%27s%20Cafe

它的意思表示:

1
2
3
4
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"

比特币的交易

交易告知全网:比特币的持有者已授权把比特币转帐给其他人。而新持有者能够再次授权,转移给该比特币所有权链中的其他人,产生另一笔交易来花掉这些比特币,后面的持有者在花费比特币也是用类似的方式。

每笔交易包含多个输入或输出,输入是针对一个比特币账号的负债,输出被当成信用点数记入到比特币账户中。当输出累加略少于输入量时,两者的差额就代表了一笔隐含的“矿工费”,这也是将交易放进账簿的矿工所收集到的一笔小额支付。

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

常见的交易形式:

从一个地址到另一个地址的简单支付,一个交易包含一个输入和两个输出

image-20231020152736091

集合多个输入到一个输出,相当于生活中很多零钱+纸币兑换大额面钞

image-20231020152840214

将一个输入分配给多个输出,即多个接收者的交易,可被用作商业实体分配资金

image-20231020153350606

交易的构建

钱包应用知道如何选取合适的输入和输出以建立Alice所希望的交易,A只需要输入地址和金额,其余的细节钱包应用会在后台自动完成。包应用甚至可以在完全离线时建立交易:比特币交易建立和签名时不用连接比特币网络,只有在执行交易时才需要将交易发送到网络。

获取正确的输入

Alice的钱包应用首先要找到一些足够支付给Bob所需金额的输入。如果钱包客户端没有某一未消费交易输出,它可以通过不同的服务者提供的各种API或完整索引节点的JSON PRC API从比特币网络中拿到这一交易信息。

如下所示:

1
$ curl https://blockchain.info/unspent?active=1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK

查找Alice的比特币地址所有的未消费的输出

返回的响应数据

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"unspent_outputs": [
{
"tx_hash":"186f9f998a5...2836dd734d2804fe65fa35779",
"tx_index":104810202,
"tx_output_n":0,
"script":"76a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac",
"value":10000000,
"value_hex":"00989680",
"confirmations":0
}
]
}

A的地址:1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK

含有一个未消费输出,价值是一千万聪(0.1btc)

创建交易输出

Alice的交易输出会包含一个脚本,这个脚本说 “这个输出谁能拿出一个签名和Bob的公开地址匹配上,就支付给谁”。因为只有Bob的钱包的私钥可以匹配这个地址,所以只有Bob的钱包可以提供这个签名以兑换这笔输出。因此Alice会用需要Bob的签名来包装一个输出。

第二个输出:因为Alice的金额是0.10比特币的输出形式,对0.015 比特币一杯的咖啡来说太多了,需要找Alice 0.085比特币的零钱。Alice钱包创建给她的零钱的支付就在付给Bob的同一个交易里面。

Alice的钱包将她的金额分成了两个支付:一个给Bob,一个给自己。她可以在以后的交易里消费这笔零钱输出。

最后,为了让这笔交易尽快地被网络处理,Alice的钱包会多付一小笔费用。这个不是明显地包含在交易中的;而是通过输入和输出的差值所隐含的。如果Alice的找零时0.0845btc,而不是0.1-0.015=0.085btc,这里就有剩下 0.0005btc(50万聪) 。因为加起来小到 0.10,所以这个 0.10 btc的输入就没有被完整的消费了。

比特币挖矿

这个交易现在在比特币网络上传播开来。但只有被一个称为挖矿的过程验证且加到一个区块中之后,这个交易才会成为这个共享账簿(区块链)的一部分。

比特币系统的信任是建立在计算的基础上的。交易被包在一起放进区块中时需要极大的计算量来证明,但只需少量计算就能验证它们已被证明。

▷ 挖矿在构建区块时会创造新的比特币,和一个中央银行印发新的纸币很类似。每个区块创造的比特币数量是固定的,随时间会渐渐减少。

▷ 挖矿创建信任。挖矿确保只有在包含交易的区块上贡献了足够的计算量后,这些交易才被确认。区块越多,花费的计算量越大,意味着更多的信任。

密钥,地址,钱包

每笔比特币交易都需要一个有效的签名才会被存储在区块链,只有有效的数字密钥才能产生有效的数字签名,因此拥有比特币的密钥副本就拥有了该帐户的比特币控制权。密钥包含公钥和私钥。

在比特币交易中,收件人的公钥称为比特币地址,比特币地址是用户经常看到的密钥的唯一代表,他们只需要把比特币地址告诉其他人即可。

在比特币系统中,我们用公钥加密创建一个密钥对,密钥对包括私钥和衍生出的公钥,公钥用于接收比特币,私钥用于比特币支付时的交易签名。

公钥和私钥之间的数学关系,使得私钥可用于生成特定消息的签名。此签名可以在不泄露私钥的同时对公钥进行验证。

私钥和公钥

私钥是一个随机选出的数字。私钥用于生成支付比特币所必需的签名以证明资金的所有权。私钥必须始终保持机密。

更准确地说,私钥可以是1和n-1之间的任何数字,其中n是一个常数(略小于2^256)。要生成这个私钥,我们可以随机选择一个256位的数字,并检查它是否小于n-1。

通过椭圆曲线算法可以从私钥计算得到公钥,这是不可逆转的过程:K=kGK = k * G 。其中k是私钥,G是被称为生成点的常数点,而K是所得公钥。

比特币使用了secp256k1标准所定义的一条特殊的椭圆曲线和一系列数学常数。

例如:

1
K = 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD * G
1
2
3
K = (x, y)
x = F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A
y = 07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2E505BDB

比特币地址

比特币地址是一个由数字和字母组成的字符串,可以与任何想给你比特币的人分享。通常由“1”开头。

通常用户见到的比特币地址是经过“Base58Check”编码的。如图所示

img

Base58是一种基于文本的二进制编码格式,用在比特币和其它的加密货币中。相比于Base64(26个小写字母、26个大写字母、10个数字以及两个符号),Base58由不包括(0,O,l,I)的大小写字母和数字组成。

为什么要Base58编码?

想要记住一个256位的整数是非常困难的,并且,如果记错了其中某些位,这个记错的整数仍然是一个有效的私钥,因此,比特币有一种对私钥进行编码的方式,这种编码方式就是带校验的Base58编码。又称为钱包导入格式:WIF(Wallet Import Format)

对私钥进行Base58编码有两种方式:非压缩的私钥格式(非压缩的公钥格式),压缩的私钥格式(压缩的公钥格式)。

非压缩的私钥格式

非压缩的私钥格式是指在32字节的私钥前添加一个0x80字节前缀,得到33字节的数据,对其计算4字节的校验码,附加到最后,一共得到37字节的数据:

私钥:0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D

增加0x80到私钥的前面:800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D

两次SHA-256运算:

8147786C4D15106333BF278D71DADAF1079EF2D2440A4DDE37D747DED5403592

507A5B8DFED0FC6FE8801743720CEDEC06AA5C6FCA72B07C49964492FB98A714

前四个字节作为效验位:507A5B8D

效验位加在第二步的结果的后面:800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D507A5B8D

Base58编码:5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ

压缩的私钥格式

压缩的私钥格式会在32字节的私钥前后各添加一个0x80字节前缀和0x01字节后缀,共34字节的数据,对其计算4字节的校验码,附加到最后,一共得到38字节的数据

交易

比特币交易的本质是数据结构,这些数据结构中含有比特币交易参与者价值转移的相关信息。比特币区块链是全球复式记账总账簿,每个比特币交易都是在比特币区块链上的一个公开记录。

比特币交易的生命周期

诞生:一笔比特币交易的生命周期起始于它被创建的那一刻。

比特币交易会被一个或者多个签名加密(这标志着对该交易指向的比特币资金的使用许可)。在比特币网络中,每一个节点(比特币交易参与者)验证、并将交易在网络中进行广播,直到这笔交易被网络中大多数节点接收。最终,比特币交易被一个挖矿节点验证,并被添加到区块链上一个记录着许多比特币交易的区块中。

创建比特币交易->广播交易比特币至网络->比特币交易在比特币网络中的传播

交易结构

一笔比特币交易是一个含有输入值和输出值的数据结构。

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

一个UTXO可以是一“聪”的任意倍。尽管UTXO可以是任意值,但只要它被创造出来了,就像不能被切成两半的硬币一样不可再分了。如果出现UTXO过大,在交易支付的时候会出现找零的情况。例如:用户由5btc的UTXO想支付1btc,那么这笔交易必须消耗掉20btc并且产生两个输出,1btc支付给接收人,4btc支付到找零地址。

就像现实生活中一样,比特币应用可以使用一些策略来满足付款需要:组合若干小的个体,算出准确的找零;或者使用一个比交易值大的个体然后进行找零。

被交易消耗的UTXO被称为交易输入,由交易创建的UTXO被称为交易输出。

交易输入是指向UTXO的指针。它们指向特定的UTXO,并被交易哈希和在区块链中记录UTXO的序列号作为参考。可以使用贪心算法选择所要使用的UTXO。

大多数交易包含交易费,这是为了在网络安全方面给比特币矿工一种补偿。

交易费可当作是为了包含(挖矿)一笔交易到下一个区块中的一种鼓励,也可当作是对于欺诈交易和任何种类的系统滥用,在每一笔交易上通过征收一笔小成本的税而造成的一种妨碍。交易费被挖出这个区块的矿工得到,并且记录在这个交易的区块链中。交易费通过所有输入的总和,以及所有输出的总和之间的差来表示:交易费 = 求和(所有输入) - 求和(所有输出)

比特币网络

P2P网络架构

比特币采用了基于国际互联网(Internet)的P2P(peer-to-peer)网络架构。P2P是指位于同一网络中的每台计算机都彼此对等,各个节点共同提供网络服务。

尽管P2P网络中各个节点互等,但是根据提供的功能不同,各节点之间具有不同的分工。每个比特币节点都由路由、区块链数据库、挖矿、钱包服务的功能集合。一个全节点包括:钱包、矿工、完整区块链、网络路由节点。

全节点能够独立自主地校验所有交易,而不需借由任何外部参照。轻量级节点只保留了区块链的一部分,通过“建议支付验证(SPV)”的方式来完成交易验证。

挖矿节点通过运行在特殊硬件设备上的工作量证明(proof-of-work)算法,以相互竞争的方式创建新的区块。

用户钱包也可以作为全节点的一部分

扩展比特币网络的不同节点类型:

  • 核心客户端:钱包,矿工,完整区块链,网络路由节点
  • 完整区块链节点:完整区块链,网络路由节点
  • 独立矿工:矿工,完整区块链,网络路由节点
  • SPV钱包:钱包,网络路由节点

全节点

全节点是指维持包含全部交易信息的完整区块链的节点。完整区块链节点保有完整的、最新的包含全部交易信息的比特币区块链拷贝,这样的节点可以独立地进行建立并校验区块链,从第一区块(创世区块)一直建立到网络中最新的区块。

简易支付验证 (SPV)节点

通过简化的支付验证(SPV)的方式可以使某些节点在不必存储完整区块链的情况下进行工作,这种类型的客端被称为SPV客户端或轻量级客户端。SPV节点只需下载区块头,而不用下载包含在每个区块中的交易信息。

简易支付验证是通过参考交易在区块链中的深度,一个拥有完整区块链的节点会构造一条验证链,这条链是由沿着区块链按时间倒序一直追溯到创世区块的数千区块及交易组成。而一个SPV节点会验证所有区块的链(但不是所有的交易),并且把区块链和有关交易链接起来。

SPV节点不能验证某个交易(譬如同一个UTXO的双重支付)不存在。为了防御这些攻击,SPV节点需要随机连接到多个节点,以增加与至少一个可靠节点相连接的概率。

在引入SPV节点/轻量级节点后不久,比特币开发人员就添加了一个新功能:Bloom过滤器,用以解决SPV节点的隐私风险问题。Bloom过滤器通过一个采用概率而不是固定模式的过滤机制,允许SPV节点只接收交易信息的子集,同时不会精确泄露哪些是它们感兴趣的地址。

Bloom过滤器

Bloom过滤器是一个允许用户描述特定的关键词组合而不必精确表述的基于概率的过滤方法。

首先,SPV节点会初始化一个不会匹配任何关键词的“空白”Bloom过滤器。接下来,SPV节点会创建一个包含钱包中所有地址信息的列表,并创建一个与每个地址相对应的交易输出相匹配的搜索模式。然后,SPV节点会把每一个搜索模式添加至Bloom过滤器里,这样只要关键词出现在交易中就能够被过滤器识别出来。最后,对等节点会用收到的Bloom过滤器来匹配传送至SPV节点的交易。

Bloom过滤器的实现是由一个可变长度(N)的二进制数组(N位二进制数构成一个位域)和数量可变(M)的一组哈希函数组成。这些哈希函数的输出值始终在1和N之间,该数值与二进制数组相对应。Bloom过滤器的准确性和私密性能通过改变长度(N)和哈希函数的数量(M)来调节。

Bloom过滤器被用来过滤SPV节点从对等节点里收到的交易信息。SPV会建立一个只能和SPV节点钱包里的地址匹配的过滤器。SPV节点会向对等节点发送一条包含需在该连接中使用的过滤器的filterload消息。当过滤器建好之后,对等节点将每个交易的输出值代入过滤器中验证。那些匹配的交易会被传送回SPV节点。

交易池

交易池:维护一份未确认交易的临时列表。例如,保存用户钱包的节点会利用这个交易池来记录那些网络已经接收但还未被确认的。当一个交易被添加到交易池中,会同时检查孤立交易池,看是否有某个孤立交易引用了此交易的输出(子交易)。

区块链

区块链是由包含交易信息的区块从后向前有序链接起来的数据结构。

区块链可以被视为一个垂直的栈,第一个区块作为栈底的首区块,随后每个区块都放在其他区块之上。

每个区块头都经过SHA-256加密生成一个哈希值,每个区块都通过其区块头的“父区块哈希值“字段引用前一区块,这样,每个区块都可以连接前一个区块,这也方便了追溯。

每个区块都只有一个父区块,但可以暂时拥有多个子区块,这是区块链分叉,这是暂时的,最终,只有一个子区块会成为区块链的一部分。

区块结构

区块是一种被包含在公开账簿(区块链)里的聚合了交易信息的容器数据结构。它包含:一个区块头,紧跟其后的区块主体的一长串交易。区块头80字节,平均每个交易为250字节,每个区块超过500个交易,因此,一个包含所有交易的完整区块比区块头大得多。

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

区块头

区块头由三组区块元数据组成。

一组引用父区块哈希值的数据,这组数据用于该区块与前一区块连接。

第二组元数据,难度,时间戳和nonce,与挖矿竞争相关。

第三组元数据是merkle树根。

区块标识符

区块主标识符就是它的加密哈希值,一个通过两次SHA256算法得到的数字指纹,产生的32字节哈希值,即区块头哈希值,例如:

000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

是第一个比特币区块的区块哈希值。区块哈希值可以唯一、明确地标识一个区块.

区块哈希值并不包含在区块的数据结构里,它可能会作为区块元数据的一部分被存储在一个独立的数据库表中。

另一种标识区块的方式是通过该区块在区块链中的位置,即区块的高度,block height。第一个区块的高度是0,和之前的哈希值表示同一个区块。每一个随后被存储在第一个区块之上的区块在区块链中都比前一区块“高”出一个位置。

但是,相较于区块哈希值,区块高度并不是唯一的标识符。虽然单一的区块总会有一个明确的固定的高度,但反过来不成立。有可能存在两个相同高度的区块在争夺位置,这是分叉。

创世区块

区块链里的第一个区块创建于2009年,被称为创世区块。它是区块链里面所有区块的共同祖先,这意味着你从任一区块,循链向后回溯,最终都将到达创世区块。

创世区块的哈希值:

1
0000000000 19d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

https://blockchain.info/block/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f可以在这个网址查看创世区块的信息。

区块的连接

当一个节点从网络接收传入的区块时,它会验证这些区块,然后链接到现有的区块链上。

例如,现在第277314个区块的区块头哈希值为:00000000000000027e7ba6fe7bad39faf3b5a83daed765f05f7d1b71a1632249,此时比特币节点从网络上接收到一个新的区块,描述如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"size":43560,
"version":2,
"previousblockhash":"00000000000000027e7ba6fe7bad39faf3b5a83daed765f05f7d1b71a1632249",
"merkleroot":"5e049f4030e0ab2debb92378f53c0a6e09548aea083f3ab25e1d94ea1155e29d",
"time":1388185038,
"difficulty":1180923195.25802612,
"nonce":4215469401,
"tx":["257e7497fb8bc68421eb2c7b699dbab234831600e7352f0d9e6522c7cf3f6c77",
#[...many more transactions omitted...]
"05cfd38f6ae6aa83674cc99e4d75a1458c165b7ab84725eda41d018a09176634"
]
}

对于这个区块,节点会根据”父区块哈希值“字段找出包含它的父区块的哈希值,这是节点已知的哈希值,也就是第277314块区块的哈希值。故这个区块的高度为277315。

Merkle 树

区块链中的每个区块都包含了产生于该区块的所有交易,且以Merkle树表示。

Merkle树是一种哈希二叉树,用作快速归纳和校验大规模数据完整性。

在比特币网络中,Merkle树被用来归纳一个区块中的所有交易,同时生成整个交易集合的数字指纹,且提供了一种校验区块是否存在某交易的高效途径。当N个元素插入到Merkle树中后,至多计算2log2N2\log_2N就可检测出某个交易是否在这个树中。

Merkle树是自底向上构建的。

Merkle树被SPV节点广泛使用。SPV节点不保存所有交易也不会下载整个区块,仅仅保存区块头。它们使用认证路径或者Merkle路径来验证交易存在于区块中,而不必下载区块中所有交易。

挖矿与共识

挖矿是增加比特币货币供应的一个过程。每10分钟就会有一个新的区块被“挖掘”出来。

矿工们在挖矿过程中会得到两种类型的奖励:创建新区块的新币奖励,以及区块中所含交易的交易费。为了得到这些奖励,矿工们会争相完成一种基于加密哈希算法的数学难题,解决这个难题的答案,作为矿工的计算工作量的证明,被称为”“工作量证明”

新比特币的生成过程被称为挖矿是因为它的奖励机制被设计为速度递减模式,类似于贵重金属的挖矿过程。矿工通过创造一个新区块得到的比特币数量准确说是每210,000个块减少一半。在2140年之后,不会再有新的比特币产生。

矿工们同时也会获取交易费。每笔交易都可能包含一笔交易费,交易费是每笔交易记录的输入和输出的差额。

比特币经济学和货币创造

目前,比特币一一个确定的但不断减慢的速率被铸造出来。大约每10分钟产生一个新区块,每一个区块都伴随着一定数量的全新比特币。每开采21万个区块,大约耗时4年,货币发行速率降低50%,在比特币运行的第一个四年中,每个区块创造出50个新比特币。

最终,在经过1,344万个区块之后,所有的共2,099,999,997,690,000聪比特币将全部发行完毕。这大约是2140年。

image-20231206154105985

总量有限并且发行速度递减创造了一种抗通胀的货币供应模式。

去中心化共识

区块链并不是由一个中心机构创造的,它是由比特币网络中的所有节点各自独立竞争完成的。换句话说比特币网络中的所有节点,依靠着节点间的不稳定的网络连接所传输的信息,最终得出同样的结果并维护了同一个公共总帐。

中本聪的主要发明就是这种去中心化的自发共识机制。自发是指,没有经过明确选举或者没有固定达成的共识的时间,在比特币的共识中,数以千计的独立节点遵守了简单的规则通过异步交互自发形成的产物。

比特币的去中心化共识由所有网络节点的4种独立过程相互作用而产生:

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

交易的独立检验

钱包软件通过收集UTXO、提供正确的解锁脚本、构造支付给接收者的输出这一系列的方式来创建交易。产生的交易随后将被发送到比特币网络临近的节点,从而使得该交易能够在整个比特币网络中传播。每一个收到交易的比特币节点将会首先验证该交易,这将确保只有有效的交易才会在网络中传播。

每一个节点在校验每一笔交易时,都需要对照一个长长的标准列表:

  • 交易的语法和数据结构必须正确。
  • 输入与输出列表都不能为空。
  • 交易的字节大小是小于MAX_BLOCK_SIZE的。
  • 每一个输出值,以及总量,必须在规定值的范围内 (小于2,100万个币,大于0)。
  • 没有哈希等于0,N等于-1的输入(coinbase交易不应当被中继)。
  • nLockTime是小于或等于INT_MAX的。
  • 交易的字节大小是大于或等于100的。
  • 交易中的签名数量应小于签名操作数量上限。
  • 解锁脚本(scriptSig)只能够将数字压入栈中,并且锁定脚本(scriptPubkey)必须要符合isStandard的格式 (该格式将会拒绝非标准交易)。
  • 池中或位于主分支区块中的一个匹配交易必须是存在的。
  • 对于每一个输入,如果引用的输出存在于池中任何的交易,该交易将被拒绝。
  • 对于每一个输入,在主分支和交易池中寻找引用的输出交易。如果输出交易缺少任何一个输入,该交易将成为一个孤立的交易。如果与其匹配的交易还没有出现在池中,那么将被加入到孤立交易池中。
  • 对于每一个输入,如果引用的输出交易是一个coinbase输出,该输入必须至少获得COINBASE_MATURITY (100)个确认。
  • 对于每一个输入,引用的输出是必须存在的,并且没有被花费。
  • 使用引用的输出交易获得输入值,并检查每一个输入值和总值是否在规定值的范围内 (小于2100万个币,大于0)。
  • 如果输入值的总和小于输出值的总和,交易将被中止。
  • 如果交易费用太低以至于无法进入一个空的区块,交易将被拒绝。
  • 每一个输入的解锁脚本必须依据相应输出的锁定脚本来验证。

整合交易至区块

验证交易后,比特币节点会将这些交易添加到自己的内存池中。内存池也称作交易池,用来暂存尚未被加入到区块的交易记录。

Alice从Bob咖啡店购买咖啡时产生的那个区块,我们假设这个区块是由Jing的挖矿系统挖出的,并且继续跟进Alice的交易,因为这个交易已经成为了新区块的一部分。

Jing的挖矿节点维护了一个区块链的本地副本,包含了自2009年比特币系统启动运行以来的全部区块。当Alice买咖啡的时候,Jing节点的区块链已经收集到了区块277,314,并继续监听着网络上的交易,在尝试挖掘新区块的同时,也监听着由其他节点发现的区块。

Jing的节点立刻构建一个新的空区块,做为区块277,316的候选区块。

交易优先级

交易的优先级是由交易输入所花费的UTXO的“块龄”决定,交易输入值高、“块龄”大的交易比那些新的、输入值小的交易拥有更高的优先级。

交易的优先级是通过输入值和输入的“块龄”乘积之和除以交易的总长度得到的:

1
Priority = Sum (Value of input * Input Age) / Transaction Size

交易输入的值是由比特币单位“聪”(1亿分之1个比特币)来表示的。UTXO的“块龄”是自该UTXO被记录到区块链为止所经历过的区块数,即这个UTXO在区块链中的深度。

一个交易想要成为“较高优先级”,需满足的条件:优先值大于57,600,000,相当于一个比特币(即1亿聪),年龄为一天(144个区块),交易的大小为250个字节:

1
High Priority > 100,000,000 satoshis * 144 blocks / 250 bytes = 57,600,000

比特币交易中没有过期、超时的概念,一笔交易现在有效,那么它就永远有效。

创币交易

区块中的第一笔交易是笔特殊交易,称为创币交易或者coinbase交易。是由节点构造并用来奖励矿工们所做的贡献的。

创币交易没有输入,不消耗UTXO。它只包含一个被称作coinbase的输入,仅仅用来创建新的比特币。创币交易有一个输出,支付到这个矿工的比特币地址。