深入浅出:从一笔比特币交易的生命周期看懂区块链技术
为什么要写这篇文章?最近看了许多解释区块链的文章,发现很多文章要么过于概念化或谈及一些应用前景和行业判断,要么又过于专业晦涩,使得很多没有技术底子的小伙伴难以真正理解区块链技术。由于以上的原因,我希望通过一笔比特币交易的完整生命周期来解释比特币中的区块链技术。在这样具体流程的场景下,我相信会更容易理解区块链。
基本常识:
- 区块链不等于比特币,区块链只是比特币系统用来记录交易信息的账簿;
- 比特币没有账户余额的概念,所有的交易只记录资金的来源和去向,所谓账户余额是区块链中计算出来的结果;
- 挖矿奖励是为了维护整个系统鼓励人们利用自己设备的算力资源来共同验证每笔交易的有效性而给予的奖励;
交易的完整过程:从创建新交易到新区块产生
假设一笔比特币交易 A 一旦被创建,它的生命周期就开始了。随后,交易 A 会被一个或者多个签名加密(这些签名用来说明交易 A 的资金流向是被资金的拥有者所许可的)。而后,交易 A 被广播到比特币网络中,最快收到广播信息的是相邻的2-3个节点,这些节点都会参与验证这笔交易,于此同时将交易在网络中再次进行广播,直到这笔交易 A 被网络中大多数节点(所有下载比特币客户端的设备都有可能成为这样的节点)接收。
最终,交易 A 被一个正在参与挖矿的节点验证,交易 A 连同其它一些近期被创建的交易一起被打包到一个区块 B 中,并被添加到区块链上,这时整个区块链就被延长并新增了一个区块 B 。区块 B 获得 6 次以上的“确认”时就被认为是不可撤销的,因为要撤销和重建六个区块需要巨量的计算,交易被打包在一起放进区块中时需要极大的计算量来证明,但只需少量计算就能验证它们已被证明。
我们将上面的交易过程描述简单细分为以下 6 个步骤:
- 产生新交易
- 签名加密
- 交易在比特币网络中传播
- 整合交易&构建新区块
- 挖矿
- 新区块连接到区块链
接下来,我们将详细分析 6 个交易步骤中的具体细节和所采用到的底层技术,在解释每个步骤和具体的概念时,我都将举出适当的例子来帮助理解,如果依然没有读懂,那肯定是你看的太快了……
01 产生新交易
当隔壁老王想要将自己钱包中的一个比特币转账给老张时,这个交易就被老王的钱包所构建了。
将一笔比特币交易理解成纸质支票有助于我们的理解,一笔比特币交易是一个有着货币转移目的工具, 如同当收款人或持票人拿着支票到银行时,银行会无条件支付其规定数量的金额。并且交易发起人并不一定是签署该笔交易的人。
比特币交易可以被任何人在线上或线下创建,即便创建这笔交易的人不是这个账户的授权签字人。就像一家企业中秘书开出的这张支票(发起交易),需要等待Boss签署该笔交易(数字签名)。
有以下 4 个概念需要展开理解,用以更加深入地理解“新交易构建”的一些细节:
- UTXO
- 交易输出
- 交易输入
- 交易费
UTXO
UTXO易于理解的说就像是账户的余额。它是比特币交易的基本单位,是未经使用的一个交易输出,Unspent Transaction Output,简称UTXO,“未花费的交易输出”。UTXO不能再分割,1 个UTXO可以是 1“聪” 的任意倍,就像美元可以被分割成“美分”一样,“分”就不可以再分割了。UTXO被记录于区块链中,比特币网络监测着以百万为单位的所有可用的UTXO。
假设隔壁老王此时拥有 1.9 比特币,当隔壁老王接收到 0.1 比特币时,这个金额被当作UTXO记录到区块链里,现在老王一共拥有的 2 比特币,同样都被当作UTXO分散到数百个交易和数百个区块中。实际上,并不存在一个储存比特币的地址或账户余额的地方,只有被老王(所有者)锁住的、分散的UTXO。
因此,“隔壁老王的比特币余额”这个概念,是通过扫描区块链并聚合所有属于该用户的UTXO来计算该用户的余额。
交易的输出
一笔比特币交易是一个含有输入值和输出值的数据结构,其中包含了将一笔资金从初始地址(输入)转移至目标地址(输出)的代码信息:版本规则、输入&其数量、输出&其数量、时间戳。
每一笔比特币交易创造输出,输出都会被比特币账簿记录下来。所有的输出都能创造一定数量的可用于支付的比特币(也就是UTXO)。这些UTXO会被整个网络所识别记录,其所有者可在未来的交易中使用它们。给隔壁老王发送比特币实际上是创造新的UTXO,并且能被他用于新的支付。
交易的输入
交易输入是指向UTXO的指针,当用户付款时,他的钱包通过选择可用的UTXO来构造一笔交易。
例如:隔壁老王想要支付0.015比特币,他的钱包应用会选择一个 0.01 UTXO和一个 0.005 UTXO,使用它们加在一起来得到想要的付款金额。
交易费
大多数交易包含交易费,这是为了在网络安全方面给比特币矿工一种补偿。大多数钱包自动计算并计入交易费,交易费被挖出这个区块的矿工得到,并且记录在这个交易的区块链中。交易的数据结构没有交易费的字段,意味着你无法从交易信息中直接看到交易费的金额。
例如:隔壁老王想要消费支付0.015比特币,为了自己的交易被矿工优先处理,他愿意支付0.001比特币作为交易费,那么老王的钱包至少需要从区块链记录中整合至少0.016比特币的UTXO。假设他的钱包有一个0.2比特币的UTXO可用,那么这笔新的交易就会产生一个0.2比特币的输入,和两个输出:一个是0.015比特币的消费金额被支付给目标地址,另一个0.184比特币的输出作为找零支付给老王的钱包地址,其中有0.001比特币未分配,就是“隐藏的”交易费用。
值得说明的是:一定要定义清楚0.184比特币是一个指向老王自己钱包的输出,这样找零才会有效“退回”给老王的钱包,否则0.184比特币也都将成为交易费,被矿工挖到这份惊喜的“红包”。
02 签名加密
一笔比特币交易一旦被创建,它就会被资金所有者(可能存在多位所有者)签名。如果它是合法创建并签名的,则该笔交易现在就是有效的。它包含资金转移时所需要的所有信息。用户的私钥用于生成支付比特币所必需的签名,来证明资金的所有权,这样的签名加密是为了确保交易内容不被篡改。这和前面介绍的纸质支票的授权签字效果相同。
网络中节点收到交易信息后,会对交易的合法性进行检查,资金所有者的签名加密是重要的验证依据,检查都通过后,则将交易标记为合法的未确认交易,才会在网络中进行广播。
有以下 4 个概念需要展开理解,用以更加深入的理解“签名加密”的一些细节:
- 私钥
- 公钥
- 钱包
- 交易脚本
私钥
一个比特币钱包中包含一系列的密钥对,每个密钥对包括一个私钥和一个公钥。私钥是一个数字,通常是随机产生的。一个比特币地址中的所有资金的控制取决于相应私钥的所有权和控制权。私钥必须保密,因为一旦被泄露,相当于该私钥保护下比特币也就丢失了。
通过在一个密码学安全的随机源中取出一串随机字节,对其使用SHA256哈希算法进行运算,生成了一个256位的数字,这样的一个数字就可以作为私钥。以十六进制格式表示一个随机生成的私钥,即:
1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD
公钥
通过椭圆曲线算法可以从私钥计算得到公钥,这是不可逆转的过程。由公钥经过单向的加密哈希算法生成的比特币地址以数字“1”开头,在交易中比特币地址就是收款人的地址。
钱包
比特币钱包是私钥的容器,钱包只包含私钥而不是比特币,每一个用户有一个包含多个私钥的钱包。钱包中包含成对的私钥和公钥,用户用这些私钥来签名交易。
其中一种常见且典型的钱包就是使用“助记码词汇”做为种子,而生成私钥的钱包。这样的单词的序列可以重新创建种子,并重新创造钱包以及所有私钥。在首次创建钱包时,带有助记码的钱包应用程序将会向使用者生成一个12至24个单词,单词的顺序就是钱包的备份。
交易脚本
交易脚本是检验交易是否合法的核心机制。一般每个交易都会包括两个脚本:输出脚本,scriptPubKey和输入脚本,scriptSig。
输出脚本一般由付款方对交易设置锁定,用来对收款方进行权限控制,例如限制必须是某个公钥 (比特币地址) 的拥有者才能花费这笔交易。
输入脚本 (签名脚本) 常常含有一个被用户的私钥生成的数字签名,用来证明自己可以满足交易输出脚本的锁定条件,即对某笔交易中比特币资金的拥有权。
值得注意的是:比特币交易的输入和输出并非只是简单对应了付款人的私钥和收款人的公钥地址,而是还包含了更多的内容,通过脚本可以直接验证交易的有效性,并且实现了更多复杂的交易方式,比如“多重签名脚本”,保证只有自己和第三方钱包共同签名后才可动用输出,这样保证了黑客在攻击了第三方钱包后也无法花掉用户的比特币。
03 交易在比特币网络中传播
一笔交易需要传递至比特币网络,才能被传播,也才能加入区块链中。一笔比特币交易只是300到400字节的数据,一旦交易被发送到任意一个连接至比特币网络的节点,这笔交易将会被该节点验证。如果交易被验证有效,该节点将会将这笔交易传播到这个节点所连接的其他节点。
无论交易是否被节点验证有效,交易发起者会收到一条回执消息,包含了此笔交易是否被接受的返回信息。在几秒钟之内,一笔有效的交易就会呈指数级扩散的效率在网络中传播,直到所有连接到网络的节点都接收到它。
值得注意的是:每一个节点在传播每一笔交易之前均进行独立验证。因此,一个异常交易所能到达的节点不会超过一个。所以,比特币网络能有效抵御入侵,避免垃圾信息的滥发和有效拒绝服务攻击。
有以下 4 个概念需要展开理解,用以更加深入的理解“交易传播”的一些细节:
- 客户端
- 完整节点
- 轻量节点 (SPV) 节点
- 挖矿节点
客户端
bitcoin.org可以下载标准客户端,即比特币核心,也叫“中本聪客户端”(satoshi client)。它包括了比特币系统的所有内容:钱包功能、整个交易账簿(区块链)的完整拷贝、交易确认引擎,P2P比特币网络中的一个完整网络节点。
完整节点
保有一份完整的、最新的区块链拷贝的节点被称为“完整节点”。完整节点能够独立自主地校验所有交易, 而不需借由任何外部参照。
轻量节点 / SPV节点
只保留了区块链的一部分,通过一种名为“简易支付验证(SPV)”的方式来完成交易验证的节点被称为“SPV节点”, 又叫“轻量节点”。越来越多的用户钱包都是SPV节点,尤其是运行于智能手机等资源受限设备上,这些设备没有空间存储完整的 150G 大小的区块链。
挖矿节点
挖矿节点通过运行在特殊硬件设备上的工作量证明算法,以相互竞争的方式创建新的区块。一些挖矿节点同时也是全节点,保有区块链的完整拷贝;还有一些参与矿池挖矿的节点是轻量级节点,它们必须依赖矿池服务器维护的全节点进行工作。
04 整合交易&构建新区块
验证交易后,每个比特币网络节点会将这些交易添加到自己的内存池中,内存池也称作交易池,用来暂存尚未被加入到区块的交易记录。而挖矿节点除了收集和验证交易以外,还会将这些交易打包到一个候选的区块中。
挖矿节点需要为内存池中的每笔交易分配一个优先级,并选择较高优先级的交易记录来构建候选区块,在区块被填满后,内存池中的剩余交易会成为下一个区块的候选交易。例如,一个挖矿节点从内存池中整合到了全部的交易,新的候选区块包含有418笔交易,总的矿工费为0.09094925个比特币。
现在既然创建好了一个包含418笔交易的候选区块,挖矿节点就准备拿它来挖矿。
有以下 4 个概念需要展开理解,用以更加深入的理解“整合交易”的一些细节:
- 临时未验证的交易池
- 交易优先级
- 区块结构
- 矿池
临时未验证的交易池
比特币网络中几乎每个节点都会维护一份未确认交易的临时列表,被称为内存池或交易池。节点们利用这个池来追踪记录那些被网络所知晓但还未被区块链所包含的交易。交易池是存储在本地内存中,并不是存储在硬盘里,因此不同节点的两池内容可能有很大差别。
交易优先级
挖矿节点需要为内存池中的每笔交易分配一个优先级,并选择较高优先级的交易记录来构建候选区块。交易的优先级是由交易输入所花费的UTXO的交易创建时间决定,交易输入值高且创建时间较早的交易比那些较新且输入值小的交易拥有更高的优先级。
区块中用来存储交易的前50K字节是保留给较高优先级交易的,如果区块中有足够的空间,高优先级的交易行为将不需要矿工费。矿工费越高,交易被处理的优先级也越高。
区块结构
区块是一种聚合了交易信息容器的数据结构。由区块头和区块主体组成,区块头是80字节,而平均每个交易至少是250字节,而且平均每个区块至少包含超过500个交易。
区块头包含三组元数据:
- 用于连接前面的区块、索引自父区块哈希值的数据;
- 挖矿难度、Nonce(用于工作量证明算法的计数器)、时间戳;
- 能够总结并快速归纳校验区块中所有交易数据的Merkle(默克尔)树根数据。
矿池
改变了原来挖矿奖励由一个胜出矿工独自获得的状态,采用团队协作方式来集中算力进行挖矿,对产出的数字货币按照算力进行分配。
采矿成为一项团队运动,一群矿工于2010年12月16日一起在slush矿池挖出了它的第一个区块。根据其所贡献的工作量,每位矿工都获得了相应的报酬。此后的两个月间,slush矿池的算力从1 400Mhash/s增长到了60Ghash/s。
05 挖矿
现在既然已经创建好了一个候选区块,挖矿节点就准备拿它来挖矿。矿工们争相完成一种基于加密哈希算法的数学难题,获胜者有权在区块链上进行交易记录并得到奖励。每 10 分钟左右生成一个不超过 1 MB 大小的新区块,这个区块记录了这 10 分钟内发生并验证过的交易内容。矿工们在挖矿过程中会得到两种类型的奖励:创建新区块的新币奖励,以及区块中所含交易的交易费。
一旦某一个挖矿节点在算力竞争中胜出,优先得到了数学难题的答案,会立刻将这个区块发给它的所有相邻节点,这些节点在接收并独立验证这个新区块后,也会继续传播此区块,每个节点都会将它作为新区块加到自身节点的区块链副本中。
有以下 3 个概念需要展开理解,用以更加深入的理解“确认交易”的一些细节:
- 工作量证明
- 创币交易
- Coinbase奖励和矿工费
工作量证明
Proof of Work,通过计算来猜测一个数值(nonce)。具体到比特币,矿工必须要在满足全网目标难度的情况下求解SHA256算法。优先完成工作量证明的矿工可以获得比特币奖励。保证在一段时间内,系统中只能出现少数合法提案。
哈希问题具有不可逆的特点,只有通过暴力计算找到问题的答案。一旦获得符合要求的nonce,说明在概率上是付出了对应的算力。谁的算力多,谁最先解决问题的概率就越大。
创币交易
区块中的第一笔交易是笔特殊交易,称为创币交易或者Coinbase交易,这个交易是挖矿节点构造并用来奖励矿工们所做的贡献的。
- 创币交易的输入:创币交易于其他交易的不同点在于其交易输入没有UTXO,也没有“输入脚本”。这个字段被Coinbase数据替代,除开始的几个字节外,矿工可以任意使用Coinbase的其他部分,随意填充任何数据。因此,中本聪在创世区块的Coinbase中填入了这样的数据 “The Times 03/Jan/ 2009 Chancellor on brink of secondbailout for banks”。
- 创币交易的输出:由挖矿胜出的矿工构建并将创币奖励和矿工费一起支付给了自己的比特币钱包地址。
Coinbase奖励和矿工费
矿工们在挖矿过程中会得到两种类型的奖励:创建新区块的新币奖励,以及区块中所含交易的交易费。比特币的货币是通过挖矿发行的,大约每四年减少一半。2009年1月每个区块奖励50个比特币,到2012年11月减半为每个区块奖励25个比特币,现在每个新区块奖励12.5个比特币。比特币挖矿奖励以指数方式递减,直到2140年所有的比特币全部发行完毕,不会再有新的比特币产生。
例如:隔壁老王的挖矿节点构造了一个创币交易,支付给自己12.59094928枚比特币,其中12.5个比特币是Coinbase奖励,0.09094928比特币是矿工费。
06 新区块连接到区块链
比特币交易生命周期的最后一步是将新区块连接至有最大工作量证明的链中。一个节点一旦验证了一个新的区块,它将尝试将新的区块连接到到现存的区块链组装起来。
节点维护三种区块:第一种是连接到主链上的区块,第二种是从主链上产生分支的(备用链)区块 ,最后一种是在已知链中没有找到已知父区块的。在验证过程中,一旦发现有不符合标准的地方,验证就会失败,区块会被节点拒绝并不会加入到任何一条链中。
如果节点收到了一个有效的区块,而在现有的区块链中却未找到它的父区块,那么这个区块被认为是“孤块”。孤块会被保存在孤块池中,直到它们的父区块被节点收到。
每一个节点总是选择并尝试延长代表累计了最大工作量证明的区块链,也就是最长的或最大累计难度的链,只要所有的节点选择最长累计难度的区块链,整个比特币网络最终会收敛到一致的状态。
有以下 4 个概念需要展开理解,用以更加深入的理解“新区块连接到链”的一些细节:
- 创世区块
- 难度目标与难度调整
- 区块链的分叉
- 区块浏览器
创世区块
区块链里的第一个区块创建于2009年,被称为创世区块。它是区块链里面所有区块的共同祖先,这意味着你从任一区块,循链向后回溯,最终都将到达创世区块。
创世区块的哈希值为:000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
在区块浏览网站 (blockchain.info) 搜索这个区块哈希值,你会发现这个哈希值来描述这一区块内容的页面:
难度目标与难度调整
比特币的区块平均每10分钟生成一个。这就是比特币货币发行速率和交易达成速度的基础,必须始终保持恒定。随着技术发展,计算机性能将飞速提升。此外,参与挖矿的人和计算机也会不断变化。为了能让新区块的保持10分钟一个的产生速率,挖矿的难度必须根据这些变化进行调整。
2009年12月30日,比特币挖矿难度首次增长。寻找一个比特币区块需要整个网络花费10分钟来处理,每发现2,016个区块时会根据前2,016个区块完成的时间对难度进行调整。
New Difficulty = Old Difficulty * (Actual Time of Last 2016 Blocks / 20160 minutes)
区块链的分叉
分叉发生在两名矿工在较短的时间内,各自都算得了工作量证明解的时候。两个矿工在各自的候选区块一发现解,便立即传播自己的“获胜”区块到网络中,先是传播给邻近的节点而后传播到整个网络。
由于每个矿工的区块数据都不一样,所以他们解题得出的结果也是不一样的,都是正确答案,只是区块不同。区块链在这个时刻,出现了两个都满足要求的不同区块。不同的矿工看到这两个区块是有先后顺序的,通常情况下,矿工们会把自己先看到的区块复制过来,然后接着在这个区块开始新的挖矿工作。这时分叉就产生了。
从分叉的区块起,由于分叉的链上矿工的数量不同,因此算力也有差别,两条链的增长速度也是不一样的,总有一条链的长度要超过另一条。当矿工发现全网有一条更长的链时,他就会抛弃他当前分叉的链,而继续在更长的主链上进行挖矿工作。
区块浏览器
用户想要浏览区块链信息,就得用区块链浏览器。每一个区块所记载的内容都可以从区块链浏览器上进行查阅。区块链浏览器可以说是区块链信息浏览的主要窗口。
以太坊的区块浏览器如下图所示:
总结
比特币挖矿通过人性解决了区块链的维护问题,这也解释了比特币系统为什么能稳定运行了8年,也使得比特币成为区块链技术如此众多的应用中生命力最为旺盛的一个。“中本聪”对于人性的利用,让人们在为获得利益的挖矿中,维持着这个系统的运转。但矿机的出现使得比特币的去中心化并不完美,所以对于比特币的创新和改进也从未停止,想了解更多,可以阅读我的上一篇文章《一篇文章,看透500多种数字货币哪些是真正有价值的技术创新》,介绍了如何进一步解决矿机对整个区块链网络带来的影响。
深度理解区块链技术
感兴趣的同学可以进一步扩展阅读:
- 什么是椭圆曲线加密算法(secp256k1)?
- 什么是SHA256和RIPEMD160?
- 什么是P2SH (Pay-to-Script Hash)和多重签名地址?
- 什么是交易脚本,P2PKH( Pay-to-Public-Key-Hash)交易?
- 什么是Merkle树和简单支付验证(SPV)?
对于区块链深度的数据结构和算法不在此继续赘述了,欢迎关注“区块链老垚”,天天分享区块链。
本文由 @ 区块链老垚 原创发布于人人都是产品经理。未经许可,禁止转载。
题图来自 Pixabay,基于 CC0 协议
非常棒,把区块链运行的逻辑说的很明白了,这文章精品!就是老垚怎么不更新文章了呢?
作为初学者,我觉得这是目前我看到过的最好的比特币介绍文章。
我了解区块链已经有将近一年,可以说,这是我见过的写区块链科普写的最好的一篇,不过评论中还是有大部分人看不懂,那估计是了解不够多,如果我一刚开始就来看的话估计也会看不懂,但是有了点基础之后来看这篇简直觉得写的太好了。
如何理解比特币没有账户余额的概念呢?用户可以赚取比特币,可以消费比特币,理论上最后会存在余额啊?
写的太深了,越看越蒙…. 🙁
不明觉厉
我感觉写此类文章的都是很懂这个领域的高手,都在试图用自己的理解来解释什么事区块链,但我这个外行感觉每篇文章都差不多,不理解的还是没理解。和一楼说的一样,我等读书还是太少~,感谢作者的精彩分享。
成功的深入,但并未浅出,我等读书还是太少,不懂 arrow:
😉