一文学完比特币

333 阅读13分钟

学之前先看看一下比特币的价格和趋势图,可以看出比特币的价格波动一直以来都挺大的,目前处于低谷期。 image.png 比特币的涨幅与人们对区块链的认可程度息息相关。

按照惯例,先来学习一下比特币的历史。

image.png 图片来自永远的杰西

上图总结了比特币的发展的重要的时间节点。

重要人物:中本聪

中本聪在07年5月开始编写比特币,2008年10月发表白皮书,一直是匿名的状态活跃在社区里。在2010年后他就将比特币项目交给了社区的其他成员。 有人说中本聪退出比特币,比特币才真正地去中心化,因为中本聪在比特币里的权力太大了。

最近看了个文章说美国政府知道中本聪是谁,是一个四个人的团队。真假就不知道了。

中本聪为什么要发明比特币?

对抗通货膨胀

中本聪在创世区块留了这么一句话:“当时正是英国财政大臣第二次出手纾解银行危机之时。”
中本聪想创建一个不需要政府发币的系统来对抗通货膨胀

其实通货膨胀在没有政府的情况下也会产生,不过中本聪想解决的是恶性通货膨胀。

介绍

背景: 需要一个电子支付系统,建立在密码学证明基础上,允许双方直接转账而不需要一个信任的第三方。
定义:比特币是一种加密数字货币

  • 比特币是一个分布式点对点网络系统。
  • 通过名为“挖矿”的过程产生。
    比特币协议包括了内置算法,调节网络中的挖矿功能
  • 比特币是综合技术集合。
    *比特币协议:去中心化点对点网络。
    区块链:公共交易账簿
    分布式挖矿:去中心化、数学、确定性货币发行
    交易脚本:去中心化的交易验证系统 CUI *

交易

比特币并不是币,他是一个数字金额。通过交易,进行余额的改变。

image.png

交易流程

image.png

1、比特币交易的创建:比特币交易可以被任何人在线上或线下创建,但要使交易有效,则需要由一个或多个私钥签名,表明具备交易中发送方地址所指向的比特币资金的所有权。

2、比特币交易广播到整个P2P网络:一笔比特币交易数据约有300到400字节,经过签名但不会泄露任何机密信息、私钥或密码,可以被公开传播。比特币交易可在任意网络环境下发送到比特币网络。每个节点都将从网络中收集交易数据并广播给相连接的其他节点。在传播每一笔交易之前,节点均进行独立验证,确保交易有效性(交易的输入,即上一个交易的输出未动用过,属于UTXO),异常交易无法在网络中传播。比特币网络是一个点对点网络,交易的扩散非常迅速,就像指数级扩散的波一样,几秒钟之内全网节点都会收到。

3、比特币交易验证与挖矿:每个节点维护了一个交易池,存放临时的未经确认的交易。节点从交易池中选择一系列交易构成一个区块,基于自身算力找到一个具有足够难度的工作量证明,找到后向全网所有节点广播此区块。

4、比特币交易确认:当包含在区块中的所有交易都是有效的且交易输入未动用(UTXO),其他节点才会接受这个新的区块,链接到自己的区块链的尾部。

5、交易记录:交易得到全网的6个确认之后,便永久的记录在区块链中。

共识

比特币采用POW共识机制

1.每产生一个新的交易向全网广播。

2.其他节点将收到的交易信息纳入一个候选区块中,并将其他很多交易一起打包在一起。

3.其他节点都尝试在自己的候选区块中进行具有足够难度的工作量证明(POW)。

4.当某个节点完成了工作量证明(POW),向全网广播此区块的完成结果。(挖矿过程)

5.其他节点验证其完成结果。

6.其他节点若验证通过,才能将此区块添加到区块链中

第三步节点完成工作量证明是重点,过程如下:

工作量证明(POW)机制

工作量证明的实质是:尝试大量的随机数来进行哈希运算。

具体是找到一个随机数加入块头中,计算区块的块头的哈希值,使得计算的哈希结果小于或等于块头中目标值,公式如下:

SHA256(SHA256(Block_Header)) <=target

image.png

即只需要对区块头进行两次SHA256运算即可,得到的值和目标值进行比较,小于目标值即可。

如果验证通过,则表明已经有节点成功解迷,自己就不再竞争当前区块打包,而是选择接受这个区块,记录到自己的账本中,然后进行下一个区块的竞争猜谜。网络中只有最快解谜的区块,才会添加的账本中,其他的节点进行复制,这样就保证了整个账本的唯一性。

1.工作量证明函数

在比特币中使用的是SHA256算法函数,是密码哈希函数家族中输出值为256位的哈希算法。

