精通比特币第二版笔记

[TOC]

比特币介绍

历史

比特币(bitcoin)由中本聪于2009年提出并开源。它具有分布式、去中心化、加密数字化等特点,采用工作量证明机制解决共识问题,所以,它又是安全的。
它诞生与全球经济危机(2008年)时期,是奥地利经济学派观点的实践。

比特币定义

通常所说的比特币指的是一种加密数字货币,由比特币网络发行(实际是给矿工的奖励)、并在比特币网络上流通。数字签名是目前数字货币的首选方案,其可以有效验证货币所有权。对于双清问题,比特币采用工作量证明机制解决双清问题。

交易

交易是参与者之间价值转移的过程。
比特币交易的基础单元是交易输出。未被使用的输出被称为UTXO。一个UTXO是最小的不可分割的。一个UTXO是一聪(satoshi)的任意整数倍。

密钥及比特币地址

比特币采用公钥加密方案对交易进行签名,算法为椭圆曲线乘法算法。交易通常会包含一个公钥、数字签名和地址。

私钥、公钥、比特币地址三者间关系,如下图:

[图片上传失败...(image-31ce69-1520689362124)]

私钥

比特币对私钥并没有强制规定。用户可以自行选择私钥。私钥目前是一个256位的数字,通常从一个安全的随机数序列中产生。加密安全的伪随机数生成器推荐使用CSPRNG。生成一个私钥的通常流程为:选择随机数生成器->选择随机数种子->生成一个随机数->SHA256哈希算法生成256位的数。

使用比特币客户端生成私钥的方法如下:

$ bitcoin-cli getnewaddress
1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy
$ bitcoin-cli dumpprivkey 1J7mdg5rbQyUHENYdx39WVWK7fsLpEoXZy
KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ

或者使用bitcoin explorer的cli工具:

$ bx seed | bx ec-new | bx ec-to-wif
5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn

比特币私钥通常使用WIF(Wallet Import Format)显示私钥。

公钥

Public Key是从私钥计算而来的,计算方法采用椭圆曲线密码学的第二个标准secp256k1

生成公式:

K = k * G

k为私钥。K为生成的公钥。G为预定义的点(被称为generator point G)。k * G生成曲线上的另外一个点,该点即为公钥K。

比特币地址

根据公钥生成的比特币地址以数字1开头。生成公式为:

A = RIPEMD160(SHA256(K))

上述公式生成的地址A为160位,共20个字节。比特币通常使用Base58Check编码格式编码比特币地址A。

Base58的详情信息参见链接

Base58Check的过程如下:

Bitcoin Address = PREFIX + A + Checksum
checksum = sha256(sha256(PREFIX + A)

prefix定义

Type Version Prefix(Hex) Base58 result prefix
Bitcoin Address 0x00 1
Pay-to-Script-Hash Address 0x05 3
Bitcoin Testnet Address 0x6F m or n
Private Key WIF 0x80 5,K, or L
BIP-38 Encrypted Private Key 0x0142 6P
BIP-32 Extended Public Key 0x0488B21E xpub

私钥的编码格式

Type Prefix 描述
Raw None 32字节
Hex None 64个16进制数字
WIF 5 Base58Check
WIF-compressed K or L As above, with added suffix 0x01 before encoding
BIP-38 6P BIP-38标准加密的私钥

密钥和地址强化

加密密钥

BIP-38标准是一个通用的私钥加密标准。它使用AES加密算法。用户需要提供私钥和一个passphrase。BIP-38标准生成的私钥以6P开头。

P2SH和多签名地址

P2SH全称为Pay-to-Script Hash,又称为Multisig Addresses(多重签名地址),地址前辍为3。目前,最为普遍的P2SH功能应用是多签名地址脚本。这种脚本要求用户提供一到多个签名来证明控制权(Ownership),然后才可以花费这笔资金。

生成P2SH地址的过程一般如下:

graph LR
    A[script]-->B(script-encode)
    B --> C(sha256)
    C --> D(ripemd160)
    D --> E(base58check-encode)

代码示例如下

$ echo \
'DUP HASH160 [89abcdefabbaabbaabbaabbaabbaabbaabbaabba] EQUALVERIFY CHECKSIG' > script
$ bx script-encode < script | bx sha256 | bx ripemd160 \
| bx base58check-encode --version 5
3F6i6kwkevjR7AsAd4te2YB2zZyASEm1HM

靓号地址(Vanity Addresses)

靓号地址是一个有效的比特币地址,它含有一部分有意义的信息。如地址1LoveBPzzD72PUXLzCkYAtGFYmK5vYNR33。该地址包含词"Love"。

纸钱包

所谓纸钱包就是把私钥和地址打印一张纸上。这是一种廉价的离线存储手段。离线存储的钱包也叫冷钱包。直接将私钥原样做成纸钱包并不安全(盗贼)。通常,冷存储的是BIP-38加密过的私钥。这就要求用户要记住一个passphrase或将passphrase另行存储。

钱包

钱包(wallet)是一个应用程序,用于管理密钥、地址,跟踪余额以及签名交易。
从技术的角度来看,钱包是一种数据结构,用于存储和管理用户的密钥。

小提示:比特币钱包并不含有比特币,他只包含密钥。所谓的币是记录在比特币网络的区块链里的,'币'是交易输出的一种形式(通常称为vout或txout)。

钱包有两种类型:非确定性钱包和确定性钱包。区分的标准是密钥间是否有关联。

非确定性钱包里的密钥们没有相关性,是独立的。

确定性钱包里的密钥由一个主私钥衍生而来(被称为seed,即种子)。最常见的实现方式是一种类树状结构,被称为分层确定性钱包(HD wallet),标准为BIP-32/BIP-44。

确定性钱包从一个种子初始化而来。为便于使用,种子通常编码为英文单词,又称助记码(Mnemonic Codes,标准为BIP-39)。

现在,基本上都是HD钱包了,除了Bitcoin core。

钱包最佳实践

  • 基于BIP-39的助记码
  • 基于BIP-32的HD钱包
  • 基于BIP-43的多用途HD钱包
  • 基于BIP-44的多币种、多帐号钱包

助记符(BIP-39)

BIP-39是助记码的当前工业标准。它是Trezor硬件钱包公司提出的。目前,BIP-39有两个实现版本:Trezor版本和Electrum钱包。两者因为使用不同的词典集合而不能互通。

助记符生成示例如下

$bx mnemonic-new ea3138a05e18f4f68f345a40b0e4e264
tuition mean chimney rotate monster kitten devote mercy doll mango decade since

交易

交易是比特币系统最重要的部分。系统的其他部分都是为了保证交易的创建、验证以及记入全球帐薄。

交易输出和输入

比特币交易的基石是交易输出(vout)。交易输出是不可分割的比特币货币(类似于有面额的纸币),记录在区块链上并由全网络验证有效。比特币全节点跟踪所有的可用、可花费的输出,这些输出被称为UTXO(未花费的交易输出)。

原始的交易解码后,一般是下面样子:

{
  "version": 1,
  "locktime": 0,
  "vin": [
    {
      "txid": "7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18",
      "vout": 0,
      "scriptSig" : "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813[ALL] 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf",
      "sequence": 4294967295
    }
  ],
  "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",
    }
  ]
}

