比特币

2019-03-29 15:36:20 浏览数 (1)

区块链

什么是区块链?

区块链是一种分布式的去中心化的数据库。

比特币

什么是比特币? 比特币本质是一个记账簿。 它是一个去中心化的网络,每一个节点称为矿工。 记账的方式: 发生比特币交易时,需要加入这个比特币网络,交易双方为比特币网络的节点,例如:A向B转账 这个转账申请加入区块链网络,因为这个网络是由很多节点组成的,需要一半以上的节点的同意,才可以加入网络,也就是51%的节点的同意。好,同意之后,就可以在这个网络记录起来了。 那这个交易记录存放在哪里了,交易记录存放在一个称为区块的地方,这个网络每隔10分钟就会产生一个新的区块,存放这个区块产生时间和上一个区块产生时间内的所有被同意的交易,也就是这10分钟的交易。 问题:如何产生第一个区块

刚才讲到,这个网络由很多个节点组成,那这个新的区块到底是由哪个节点产生?这是一个需要思考的问题 事实上,所有的节点都想当第一个,因为: 第一个生成新区块的节点有一项特权,可以在新生成的区块中插入一条特殊交易记录:凭空向一个地址转入一定数额的比特币。 “凭空”的意思是不需要输入UTXO,这些比特币是凭空产生的,是作为产生新区块的奖励。这个特殊交易称为“创币交易”,因为这一过程也是发行新比特币的过程,这就是为什么产生新区块被称为“挖矿”。 那么奖励的数额有多大呢?创建新区块的奖励数额是不定的:第一个区块奖励的是50个比特币,随后每产生210000个区块这一数字就递减50%,直到变为0。目前区块链的长度已接近50W,因此每次奖励12.5个比特币。通过以下公式便可算出,比特币的上限是2100W个。   除了创块奖励外,创块的收益还包括所有交易的交易费。因为每个区块记录了这10分钟内的交易,交易的时候需要收取交易费,这些交易非也会给创建第一个区块的节点。 那么,

如何才能创建一个新区块呢?通过解决一个问题:即找到一个nonce值,使得新区块头的哈希值小于某个指定的值,即区块头结构中的“难度目标”。 区块头中的信息,在挖矿前大部分已经是固定下来的,或者是可计算的。

image

版本号 跟随比特币客户端而定,一段时间内不会改变。即使要改变,也会有比特币的核心开发人员来协调升级策略,这个可以理解为一个静态常数。

前一区块的哈希摘要

一次哈希即可。前一区块已经是打包好的。

默克尔树的根

刚才已经得到了结果,根据本次交易包含的交易列表得到。

时间

取打包时的时间。也不需要很精确,前后几秒,几十秒也都可以。

难度目标

参考上两周产生的区块的平均生成时间而定。两周内如果平均10分钟产生一个区块的话,两周会产生2016个区块,软件会计算最新的2016个区块生成的时间,然后做对比,随之调整难度,使得接下来产生的区块的预期时间保持在10分钟左右。因为最近的2016个区块已经确定,所以这个数字也是确定的。

随机数nonce

这个就是挖矿的目标了。这是一个32位的数字。

随机数可以变化,而且要从0试到最大值2^32。直到最后出现的hash结果,其数字低于难度目标值。不过以现在的计算机算力,一台矿机用不了一秒就把全部的变化可能计算完了,所以还需要改变区块内部的创币交易中的附带消息,这样就让merkle root也发生了变化,从而有更多的可能去找到符合要求的nonce。

代码语言:javascript复制
block_header = version   previous_block_hash   merkle_root   time   target_bits   nonce

for i in range(0, 2**32):

     if sha256(sha256(block_header)) < target_bits:       

        break    

    else:        

       continue

比特币的交易如何确认

先讲一个概念:UTXO,指未花费的交易输出

比特币的记账模式跟传统的中心化记账模式有一个比较难理解的区别:比特币没有账户的概念。