2、 区块

image.png

3、难度值

关于难度值,我们直接看公式: 新难度值=旧难度值*(过去2016个区块花费时长/20160分钟) tips:难度值是随网络变动的,目的是为了在不同的网络环境下,确保每10分钟能生成一个块。 新难度值解析:撇开旧难度值,按比特币理想情况每10分钟出块的速度,过去2016个块的总花费接近20160分钟,这样,这个值永远趋近于1。

目标值=最大目标值/难度值 目标值解析:最大目标值为一个固定数,若过去2016个区块花费时长少于20160分,那么这个系数会小,目标值将会被调大些,反之,目标值会被调小,因此,比特币的难度和出块速度将成反比例适当调整出块速度。

比特币区块的结构图

image.png

区块头主要用来本区块的一些相关属性
区块体则用来存储真实的交易数据记录

1.区块头分析

区块前80个字节是区块头。

{

   "hash": "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506"

    "ver": 1,     "prev_block": "000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250",

    "mrkl_root": "f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766",

    "time": 1293623863,

 "bits": 453281356,

    "nonce": 274148111

}

字节字段说明
4版本区块版本号,表示本区块遵守的验证规则
32父区块头哈希值前一区块的哈希值,使用SHA256(SHA256(父区块头))计算
32Merkle根该区块中交易的Merkle树根的哈希值,同样采用SHA256(SHA256())计算
4时间戳该区块产生的近似时间,精确到秒的UNIX时间戳,必须严格大于前11个区块时间的中值,同时全节点也会拒绝那些超出自己2个小时时间戳的区块
4难度目标该区块工作量证明算法的难度目标,已经使用特定算法编码
4Nonce为了找到满足难度目标所设定的随机数,为了解决32位随机数在算力飞升的情况下不够用的问题,规定时间戳和coinbase交易信息均可更改,以此扩展nonce的位数

说明:

  • 版本、父区块头哈希值和Merkle根采用的是小端格式编码,即低有效位放在前面。
  • 时间戳表示的是自1970年1月1日0时0分0秒以来的秒数

2.区块体分析

Coinbase交易信息分析

一个区块第一个交易规定为coinbase交易,即由挖矿产生的比特币奖励,目前挖出每个区块的奖励是6.25个比特币 除了挖矿奖励,“矿工”的激励还有新增账本记账的手续费,在未来比特币总量不增加之后,后者会成为矿工的主要收入。

{

"hash": "8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87",

"ver": 1,

"vin_sz": 1,

"vout_sz": 1,

"lock_time": 0,

"size": 135,

"in": [{

"prev_out": {           "hash": "0000000000000000000000000000000000000000000000000000000000000000", "n": 4294967295

},

"coinbase": "044c86041b020602" }],

"out": [{ "value": "50.00000000",        "scriptPubKey": "041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84 OP_CHECKSIG",

"next_in": { "hash": "f3e6066078e815bb24db0dfbff814f738943bddaaa76f8beba360cfe2882480a", "n": 12         } }], "nid": "70ab531a68f973f7d20b8260cb5e7fecba3699c48715b8b44539ff9776d0b88e" }

字节字段描述
4版本这笔交易参照的规则
1-9输入计数器包含的交易输入数量
32交易哈希不引用任何一个交易,值全部为0
4交易输出索引固定为0xFFFFFFFF
1-9Coinbase数据长度coinbase数据长度
不定Coinbase数据在V2版本的区块中,除了需要以区块高度开始外,其它数据可以任意填写,用于extra nonce和挖矿标签
4顺序号值全部为1,0xFFFFFFFF
1-9输出计数器包含的交易输出数量
8总量用聪表示的比特币值
1-9锁定脚本大小用字节表示的后面的锁定脚本长度
不定锁定脚本一个定义了支付输出所需条件的脚本
4锁定时间一个区块号或UNIX时间戳

3.交易信息记录

下面来看下普通的交易记录。

