比特币原理细节深入解析

一,秘钥、公钥与BTC地址

由随机数生成秘钥

BTC软件使用操作系统底层的随机数生成器来产生256位的熵(随机性),也就是说首先在1-2256之间生成一个随机数,之后再用SHA256算法生成一个256位的二进制数(即64位的十六进制)。

由秘钥生成公钥

再通过椭圆曲线算法可以由秘钥生产公钥,这个过程是不可逆的,也就是说无法通过公钥反推出秘钥,这样一来就保证了秘钥的安全性。

由公钥生成BTC地址

BTC地址由公钥通过单向的哈希加密算法(SHA256和RIPEMD160)获得,生成过程如下:

钱包:管理秘钥的容器

BTC钱包是管理秘钥的容器。BTC钱包只包含秘钥,没有包含BTC,用户用秘钥来签名交易,从而以此来证明他们拥有交易输出,BTC是以交易输出的形式存储在区块链中。

二,交易
UTXO
在BTC的世界里,既没有账户,也没有余额,只有分散在区块链里的UTXO。称为“未花费的交易输出”(unspent transaction outputs),即为UTXO。
当我们说用户的钱包已经“收到”BTC时,我们的意思是,钱包已经检测到了可用的UTXO。 因此,用户的BTC“余额”其实是指用户钱包中可用的UTXO总和,而他们可能分散在数百个交易和区块中。 “一个用户的BTC余额”,这个概念是BTC钱包应用创建的派生之物。BTC钱包可通过扫描区块链并聚集所有属于该用户的UTXO来计算该用户的余额 。大多数钱包维护一个数据库或使用数据库服务来存储所有UTXO的快速参考集,这些UTXO由用户所有的秘钥来控制花费行为。

一个UTXO可以是“聪”(satoshi)的任意倍数(整数倍)。就像美元可以被分割成表示两位小数的“分”一样,BTC可以被分割成八位小数的“聪”。(BTC的最小单位虽然是「聪」,但基本单位却是「UTXO」,别搞混了。)且尽管UTXO可以是任意值,但一旦被创造出来,即不可分割。这是UTXO需要值得被强调的一个重要特性:UTXO是面值是为“聪”的离散(不连续)且不可分割的价值单元,所以一个UTXO只能在一次交易中作为一个整体被消耗。

交易过程

上图中的输入1-4,在交易前,是4个独立的UTXO;而输出1-3,是新产生的3个独立的UTXO,可以作为下次交易的输入。

签名

每个UTXO皆对应某个BTC地址,所以只有这个BTC地址对应的秘钥才能对这个UTXO进行签名,以便使其作为下一次交易的输入。

故此,当BTC钱包显示某个BTC地址总金额时,实际它是统计该地址对应的所有UTXO,只有这个地址对应的秘钥才能使用(或消费)这些UTXO,所以务必保存好你的秘钥。

找零

UTXO是BTC交易的基本单位,也就是说它不可分割。但是在现实中,如果BTC作为一种支付货币,难免会面临找零的情况,它是怎么处理的呢?

其实很简单,就是把自己的地址也作为交易输出的一部分。举个例子,假设梅梅需要支付1.5个BTC给明明,但是当前梅梅所拥有的最小UTXO为1.8个BTC,也就是说需要找零0.3个BTC,那么这个交易的输入为梅梅的1.8个BTC,输出为明明的1.5个BTC和梅梅的0.3个BTC。

交易费

一般来说BTC交易的输入总额不等于输出总额,其中的差额就是交易费。为什么会有交易费呢?后续我在介绍挖坑的原理中会详细介绍,目前你只需要简单知道这个交易费是给矿工奖励的就行,因为BTC的交易需要依赖于矿工挖矿确认,而矿工确认的优先级是根据交易费大小排序的,因此谁出的交易费越高,谁的交易就越有可能被尽早确认。大家知道,BTC被人诟病的其中一个主要问题就是交易性能很差,TPS(即每秒交易笔数)大概为7左右,远远低于银行网关,更别提支付宝、微信支付了。