每一个区块的第一个交易被称为coinbase交易,即比特币网络给矿工的奖励。所以,coinbase交易是没有input的。

交易输出

交易输出包括两部分:

  • 一定量的比特币,单位是聪(satoshis)
  • 一个加密迷题(花费该UTXO的必要条件),又被称为锁定脚本(locking script)、见证脚本(witness script)或scriptPubKey。

输出的序列化结构(开发人员关注)

Size Field Description
8 bytes(小端) 总量 比特币总量,单位聪(satoshis)
1-9 bytes Locking Script的大小 Locking Script的字节大小
可变部分 Locking Script 定义花出该输出的前提条件的脚本

交易输入

交易输入标识哪个UTXO将被消费(花出)并通过unlocking script证明其所有权。

其主要包含如下几部分:

  • 一个交易id, txid
  • 一个UTXO的索引(从0开始)
  • 一个scriptSig,用于unlocking花费
  • 一个序列号

示例如下:

"vin": [
  {
    "txid": "7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18",
    "vout": 0,
    "scriptSig" : "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813[ALL] 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf",
    "sequence": 4294967295
  }
]

交易费

大部分交易是包含交易费的。交易费用于激励矿工维护比特币网络。交易费用是隐含在交易中的,其数值为Fees = Sum(Inputs) – Sum(Outputs)

交易脚本

比特币的交易脚本(script)是一种类似于Forth语言的、逆波兰式、基于堆栈的语言。

比特币的脚本语言不是图灵完备的,不支持loop操作

比特币脚本语言是无状态的

比特币脚本语言简单,但并不友好。看起来,像是汇编语言

脚本构建

比特币交易验证引擎依赖于两种脚本:一个锁定脚本和一个解锁脚本。

锁定脚本通常称为scriptPubKey。解锁脚本通常称为scriptSig。

交易验证时,引擎执行流程是:scriptSig -> scriptPubKey。

示例如下:

[图片上传失败...(image-ec046-1520689362124)]

具体执行流程如下:
[图片上传失败...(image-ec5c92-1520689362124)]

数字签名

比特币使用的数字签名算法为ECDSA。该算法是一种公钥加密算法。

数字签名有三个作用:

  • 所有权证明
  • 授权是不可否认的(即交易一旦生成,不可否认)
  • 一旦签名,则交易不可修改(或特定部分不可修改)

高级交易和脚本

隔离见证的核心部分

比特币网络

区块链

区块链数据结构是一种后向链接的有序链表。比特币客户端使用Google LevelDB存储区块链的元数据。

Block数据结构

Block Structure