{ "hash": "fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4",
"ver": 1,
"vin_sz": 1,
"vout_sz": 2,
"lock_time": 0,
"size": 259,
"in": [{
"prev_out": {
"hash": "87a157f3fd88ac7907c05fc55e271dc4acdc5605d187d646604ca8c0e9382e03", "n": 0 }, "scriptSig": "3046022100c352d3dd993a981beba4a63ad15c209275ca9470abfcd57da93b58e4eb5dce82022100840792bc1f456062819f15d33ee7055cf7b5ee1af1ebcc6028d9cdb1c3af774801 04f46db5e9d61a9dc27b8d64ad23e7383a4e6ca164593c2527c038c0857eb67ee8e825dca65046b82c9331586c82e0fd1f633f25f87c161bc6f8a630121df2b3d3"

}],

"out": [{ "value": "5.56000000",
"scriptPubKey": "OP_DUP OP_HASH160 c398efa9c392ba6013c5e04ee729755ef7f58b32 OP_EQUALVERIFY OP_CHECKSIG",
"address": "1JqDybm2nWTENrHvMyafbSXXtTk5Uv5QAn",
"next_in": {
"hash": "5aa8e36f9423ee5fcf17c1d0d45d6988b8a5773eae8ad25d945bf34352040009",
"n": 6
}
},

{ "value": "44.44000000",
"scriptPubKey": "OP_DUP OP_HASH160 948c765a6914d43f2a7ac177da2c2f6b52de3d7c OP_EQUALVERIFY OP_CHECKSIG",
"address": "1EYTGtG4LnFfiMvjJdsU7GMGCQvsRSjYhx",
"next_in": {

"hash": "220ebc64e21abece964927322cba69180ed853bb187fbc6923bac7d010b9d87a",

"n": 0
} }

],

"nid": "fc7704fdd7ec5e69163e51b827fea2133990a26defee2b475408b3c16fd9a968" }

in : 计划花费UTXO的来源(包含解锁脚本)
out : 计划生成几个UTXO,分别给谁,每个UTXO里有多少BTC.(包含锁定脚本)

解锁脚本

"prev_out": {
"hash": "87a157f3fd88ac7907c05fc55e271dc4acdc5605d187d646604ca8c0e9382e03", "n": 0 }, "scriptSig": "3046022100c352d3dd993a981beba4a63ad15c209275ca9470abfcd57da93b58e4eb5dce82022100840792bc1f456062819f15d33ee7055cf7b5ee1af1ebcc6028d9cdb1c3af774801 04f46db5e9d61a9dc27b8d64ad23e7383a4e6ca164593c2527c038c0857eb67ee8e825dca65046b82c9331586c82e0fd1f633f25f87c161bc6f8a630121df2b3d3" }]

vin : 交易的输入。可以有多个输入,每一个输入都说明了他是引用的哪一比交易的输出。这里可以理解为 我本次交易的钱是从哪来的。 vout: 交易的输出,可以有多个,本次交易的钱我可以转给多个不同的地址,包括给自己找零的钱。可以理解为 我本次交易的钱都给了哪些人。

prev_out:引用的交易id.这里及指明了我的钱是从这笔交易来的
n: 在交易中第几个vout是我的。这里是vout的索引 ,0 也就是第一个
scriptSig > asm : 解锁脚本 这个信息包含以下两个内容
sig 我的私钥对 prev_out hash的加密,这里的prev_out hash是我引用的交易 PubKey 我的公钥

锁定脚本

"out": [{ "value": "5.56000000",
"scriptPubKey": "OP_DUP OP_HASH160 c398efa9c392ba6013c5e04ee729755ef7f58b32 OP_EQUALVERIFY OP_CHECKSIG",
"address": "1JqDybm2nWTENrHvMyafbSXXtTk5Uv5QAn",
"next_in": {
"hash": "5aa8e36f9423ee5fcf17c1d0d45d6988b8a5773eae8ad25d945bf34352040009",
"n": 6
}
},

1.value: 我要支付的钱金额
2.scriptPubKey :
addresses: 收款人的地址
asm: 锁定脚本
. OP_DUP OP_HASH160 c398efa9c392ba6013c5e04ee729755ef7f58b32 OP_EQUALVERIFY OP_CHECKSIG 上面的每一个操作码都有固定的含义对应着需要做不同的操作。有的做加法运算,有的减法,有的是做加密运算。总之你可以理解为 不同的操作码 有不同的用处。

P2PKH为例说明交易脚本的执行过程,并给出压栈出栈的顺序

image.png P2PKH脚本的执行指针执行过程和栈上变化如下:

image.png

默克尔树的作用

image.png

image.png

比特币验证

比特币交易广播到其他节点时其他节点要先进行验证。

验证的目的

image.png

验证三个方面

  • 账号所有权
  • 比特币所有权
  • 交易所有权

账号所有权

image.png

image.png

在比特币诞生初期,中本聪为了比特币系统的安全和稳定,防止比特币系统被攻击而把区块大小设置为1M。在当时比特币用户量少,比特币交易是不存在拥堵问题的。

随着比特币网络的发展,单个区块存储的交易信息越来越多,1MB区块仅能容纳2000条左右交易,

交易量大时需要排队等待区块写入确认,交易网络拥堵问题越来越严重,为此也出现了解决容量问题的几个方案。

这几个方案下一文接着说