挖矿的奖励(Coinbase交易)

每个区块的第一个交易比较特殊,它没有输入,也就是说是凭空产生的(大家可以想象下印钞机),叫做Coinbase交易,它是给挖矿者的奖励,金额从50BTC开始,每4年递减,目前是12.5BTC。

三,网络
BTC采用去中心化的P2P(点对点)的网络架构,所谓P2P是指网络中的每个节点都是对等的,不存在「特权」节点,这也是BTC「去中心化」的底层实现。

虽然BTCP2P网络中每个节点是对等的,但根据其功能不同,分为如下几种节点类型:

网络路由节点

拥有网络路由功能的节点都可以作为网络路由节点,所有的网络路由节点通过TCP协议连成一张巨大的P2P网络。

这里需要注意,对于单个节点来说,它并不需要与其它所有节点建立直接连接,否则性能会成为瓶颈,它只需要跟其相邻的几个节点建立直接连接即可,和其它节点是间接连接。

全节点

全节点是指包含完整区块链数据库的节点,我们知道BTC从2009年1月诞生以来,平均每10分钟产生1个区块,目前为止已经产生了51万个区块,至少需要占用150G的磁盘空间。BTC刚诞生的时候,区块链数据库很小,大部分都是全节点,但随着区块链数据库越来越大,全节点的比例在不断缩小。

简单支付验证(SPV)节点

对于跑在智能手机上的钱包客户端来说,下载整个区块链数据库肯定是不可行的。于是,简单支付验证(SPV)节点孕育而生,SPV节点只需要下载区块头,不用下载区块体(即交易信息),因此它占用的空间大大减少。

独立矿工节点

所谓独立矿工节点是跟矿池相对立,是指不依赖其它节点的算力、单独进行挖矿的节点,因此它拥有完整的区块链数据库。在BTC前期,由于全网的算力不大,独立矿工还有生存空间,但随着BTC价格一路攀升,全网算力越来越大,独立矿工节点的生存空间越来越小,除非是大的数据中心。

矿池及其挖矿节点

前面说过,随着BTC全网算力越来越大,独立矿工挖到矿的概率越来越小,因此就产生了矿池。所谓矿池是指很多个挖矿节点集合在一起组成挖矿联盟,如果挖到矿,所获得的收益根据挖矿节点贡献的算力分摊,当然矿池还会收一部分管理费。这个挖矿联盟一般基于Pool或Stratum协议。

综上所述,BTC网络架构如下图所示:

四,挖矿
BTC挖坑的过程简单说就是:矿工使用挖矿节点尝试解一道数学难题,谁先解出来谁就能获得新产生的BTC和交易费。具体过程如下:

整合交易至候选区块

挖矿节点不断监听BTC网络中的交易信息,并将这些交易信息暂存到自己的内存池里,挖矿节点会根据以下信息对这些交易进行排序:

1)优先选择「块龄」更大的交易,「块龄」是指自该交易被记录到区块链为止所经历过的区块数,即这个交易在区块链中的深度。简单说,就是会优先处理那些旧的交易,这样确保即使没有交易费的交易最终也能得到确认,只是要等的时间比较长一些。

2)优先选择相对交易费更高的交易,也就是说出的交易费越高,越有可能越快得到确认。因此如果你想你的交易被尽快确认,应该主动多付些交易费。

挖矿节点根据上述条件排序后生成候选区块,同时会在候选区块里加入一笔特殊的交易-「Coinbase交易」,该交易是候选区块的第一笔交易,它会把新产生的BTC(当前是12.5个)和交易费发送给矿工的地址,是给矿工挖矿的奖励。

求解数学难题使候选区块成为合法的新区块(PoW)

构建候选区块完毕后,矿机就要开始使用PoW(Proof of Work,工作量证明)算法来获得一个正确的nonce值,来向公众证明新区块是它挖的。

所谓的PoW算法其实并不复杂,假设你是一个矿机,你会不断的尝试改变nonce值,并计算区块头的哈希值,如果你足够幸运,算出的哈希值正好小于难度值,说明你的这个nonce值是有效的,表示你成功挖到矿了,于是你会迅速的向全网广播,告诉大家这个区块我已经挖到了,你们继续挖下一个吧。但现实更多的情况是,你尝试了成千上亿次后,还是没有猜出有效地nonce值,却收到了其它矿工发来的通知说他已经挖到了,于是你只好放弃之前的所有工作,继续尝试挖下一个区块。上述描述的整个过程大概每10分钟会重复一次,生生不息,永不停止。

看到这里,相信很多人会有以下两个疑问。

第一个疑问是「我难道只能不断尝试不同的nonce值这种暴力破解的笨办法吗?是否存在更好的办法呢?」。截至目前数学家已经证明没有比暴力破解更好的办法,所以这也是很多人诟病BTC不环保、空耗大量算力的原因,但同样这也是BTC能够维持一个去中心化共识的根本原因。

第二个疑问是「难度值是如何确定的?」。BTC为了确保平均每10分钟出个新区块,它必须能够动态调整难度值,起初由于全网算力很小,因此难度值也比较小,但随着全网算力越来越大,难度值必须不断动态增大才行。但大家知道BTC是去中心化的,也就是说从来没有一个中心可以动态调整难度值,那BTC是怎么做到的呢?它把难度值的调整交给了每个全节点(什么是全节点可参考「BTC(4):网络架构」),具体是这样的:每2016个区块调整一次难度值,难度的调整公式是由最新2016个区块的真正花费时长与20160分钟(两周,即这些区块如以10分钟速率所期望花费的时长)比较得出的,如果发现平均时长小于10分钟,说明之前的难度值过小,需要加大难度,反之亦然。

区块链分叉

上述描述的基于PoW算法的挖矿过程可能会产生这样一种状况:假设矿工A挖到了新区块,但由于BTC的节点分布在全球各地,网络传输需要一定的时间,所以在他向全网广播的过程中,正好又有一个矿工B挖到了新区块,他也会向全网广播他挖到的新区块,这时就会出现两个新区块互相竞争的情况,这就是区块链分叉。

那么BTC是怎么解决分叉的问题呢?答案是暂时不解决,就让分叉存在着,相信时间最终来解决。也就是说,这时候BTC网络被分成了两派,一派基于A继续挖新区块,另一派基于B继续挖新区块,随着时间的推移,一定会出现其中一个分叉成为主链,另外一个分支慢慢被放弃。注意:这里谁能成为主链,并不是简单的基于谁先挖到算谁的,而是谁后续能获得大多数节点的认可。

这样又会带来两个问题:

问题1:有可能导致已被确认的交易被取消。比如上述例子我们假设A成为了主链,B被抛弃了,那么B挖到的这个新区块,虽然已被确认是有效的,但由于不是主链,最终会被抛弃,也就是说B创建的这个新区块上的交易都失效了。这也是为什么虽然BTC平均每10分钟生成一个区块,但一个交易真正被确认需要60分钟,因为一般认为经过后续6个区块的确认后,基本就很难被取消了。

问题2:有可能受到51%的算力攻击。假设有个人或机构非常强大,他能控制BTC全网51%的算力,就可能随意强行分叉,并让他的链总是成为主链,那么BTC的共识就崩溃了。虽然理论上是存在这样的可能性,但由于现在BTC全网的算力过于庞大,想要控制51%的算力,等同于不可能。

转载请注明来源:比特币原理细节深入解析

本文链接:https://www.cmezy.com/blog/dk10my

评论0

请先

没有账号? 忘记密码?