bitcoin介绍

持续整理中…

maxVout = MAX_BLOCK_WEIGHT / (WITNESS_SCALE_FACTOR * minTxOutSz);

bitcoin 是什么

一些概念和技术的集合,形成了数字货币生态的基础。
用户使用自己的私钥来证明自己在 bitcoin 网络中的 bitcoin 资产所有权。
私钥是唯一的用来消费交易的必要条件。

最主要的发明是使用分布式计算系统(PoW 算法)来达成交易状态的共识。解决了重复交易

单位:
比特 BTC = 1 BTC
分 cBTC = 0.01 BTC
毫 mBTC = 0.001 BTC
微 μBTC = 0.000001 BTC

钱包

一般功能:创建账号,发起交易,显示交易历史,接收并验证交易,挖矿

分类介绍

有两种主要类型的钱包:

非确定性钱包(nondeterministic wallet)

其中每个密钥都是从随机数独立生成的。密钥彼此无关。这种钱包也被称为“Just a Bunch Of Keys(一堆密钥)”,简称JBOK钱包。

确定性钱包(deterministic wallet)

其中所有的密钥都是从一个主密钥派生出来,这个主密钥即为种子(seed)。该类型钱包中所有密钥都相互关联,如果有原始种子,则可以再次生成全部密钥。确定性钱包中使用了许多不同的密钥推导方法。最常用的推导方法是使用树状结构,称为分级确定性钱包或HD钱包

全节点钱包(如 bitcoin-core 核心钱包),

维护着全部的区块链数据,完全去中心化,同步所有数据;

SPV 钱包 (Simplified Payment Verification)

即验证一笔交易是否存在是否被确认,所以SPV钱包按字面意思是可以进行‘简单支付验证’的钱包

中本聪论文简要地提及了这一概念,指出:不运行完全节点也可验证支付,用户只需要保存所有的 block header 就可以了。用户虽然不能自己验证交易,但如果能够从区块链的某处找到相符的交易,他就可以知道网络已经认可了这笔交易,而且得到了网络的多少个确认

这里有个细节需要注意,SPV指的是 “支付验证”,而不是 “交易验证”。这两种验证有很大区别。
“交易验证” 非常复杂,涉及到验证是否有足够余额可供支出、是否存在双花、脚本能否通过等等,通常由运行完全节点的矿工来完成。
“支付验证” 则比较简单,只判断用于 “支付” 的那笔交易是否已经被验证过,并得到了多少的算力保护(多少确认数)。

冷钱包,热钱包

冷钱包:就是离线钱包,避免黑客攻击。
热钱包:就是在线钱包,可以随时交易,但是有网络风险。

功能介绍

创建账号

生成主密钥(私钥)和钱包地址
钱包地址目前有两种:

  1. 以数字 1 开头的普通地址,通过公钥做 hash 生成的地址。
    脚本中会包含地址所对应公钥的 hash 值,需要用对应的私钥进行签名;
  2. 以数字 3 开头的脚本地址,通过脚本做 hash 生成的地址。
    脚本中会包含某个特定脚本的 hash 值,需要依照特定的脚本校验,若是多重签名地址,用多个私钥来签名。

挖矿(产生新区块)

除创世区块中的交易(genesis block)外,每笔交易必须要有货币来源。
货币来源有两种:

  1. 挖矿奖励,默认50个btc,然后每4年减半
  2. 验证交易的手续费

发起交易

显示交易历史

验证交易

  1. 全节点
    例如:x 付钱给 y,那么 y 如何验证这笔交易呢?
    首先,y 要遍历区块链账本,定位到 x 的账户上,这样才能查看 x 用来支付的账户上是否曾经有足够的金额
    接下来,y 要遍历后续的所有账本,看 x 是否已经支出了这个账户上的钱给别人(是否存在重复消费欺骗)
    然后还要验证脚本来判断 x 是否拥有该账户的支配权。
    这一过程要求 y 必须得到完整的区块链才行。
  2. SPV 轻钱包验证
  • 服务器解决方案,服务器运行全节点钱包,SPV钱包通过web api让服务器验证
  • 通过 BlockHeader 数据验证支付是否被确认

检查发生此项支付的那笔交易是否已经收录于区块链中,并得到了多少个确认。

  • 从网络上获取并保存最长链的所有 block header 至本地;
  • 计算该交易的hash值 tx_hash;
  • 定位到包含该 tx_hash 所在的区块,验证 block header 是否包含在已知的最长链中;
  • 从区块中获取构建 merkle tree 所需的 hash 值;
  • 根据这些 hash 值计算 merkle_root_hash;
  • 若计算结果与 block header 中的 merkle_root_hash 相等,则交易真实存在。
  • 根据该 block header 所处的位置,确定该交易已经得到多少个确认。

