最近为什么要写这篇文章?看了很多讲解区块链的文章,发现很多文章要么过于概念化,要么讲一些应用前景和行业判断,要么过于专业晦涩,导致很多没有技术基础的小伙伴很难真正了解区块链技术。基于以上原因,我希望通过一个比特币交易的完整生命周期来解释比特币中的区块链技术。在这个具体的过程场景中,我相信会更容易理解区块链。
基本常识:
区块链不等于比特币。区块链只是比特币系统用来记录交易信息的账本;没有比特币账户余额的概念。所有交易只记录资金的来源和去向。所谓账户余额,是在区块链计算的结果;挖矿奖励是维护整个系统的奖励,鼓励人们使用自己设备的计算资源,共同验证每笔交易的有效性;
假设比特币交易A一旦创建,其生命周期就开始了。随后,交易A将被一个或多个签名加密(这些签名用于表示交易A的资金流动得到资金所有者的许可)。然后将交易A广播到比特币网络中,最早收到广播信息的两三个邻居节点将参与验证交易,同时交易A将在网络中再次广播,直到交易A被网络中的大部分节点收到(所有下载比特币客户端的设备都可能成为这样的节点)。
最后,事务A被参与挖掘的节点验证。事务A与其他最近创建的事务一起打包到块B中,并添加到区块链中。此时,整个区块链被扩展,并增加了一个新的B区。B块被“确认”超过6次就被认为是不可撤销的,因为取消和重建6个块需要巨大的计算量。当事务被打包在一起放入块中时,证明它们需要巨大的计算量,而验证它们已经被证明只需要很小的计算量。
我们简单地将上述交易流程描述细分为以下6个步骤:
生成新的交易签名,加密交易,在比特币网络中传播和整合交易,构建新的区块,挖掘新的区块并链接到区块。我们将详细分析六个交易步骤的具体细节以及所采用的底层技术。在解释每个步骤和具体概念的时候,我会举适当的例子来帮助你理解。如果你还没读,那一定是你读得太快了.
隔壁老王想从钱包里转一个比特币给老张的时候,交易就是老王的钱包构造的。
将比特币交易理解为纸质支票,有助于我们的理解。比特币交易是一种以转账为目的的工具,就像收款人或持票人拿着支票去银行,银行会无条件支付指定金额。并且交易的发起者不一定是签署交易的人。
任何人都可以在线或离线创建比特币交易,即使创建该交易的人不是该账户的授权签署人。就像这种企业里秘书写的支票(发起交易),需要等老板签字交易(数字签名)。
要对“新交易构造”的一些细节有更深入的理解,需要理解以下四个概念:
UTXO交易输出交易输入交易费用
UTXO很好理解。就像账户的余额。它是比特币交易的基本单位,是一种未使用的交易输出,称为未使用的交易输出(简称UTXO),“未使用的交易输出”。UTXO不能再分了。一个UTXO可以是一个“从”的任意倍数,就像美元可以分为“分”一样,“分”也可以。UTXO在区块链被记录,比特币网络以百万计监控所有可用的UTXO。
假设隔壁老王此时拥有1.9个比特币。当隔壁法老收到0.1个比特币时,这个数额在区块链中被记录为UTXO。现在老王拥有的总共2个比特币,也是作为UTXO分发给几百笔交易,几百个区块。其实比特币的地址或者账户余额都没有地方存放,只有老王(主人)锁着的零散的UTXO。
因此,“隔壁老王的比特币余额”的概念是通过扫描区块链并聚合属于用户的所有UTXO来计算用户的余额。
一个比特币交易是一个具有输入和输出值的数据结构,它包含了将一笔资金从初始地址(输入)转移到目标地址(输出)的代码信息:版本规则、输入其数量、输出其数量、时间戳.
每一次比特币交易都会产生一个输出,这个输出会被比特币的账本记录下来。所有的输出都可以创造一定数量的比特币(也就是UTXO)用于支付。这些UTXO会被全网识别记录,主人可以在以后的交易中使用。给隔壁老王送比特币,其实是创造了一个新的UTXO,可以被他用来进行新的支付。
事务输入是指向UTXO的指针。当用户支付时,他的钱包通过选择可用的UTXO来构建交易。
例如:
ng>隔壁老王想要支付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比特币也都将成为交易费,被矿工挖到这份惊喜的“红包”。
网络中节点收到交易信息后,会对交易的合法性进行检查,资金所有者的签名加密是重要的验证依据,检查都通过后,则将交易标记为合法的未确认交易,才会在网络中进行广播。
有以下 4 个概念需要展开理解,用以更加深入的理解“签名加密”的一些细节:
私钥公钥钱包交易脚本
通过在一个密码学安全的随机源中取出一串随机字节,对其使用SHA256哈希算法进行运算,生成了一个256位的数字,这样的一个数字就可以作为私钥。以十六进制格式表示一个随机生成的私钥,即:
1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD
其中一种常见且典型的钱包就是使用“助记码词汇”做为种子,而生成私钥的钱包。这样的单词的序列可以重新创建种子,并重新创造钱包以及所有私钥。在首次创建钱包时,带有助记码的钱包应用程序将会向使用者生成一个12至24个单词,单词的顺序就是钱包的备份。
输出脚本一般由付款方对交易设置锁定,用来对收款方进行权限控制,例如限制必须是某个公钥 (比特币地址) 的拥有者才能花费这笔交易。
输入脚本 (签名脚本) 常常含有一个被用户的私钥生成的数字签名,用来证明自己可以满足交易输出脚本的锁定条件,即对某笔交易中比特币资金的拥有权。
值得注意的是:比特币交易的输入和输出并非只是简单对应了付款人的私钥和收款人的公钥地址,而是还包含了更多的内容,通过脚本可以直接验证交易的有效性,并且实现了更多复杂的交易方式,比如“多重签名脚本”,保证只有自己和第三方钱包共同签名后才可动用输出,这样保证了黑客在攻击了第三方钱包后也无法花掉用户的比特币。
无论交易是否被节点验证有效,交易发起者会收到一条回执消息,包含了此笔交易是否被接受的返回信息。在几秒钟之内,一笔有效的交易就会呈指数级扩散的效率在网络中传播,直到所有连接到网络的节点都接收到它。
值得注意的是:每一个节点在传播每一笔交易之前均进行独立验证。因此,一个异常交易所能到达的节点不会超过一个。所以,比特币网络能有效抵御入侵,避免垃圾信息的滥发和有效拒绝服务攻击。
有以下 4 个概念需要展开理解,用以更加深入的理解“交易传播”的一些细节:
客户端完整节点轻量节点 (SPV) 节点挖矿节点
挖矿节点需要为内存池中的每笔交易分配一个优先级,并选择较高优先级的交易记录来构建候选区块,在区块被填满后,内存池中的剩余交易会成为下一个区块的候选交易。例如,一个挖矿节点从内存池中整合到了全部的交易,新的候选区块包含有418笔交易,总的矿工费为0.09094925个比特币。
现在既然创建好了一个包含418笔交易的候选区块,挖矿节点就准备拿它来挖矿。
有以下 4 个概念需要展开理解,用以更加深入的理解“整合交易”的一些细节:
临时未验证的交易池交易优先级区块结构矿池
区块中用来存储交易的前50K字节是保留给较高优先级交易的,如果区块中有足够的空间,高优先级的交易行为将不需要矿工费。矿工费越高,交易被处理的优先级也越高。
区块头包含三组元数据:
用于连接前面的区块、索引自父区块哈希值的数据;挖矿难度、Nonce(用于工作量证明算法的计数器)、时间戳;能够总结并快速归纳校验区块中所有交易数据的Merkle(默克尔)树根数据。
采矿成为一项团队运动,一群矿工于2010年12月16日一起在slush矿池挖出了它的第一个区块。根据其所贡献的工作量,每位矿工都获得了相应的报酬。此后的两个月间,slush矿池的算力从1 400Mhash/s增长到了60Ghash/s。
一旦某一个挖矿节点在算力竞争中胜出,优先得到了数学难题的答案,会立刻将这个区块发给它的所有相邻节点,这些节点在接收并独立验证这个新区块后,也会继续传播此区块,每个节点都会将它作为新区块加到自身节点的区块链副本中。
有以下 3 个概念需要展开理解,用以更加深入的理解“确认交易”的一些细节:
工作量证明创币交易Coinbase奖励和矿工费
哈希问题具有不可逆的特点,只有通过暴力计算找到问题的答案。一旦获得符合要求的nonce,说明在概率上是付出了对应的算力。谁的算力多,谁最先解决问题的概率就越大。
创币交易的输入:创币交易于其他交易的不同点在于其交易输入没有UTXO,也没有“输入脚本”。这个字段被Coinbase数据替代,除开始的几个字节外,矿工可以任意使用Coinbase的其他部分,随意填充任何数据。因此,中本聪在创世区块的Coinbase中填入了这样的数据 “The Times 03/Jan/ 2009 Chancellor on brink of secondbailout for banks”。创币交易的输出:由挖矿胜出的矿工构建并将创币奖励和矿工费一起支付给了自己的比特币钱包地址。
例如:隔壁老王的挖矿节点构造了一个创币交易,支付给自己12.59094928枚比特币,其中12.5个比特币是Coinbase奖励,0.09094928比特币是矿工费。
节点维护三种区块:第一种是连接到主链上的区块,第二种是从主链上产生分支的(备用链)区块 ,最后一种是在已知链中没有找到已知父区块的。在验证过程中,一旦发现有不符合标准的地方,验证就会失败,区块会被节点拒绝并不会加入到任何一条链中。
如果节点收到了一个有效的区块,而在现有的区块链中却未找到它的父区块,那么这个区块被认为是“孤块”。孤块会被保存在孤块池中,直到它们的父区块被节点收到。
每一个节点总是选择并尝试延长代表累计了最大工作量证明的区块链,也就是最长的或最大累计难度的链,只要所有的节点选择最长累计难度的区块链,整个比特币网络最终会收敛到一致的状态。
有以下 4 个概念需要展开理解,用以更加深入的理解“新区块连接到链”的一些细节:
创世区块难度目标与难度调整区块链的分叉区块浏览器
创世区块的哈希值为:000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
在区块浏览网站 (blockchain.info) 搜索这个区块哈希值,你会发现这个哈希值来描述这一区块内容的页面:
2009年12月30日,比特币挖矿难度首次增长。寻找一个比特币区块需要整个网络花费10分钟来处理,每发现2,016个区块时会根据前2,016个区块完成的时间对难度进行调整。
New Difficulty = Old Difficulty * (Actual Time of Last 2016 Blocks / 20160 minutes)
由于每个矿工的区块数据都不一样,所以他们解题得出的结果也是不一样的,都是正确答案,只是区块不同。区块链在这个时刻,出现了两个都满足要求的不同区块。不同的矿工看到这两个区块是有先后顺序的,通常情况下,矿工们会把自己先看到的区块复制过来,然后接着在这个区块开始新的挖矿工作。这时分叉就产生了。
从分叉的区块起,由于分叉的链上矿工的数量不同,因此算力也有差别,两条链的增长速度也是不一样的,总有一条链的长度要超过另一条。当矿工发现全网有一条更长的链时,他就会抛弃他当前分叉的链,而继续在更长的主链上进行挖矿工作。
以太坊的区块浏览器如下图所示: