「区块链入门笔记」2.区块链组成

重要概念

  • 地址
  • 交易
  • 区块
  • 网络

比特币用地址来标识一笔交易的支出方和接收方。所有的交易被记到统一的账本上,而这个账本是通过区块确认并完成的。每一个新区块的产生,都会被打上时间戳,最终生成按照时间前后排列并加以记录的电子交易证明。每个独立节点之间又通过比特币网络来建立联系,这样就组成了一个去中心化、分布式的电子交易记录时间戳服务器系统。


1.地址

主要用到椭圆曲线签名算法
私钥由 32 字节随机数组成,通过私钥可以算出公钥,公钥经过一系列哈希算法及编码算法就得到了比特币中的地址。因此地址其实是公钥的另一种表现形式,可以理解为公钥的摘要。
具体步骤见知乎链接

2.交易

比特币是一个链式的数字签名串。

前一个交易和下一位所有者的公钥签署一个数字签名,并将这个签名附加在交易的末尾。收款人通过验证签名,就可以验证电子货币的所有者链条。

2.1 交易结构

比特币的交易指转账,为了使价值易于组合和分割,转账通常有多个输入和输出。

(从生成到在网络中传播,再到通过工作量证明、整个网络节点验证,最终记录到比特币的区块链,这就是交易的整个生命周期。)
交易的本质是一个数据结构交易的数据结构

  • 输入标识着交易的发送方
  • 输出标识着交易的接收方及对发送方的找零
  • 交易的手续费是输入的总和与输出的总和之差。
  • 所有的交易输入必然是前面某笔交易的输出
  • 所以交易最核心的字段是交易的输出。
    交易的数据结构

2.2 UTXO 结构

Unspent Transaction Outputs 是未花费的交易输出
交易构成的链式结构,所有合法的比特币交易都可以追溯到前一个或多个交易的输出,链条的源头都是挖矿奖励,末尾则是当前未花费的交易输出。所有的未花费的输出即为整个比特币网络的 UTXO。

比特币规定每一笔新交易的输入必须是某笔交易未花费的输出,每一笔输入同时也需要上一笔输出所对应的私钥进行签名,并且每个比特币的节点都会存储当前整个区块链上的 UTXO,整个网络上的节点通过 UTXO 及签名算法来验证新交易的合法性。

比特币的交易输入通常有3种,分别是标准输入(Standard TxIn)、花费挖矿奖励(Spend Coinbase TxOut)、产生挖矿奖励(Coinbase/Generation)

三种交易输入结构

比特币的交易输出有两种,分别是标准交易输出(Standard TxOut)、挖矿奖励输出(Coinbase TxOut)


两种输出结构

2.3 脚本

每一笔交易的每一项输出,并不是指向一个地址,而是指向一个脚本。脚本是一套规则它约束着接收方怎样才能花掉这个输出上锁定的资产

有两类脚本:

  • 锁定脚本
  • 解锁脚本

锁定脚本是基于可变的模式,通过一段脚本语言来实现,位于交易的输出。

解锁脚本与锁定脚本相对应,只有按锁定脚本的规则去解,才能花掉这个脚本上对应的资产,位于交易的输入。

脚本语言可以表达出无数的条件变种。所以比特币是“可编程的货币”。

目前常用的比特币脚本主要分为两种:

  • 一种是普通的 P2PKH 类型(Pay-to-Public-Key-Hash),即支付给公钥的哈希值是地址,接收方只需要使用地址对应的私钥对该输出进行签名,即可花掉该输出。

  • 另一种是P2SH(Pay-to-Script-Hash),支付脚本的哈希值。拿多重签名来举例,它要求该输出要有 N 把私钥中的 M 把私钥(M≤N)同时签名才能花掉该资产,它类似于现实生活中需要多把钥匙才能同时打开的保险柜,只是更加灵活。

3. 区块

每个节点都基于已存在的最新区块生成下一个区块,同时将网络中未确认的合法交易包含进去。
这个过程就是将所有的交易打上时间戳标记的过程。

3.1 区块结构

交易会被打包成一个区块,包含到比特币的公开账本(区块链)里。 区块由包含元数据的区块头和紧跟其后的交易列表组成。区块数据结构如下表所示[插图]
区块结构
核心示例结构