如何才能通过 tx_hash 定位到该交易所在的区块?
这里需要访问全节点获取相关数据

通过 getheaders 命令来获取 block headers,可以通过 getdata 命令支持获取指定的 block,
但不支持通过 tx_hash 反向查找所在的 block

为了定位 block,客户端往往不得不下载整个区块链。Bloom filter 解决了客户端检索的问题,原理是 Bloom filter 可以快速判断出某检索值一定不存在于某个指定的集合,从而可以过滤掉大量无关数据,减少客户端不必要的下载量。

网络

节点通过 bitcoin 协议相互通信。

涉及到的技术点

  • 工作量证明(Proof-of-Work)
    Adam Back 在 Hashcash 里提出来的,防止DoS和垃圾信息
  • double-spend attack
    将全部交易计入一本总账、并给交易打时间戳来防范重复消费攻击(double-spend attack)的思想是 Wei Dai 的 b-money 和 Nick Szabo 的 Bitgold 提出来的,
  • P2P 技术
    也早就有多种应用实现
  • 区块链的设计
  • UTXO的采用
  • 智能合约
    比特币交易是首先要提供一个用于解锁UTXO(用私钥去匹配锁定脚本)的脚本(常称为解锁脚本:Signature script),这也叫交易输入,
    交易的输出则是指向一个脚本(称为锁定脚本:PubKey script),这个脚本表达了:谁的签名(签名是常见形式,并不一定必须是签名)能匹配这个输出地址,钱就支付给谁。
  1. 共识机制
  2. 防止篡改
  3. 重复交易(double spending)

比特币总数(21,000,000),总数固定的

比特币由这些构成:
一个去中心化的点对点网络(比特币协议)
一个公共的交易账簿(区块链)
一个去中心化的数学的和确定性的货币发行(分布式挖矿)
一个去中心化的交易验证系统(交易脚本)

POW

用SHA256加密算法不断地对区块头和一个随机数字进行哈希计算,直到出现一个和预设值相匹配的解

比特币交易脚本和脚本语言

难度调整
整个网络每产生2,106个区块后会根据之前2,106个区块的算力进行难度调整。

Wallet
Bitcoin Address + Private key = Bitcoin Wallet

收入:系统产生(逐步递减)+每笔交易手续费

挖矿和共识

mining 的作用:

  1. 货币发行
  2. 去中心化的网络共识

挖矿机制是去中心化交易的基础。每笔交易是经过验证和确认结算的。
挖矿从安全方面保护了 bitcoin 系统,并且使网络范围内的共识机制成为可能
挖矿获得的 bitcoin 和交易手续费作为激励机制。

矿工验证交易然后,需要解决数学问题,获得记账权,然后才能记录到全球账簿中。这就是 bitcoin 的安全模型。
挖矿的定义是因为 POW 的奖励数额是逐渐递减的,直到归0,类似于现实世界的挖矿行为。目前是大约每4年(或者210,000块)减半,最开始的时候是50coin,2009年1月。

每个节点会保存一个有效交易的内存池 transaction pool, memory pool, or mempool
矿工节点接收到有效的新区块的时候,就会结束当前的挖矿操作,自动开始下一个挖矿操作

新块hash计算

查询交易信息
http://chainquery.com/bitcoin-api/getblock
https://bitcoinprivacy.net/explorer
https://blockchain.info/
查询原始区块信息 123771 2笔交易 0000000000001dc66351bed143c9302d57a97261be29d1a02e93f72767170cf1
526637 1笔交易 0000000000000000002ae8a3cae1bf46cd3fa5ffaf6059850a93dfdcd2be42ac
https://webbtc.com/block/0000000000002917ed80650c6174aac8dfc46f5fe36480aaef682ff6cd83c3ca

class CBlockHeader
{
public:
// header
int32_t nVersion;
uint256 hashPrevBlock;
uint256 hashMerkleRoot;
uint32_t nTime;
uint32_t nBits;
uint32_t nNonce;
...
}

hashMerkleRoot

构建merkle root 32bytes,merkle 树的叶子必须是偶数的

nTime

是 Unix “epoch” timestamp 从协调世界时1970年1月1日0时0分0秒起至现在的总秒数,不考虑闰秒

nBits

是难度,表示方式为
“bits”: “1903a30c”
0x19 is exponent
0x03a30c is mantissa
exponent(指数): 用来表示次方数
mantissa(尾数): 用来表示精确度

在二进制的“科学记号”,数字被表示为:Mantissa × 2^exponent

创世块 nBits = 0x1d00ffff
hex(256*0x1a0x00ffff)
0xffff0000000000000000000000000000000000000000000000000000

“bits”: “1903a30c”,
“difficulty”: 1180923195.258026,
当前的 target 比初始的 target 大多少
这里的 difficulty = (0x1d00ffff/0x1903a30c)
= 0xffff0000000000000000000000000000000000000000000000000000/
0x3a30c00000000000000000000000000000000000000000000
= 1180923195.2580261

target = 0x03a30c * 256 ^ (0x19 - 3)

837fad91.png 007d4f47.png

难度调节:
bitcoin 平均 10 分钟产生一个区块,这是发币和处理交易频率的基础。必须要保持平稳。
在长期来看,随着计算机技术的发展,计算能力会持续增加,所以需要调整难度来保持系统产生区块的稳定性。
所以 POW target 是一个动态参数,每隔 2016 个区块,每个节点各自重新计算难度,保证平均 10 分钟产生区块
New Target = Old Target * (Actual Time of Last 2016 Blocks / 20160 minutes)
通过减少或增加 target 来调整难度,可以通过统计学得出找到符合要求的 nonce 大致需要多少工作量
通过调整 nonce 计算 header hash 使 hash 满足 hash < target,完成 POW 工作

nNonce

是随机数,POW 就是通过调整这个找到 hash < nBits 表示的难度值的 hash

Coinbase Transaction
挖矿奖励交易

“Unlocking Script” (scriptSig)

交易

Transaction outputs 包括两部分:

  1. 交易金额,单位 satoshis,比特币最小单位
  2. 觉得花费 UTXO 的密码谜题,称为 locking script, a witness script, or a scriptPubKey
"vout":[
{
"value":0.01500000,
"scriptPubKey":"OP_DUP OP_HASH160 ab68025513c3dbd2f7b92a94e0581f5d50f654e7 OP_EQUALVERIFY OP_CHECKSIG"
},
{
"value":0.08450000,
"scriptPubKey":"OP_DUP OP_HASH160 7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 OP_EQUALVERIFY OP_CHECKSIG",
}
]

大多数交易都有手续费,作为网络安全的补偿,同时也能防止DoS攻击。
手续费的计算是按照交易的大小计算的,单位 kilobytes
矿工会按照不同的标准来排列优先级,包括手续费,在某些条件下还可能免手续费。

验证交易

通过两种类型的脚本来实现:
locking script
Unlocking script

共识

解决的问题:

  1. 分布式不可信环境的共识
  2. 解决重复支付问题

三个关键点:
一致性
分布式
非可信环境

自然共识机制的形成步骤:

  1. 由每一个全节点根据一系列的标准,独立验证每一笔交易。
  2. 由每一个挖矿节点独立收集交易到新的区块中,并附加上 POW 算法得出的相关数据
  3. 由每一个节点独立验证新区块然后添加到主区块链中
  4. 由每一个节点独立选择 POW 算法累计最多的链

每个节点会先校验交易然后在转发到网络中。
检查标准:

  • 语法和数据结构必须正确
  • 输入,输出列表不能为空
  • … AcceptToMemoryPool, CheckTransaction, and CheckInputs in Bitcoin Core
    transaction pool, memory pool, or mempool.

多重签名

多重签名脚本设置了这样一个条件,假如记录在脚本中的公钥个数为N,则至少需提供其中的M个公钥才可以解锁。这也被称为M-N组合,其中,N是记录在脚本中的公钥总个数,M是使得多重签名生效的公钥数阀值(最少数目)
OP_0 2 3 OP_CHECKMULTISIG

网络

新的网络节点必须发现至少一个网络中存在的节点并建立连接。节点通常采用TCP协议、使用8333端口(该端口号通常是比特币所使用的,除8333端口外也可以指定使用其他端口)与已知的对等节点建立连接。

一个节点包括功能:
routing, the blockchain database, mining, and wallet services

全节点包括以上四个功能
754a88ac.png

所有的节点都包括路由功能,参与到网络中。其他功能是可选项。
除了 bitcoin P2P protocol 外,还有服务和节点运行其他协议,例如专门的挖矿协议,轻节点访问协议

The Extended Bitcoin Network

Fast Internet Bitcoin Relay Engine or FIBRE 2016年启动

网络发现:节点启动时最少要连接到一个节点,通过TCP协议,8333端口。
连接后会握手,发送 “version” 消息,包括下面字段:
nVersion
The bitcoin P2P protocol version the client “speaks” (e.g., 70002)
nLocalServices
A list of local services supported by the node, currently just NODE_NETWORK
nTime
The current time
addrYou
The IP address of the remote node as seen from this node
addrMe
The IP address of the local node, as discovered by the local node
subver
A sub-version showing the type of software running on this node
(e.g., /Satoshi:0.9.2.1/)
BestHeight
The block height of this node’s blockchain

接收方收到 “version” 消息后,检验版本是否兼容,如果通过,则返回 verack

如何找到其他节点,通过 “DNS seeds” 获取节点 IP,一些 DNS seeds 提供静态的节点 IP 列表