具体来说,比特币的记账系统,是通过记录和确认每一笔交易本身来记账,是交易本身,是交易的行为本身,也就是A向B转账这个过程,而不是记录A和B的余额变动,而A及B的最终余额是通过扫描交易数据计算出来的。

而传统的记账系统(银行),是通过记录和保存每个账户的余额变动数据来验证交易的,也就是说,每一次交易由中心记账系统把不同账户(一般是2个),的余额进行相应的调整并保存,完成了一个交易的记录。A向B转100万,那么先把A的余额减少100万,同时把B的余额增加100万,会计上说的,有借必有贷,借贷必相等。

为什么会这样?为什么比特币系统,不采取实时更新账户余额的方式来记账?主要有两个原因:

1.节省算力和储存空间。因为如果采取余额模式,为了避免双重支付,即使你的账户没有发生变化,比特币系统里任何一个客户端(钱包)发生一笔交易和变动,所有的客户端都有同步数据,否则,若B没有同步更新整个系统中的所有账户余额信息,在A给B转账时,B无法知道A的账上是否有足够的余额,甚至有可能,A把同一个比特币同时转给了B和C,而B和C由于都没有更新A的余额信息,都不知道A的账上其实没有那么多钱。

而传统的支付系统不一样,每一次交易,只有付款方和收款方的余额变动,顶多再加上中心化的服务器数据发生变动,所以只要同步很少的数据(这个是相对于区块链来说),事实上由于所有记账都是中心服务器来完成,其实不需要额外同步,只需要在完成记录的同时储存数据就可以了。所以在数据储存上中心化的系统是有优势的,如果比特币也采用这种余额思路,那么必定会失败(虽然现在也还不好说一定能成功)。

2.如果采取记录账户余额的方式,那么在不同节点更新存在时间差的时候,很容易出现双重支付,简单来说,A把同1各比特币转给B和C,由于BC的地理位置不同,他们附近的节点不同,有可能都确认为交易,虽然随着时间的推移,比特币系统会达成竞争共识,只确认一个交易,但,BC两人都提供了商品给A,最后,肯定有一个人蒙受损失。

那比特币系统是怎么做的呢:那就是只确认交易本身,直记录交易输入和输出:每笔比特币交易都有输入和输出,别人付给你的钱是“交易输入”(对你来说),你收到的钱如果被你支付出去了,叫做“交易输出”,你收到但是还没有支付出去的钱叫做“未花费交易输出”(UTXO),这是一种待支付的状态。

矿工们把每一次交易本身的数据(输入和输出)打包到区块之中,通过竞争计算,确保不可串改,实际上如果得到6个区块的确认,那么全球的算力加起来都没法串改。

如果需要确认余额,那么就用客户端(钱包)扫描某一个账户的输入、输出数据,就可以算出这个账户的余额,相比更新所有账户的余额数据来说,简直太轻松,不到1秒钟就可以搞定。

说完了比特币系统记账的方式,下面讲讲具体支付过程中,双方如何确认交易已经完成了?还是先讲一个关键概念:

SPV:简单支付验证。我们在用比特币交易的时候,必须确定交易成功,才会提供相应的服务或者商品,也就是一手交钱一手交货,确认收到钱,才交货。为什么说是“简单验证”呢?因为这种验证方法,不需要下载所有的交易数据,只需要下载区块头数据就可以验证。

那什么是区块头呢?

简单回顾一下,区块链对交易的记录,是把一段时间内的交易数据,打包到一个区块中,然后随着时间的推移,区块不断累积叠加,环环相扣,形成区块链,区块链越长,越难修改,一般来说经过6个区块以后,全球的计算机加起来都无法修改。

每个区块头信息代表着一个区块,就像是区块的身份证一样,你看到我的身份证就知道我是谁,就可以在脑海中浮现出我的身高、样貌,甚至职业、爱好等信息,在区块链世界里,系统通过区块头,可以识别出区块信息的方方面面。

0 人点赞