区块头的大小为 80 字节,由 4 字节的版本、32 字节的上一个区块的哈希值、32 字节的 Merkle Root Hash、4 字节的时间戳(当前时间)、4 字节的当前难度值、4 字节的随机数等组成。

区块所包含的交易列表则附加在区块头后面。比特币网络约定每个区块的第一笔交易是coinbase 交易,这是一笔为了让矿工获得奖励及手续费的特殊交易。

3.2 Merkle Tree

区块包含的所有交易首先都会通过 Merkle Tree 算法生成 Merkle Root Hash 并存储至区块头的数据结构里。Merkle Tree 算法是用来同步数据一致性的算法,它基于一组哈希值列表构建成一个树,树的根哈希值作为原始数据列表的摘要。

Merkle Tree 具有以下特点:

1)数据结构是一个树,可以是二叉树,也可以是多叉树。

2)Merkle Tree的叶子节点的值是数据集合的单元数据或者单元数据的哈希值。

3)Merkle Tree的非叶子节点的值是所有叶子节点值的哈希值。
区块中所使用的Merkle Tree算法的原理如下图所示。
Merkle Tree 算法原理

3.3 时间戳服务器

时间戳服务器对以区块形式存在的一组数据实施随机哈希处理,加上时间戳,并将该随机哈希值进行广播

该时间戳能够证实特定数据于某特定时间是的确存在的,因为只有在该时刻存在了,才能获取相应的随机哈希值。

每个时间戳应当将前一个时间戳纳入其随机哈希值中,每一个随后的时间戳都对之前的一个时间戳进行增强(Reinforcing),这样就形成了一个链条(Chain)。

4. 网络

比特币采用了基于 P2P(Peer to Peer)的网络架构。

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

P2P 网络通信在比特币之前就已经被应用于文件共享领域了。

比特币被设计成一个点对点的数字现金系统,而 P2P 正好是这个理念的核心特征的反映,也是该特征的基石。

运行在每一台机器上的比特币核心程序就是比特币 P2P 网络中的一个节点。

比特币网络的相关功能如下:

  1. 新交易广播到全网的节点,每个节点会收到交易消息。
  2. 每个(挖矿)节点将新交易收集到节点的内存,并组装成区块。
  3. 每个(挖矿)节点都尝试在自己的区块中找到一个具有足够难度的工作量证明。
  4. (挖矿)节点找到一个工作量证明,把有效的区块数据向全网进行广播。
  5. 当且仅当包含在该区块中的交易都是有效的,并验证其完成了工作量证明,其他节点才认同该区块的有效性。
  6. 其他(挖矿)节点表示接受该区块,并在该区块的末尾制造新的区块以延长整个区块的链条。

在比特币网络中,交易和区块信息的传播是通过洪水算法(Flooding Algorithm)进行的。

简单地说,就是每一个收到信息的节点,向与它相连的所有节点推送该信息。下一个收到信息的节点继续这个过程。通常在一两秒内,交易或者区块的信息就可以传遍全网。
洪水算法

节点始终都将最长的链条作为正确的链条,在它的基础上持续工作并延长它。

如果有两个节点同时广播不同的基于上一个区块的新区块,那么其他节点在接收到该区块的时间先后上将存在差别。在此情形下,它们将在率先收到的区块基础上进行工作,但也会保留另外一个链条,以防后者变成最长的链条。该僵局的打破要等到下一个区块(工作量证明)被发现,当其中的一条链条被证实为是较长的一条时,在另一条分支链条上工作的(挖矿)节点将转换阵营,开始在较长的链条上工作。

所谓“新交易的广播”,实际上不需要抵达网络中的全部节点,只要交易信息能够抵达足够多的节点,它们将很快被整合进一个新的区块中。而区块的广播对被丢弃的信息进行容错处理。

容错处理:如果一个节点没有收到某特定区块,那么该节点将会发现自己缺失了该区块,就会向较长链的节点发出下载该缺失区块的请求

比特币网络中的矿工们不停地在最新的区块基础上构造下一个区块,通过算力竞争来争取记账权(将新区块写到比特币的区块链的机会),确认网络的转账交易,同时获取区块奖励。

由于每一个区块都包含上一个区块的哈希值,通过这个前向的哈希值,区块以链条的形式进行相连,最终形成了由各个区块组成的记账系统——区块链。