Size Field Description
4字节 块大小 随后的块大小,字节单位
80 bytes Block Header 由多个field构成
1–9 bytes (VarInt) 交易计数器 该block包含的交易数目
可变部分 交易的集合 记录在该区块上的交易

区块头(Block Header)

Size Field Description
4 bytes Version 协议的版本号
32 bytes Previous Block Hash 父区块的Hash
32 bytes Merkle Root Merkle树的root
4 bytes 时间戳 区块的创建时间,秒(是个近似值)
4 bytes Difficulty Target(难度目标) 该区块的PoW难度
4 bytes Nonce PoW算法的一个计数器

区块标识 (Block Identifier)

Block的标识是一个哈希值(Hash),使用sha256算法对区块头(Block Header)执行两次哈希操作而来。

创世区块的哈希值是:000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

区块的Hash值并没有存储在区块上。当节点收到一个区块时,节点需要去计算该节点的Hash。

另一种标识则是区块高度(block height)。创世区块从0开始。一个区块一定有一个高度。但一个高度并不唯一对应一个区块。这涉及到区块竞争问题。常见场景是forks(即分叉)。Block Height也不是区块数据结构的一部分。节点需要在收到区块时计算。

创世区块(Genesis Block)

比特币区块链上的第一个区块被称为创世区块,创建于2009年。它是所有区块的祖宗。创世区块的UTXO是50BTC,至今未花。创世区块上写有一条信息(已经是非常出名了):"The Times 03/Jan/2009 Chancellor on brink of second bailout for banks."。

Merkle Tree

每一个区块均使用Merkle Tree记录该区块上所有交易的摘要。Merkle Tree生成过程如下图所示。
[图片上传失败...(image-79a62-1520689362124)]

区块上存储Merkle Tree Root节点的hash。每个节点的hash算法均为double-sha256。

SPV (Simplifiled Payment Verification)

SPV节点不需要全部的交易数据也不需要下载全部区块,只需要区块头数据即可。SPV节点使用merkle path来验证一个节点是否被包含在该区块内。

SPV节点验证交易A被包含于区块Block_b的基本过程如下:

  1. SPV节点向向周边节点(peers)广播其感兴趣的交易(以bloom filter形式)
  2. 当一个peer节点发现一条交易包含在bloom filter中,该节点则返回该区块(区块头和一条merkle path)
  3. SPV节点使用merkle path验证交易A是否在Block_b中

merkle path如下图所示:
[图片上传失败...(image-26d469-1520689362124)]

如果要验证交易Hk是否包含在区块内,只需要获知H(L), H(IJ), H(MNOP),H(ABCDEFGH)这四个哈希值即可。

Merkle Tree的效率

交易数量 区块大小 Merkle Path哈希数 Path字节数
16条交易 4KB 4 hashes 128B
512条交易 128KB 9 hashes 288B
2048条交易 512KB 11 hashes 352B
65535条交易 16MB 16 hashes 512B

比特币测试链(Test Blockchains)

比特币是有多条链的。由中本聪同学创建于2009年1月3日的区块链为主网络(mainnet)。还有其他测试目的的区块链:testnet(测试网络), segnet(隔离见证网络), regtest。

  • testnet

testnet拥有主网络的所有特征。通常,testnet网络上的币是没有价值的(因为其挖矿难度比较低),但事实并非如此。因为总是有玩家使用asic来挖矿,从而导致测试网络挖币也是一件困难的事情。目前的解决方案是从一个新的创世区块重启测试网络,并重设难度。

目前的测试网络为testnet3(重启于2011年)。

bitcoind -testnet
  • segnet

2016年,为了支持SegNet的开发测试,一个特定目的的测试网络启动。(目前已不再是必须的,因为segwit已经被testnet3引入)

  • Regtest

本地区块链

$ bitcoind -regtest

挖矿和共识

挖矿是确保比特币去中心化安全性的机制。比特币是一种经济激励机制。

矿工负责验证新的交易并记录在全球帐薄上。挖出一个新区块的平均时间是10分钟。而记录在区块链上的交易则被认为是确认过的。

比特币的确认时间目前比较长,一个小时之上。

矿工有两种奖励:交易费和区块奖励。为了获得奖励,矿工需要解决一个数学难题。比特币采用PoW方案来解决这个难题(工作量证明-Proof-of-Work)。答案被记录在新区块中并作为一个凭据。该凭据可以证明矿工花费了一定的算力来解决这个问题。

这个过程称为挖矿,因为奖励(比特币发生成)旨在模拟收益递减,就像开采贵金属一样。比特币总量固定而且区块生成的比特币每四年或210000个区块减半。2009年一个区块奖励是50个比特币,2012年11月为25个比特币,2016年7月则为12.5个。到2140年,不会再有新的比特币生成。

目前,交易费只占矿工收入的0.5%。而随着奖励指数级下降,区块上的交易日渐增多,比特币矿业收入的更大比例将来自交易费用。

从发行上来看,比特币是具有通缩特性的。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容