[TOC]
比特幣介紹
歷史
比特幣(bitcoin)由中本聰于2009年提出并開源。它具有分布式、去中心化、加密數(shù)字化等特點(diǎn),采用工作量證明機(jī)制解決共識(shí)問題,所以,它又是安全的。
它誕生與全球經(jīng)濟(jì)危機(jī)(2008年)時(shí)期,是奧地利經(jīng)濟(jì)學(xué)派觀點(diǎn)的實(shí)踐。
比特幣定義
通常所說的比特幣指的是一種加密數(shù)字貨幣,由比特幣網(wǎng)絡(luò)發(fā)行(實(shí)際是給礦工的獎(jiǎng)勵(lì))、并在比特幣網(wǎng)絡(luò)上流通。數(shù)字簽名是目前數(shù)字貨幣的首選方案,其可以有效驗(yàn)證貨幣所有權(quán)。對(duì)于雙清問題,比特幣采用工作量證明機(jī)制解決雙清問題。
交易
交易是參與者之間價(jià)值轉(zhuǎn)移的過程。
比特幣交易的基礎(chǔ)單元是交易輸出。未被使用的輸出被稱為UTXO。一個(gè)UTXO是最小的不可分割的。一個(gè)UTXO是一聰(satoshi)的任意整數(shù)倍。
密鑰及比特幣地址
比特幣采用公鑰加密方案對(duì)交易進(jìn)行簽名,算法為橢圓曲線乘法算法。交易通常會(huì)包含一個(gè)公鑰、數(shù)字簽名和地址。
私鑰、公鑰、比特幣地址三者間關(guān)系,如下圖:
[圖片上傳失敗...(image-31ce69-1520689362124)]
私鑰
比特幣對(duì)私鑰并沒有強(qiáng)制規(guī)定。用戶可以自行選擇私鑰。私鑰目前是一個(gè)256位的數(shù)字,通常從一個(gè)安全的隨機(jī)數(shù)序列中產(chǎn)生。加密安全的偽隨機(jī)數(shù)生成器推薦使用CSPRNG。生成一個(gè)私鑰的通常流程為:選擇隨機(jī)數(shù)生成器->選擇隨機(jī)數(shù)種子->生成一個(gè)隨機(jī)數(shù)->SHA256哈希算法生成256位的數(shù)。
使用比特幣客戶端生成私鑰的方法如下:
$ 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是從私鑰計(jì)算而來的,計(jì)算方法采用橢圓曲線密碼學(xué)的第二個(gè)標(biāo)準(zhǔn)secp256k1。
生成公式:
K = k * G
k為私鑰。K為生成的公鑰。G為預(yù)定義的點(diǎn)(被稱為generator point G)。k * G生成曲線上的另外一個(gè)點(diǎn),該點(diǎn)即為公鑰K。
比特幣地址
根據(jù)公鑰生成的比特幣地址以數(shù)字1開頭。生成公式為:
A = RIPEMD160(SHA256(K))
上述公式生成的地址A為160位,共20個(gè)字節(jié)。比特幣通常使用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字節(jié) |
| Hex | None | 64個(gè)16進(jìn)制數(shù)字 |
| WIF | 5 | Base58Check |
| WIF-compressed | K or L | As above, with added suffix 0x01 before encoding |
| BIP-38 | 6P | BIP-38標(biāo)準(zhǔn)加密的私鑰 |
密鑰和地址強(qiáng)化
加密密鑰
BIP-38標(biāo)準(zhǔn)是一個(gè)通用的私鑰加密標(biāo)準(zhǔn)。它使用AES加密算法。用戶需要提供私鑰和一個(gè)passphrase。BIP-38標(biāo)準(zhǔn)生成的私鑰以6P開頭。
P2SH和多簽名地址
P2SH全稱為Pay-to-Script Hash,又稱為Multisig Addresses(多重簽名地址),地址前輟為3。目前,最為普遍的P2SH功能應(yīng)用是多簽名地址腳本。這種腳本要求用戶提供一到多個(gè)簽名來證明控制權(quán)(Ownership),然后才可以花費(fèi)這筆資金。
生成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
靚號(hào)地址(Vanity Addresses)
靚號(hào)地址是一個(gè)有效的比特幣地址,它含有一部分有意義的信息。如地址1LoveBPzzD72PUXLzCkYAtGFYmK5vYNR33。該地址包含詞"Love"。
紙錢包
所謂紙錢包就是把私鑰和地址打印一張紙上。這是一種廉價(jià)的離線存儲(chǔ)手段。離線存儲(chǔ)的錢包也叫冷錢包。直接將私鑰原樣做成紙錢包并不安全(盜賊)。通常,冷存儲(chǔ)的是BIP-38加密過的私鑰。這就要求用戶要記住一個(gè)passphrase或?qū)assphrase另行存儲(chǔ)。
錢包
錢包(wallet)是一個(gè)應(yīng)用程序,用于管理密鑰、地址,跟蹤余額以及簽名交易。
從技術(shù)的角度來看,錢包是一種數(shù)據(jù)結(jié)構(gòu),用于存儲(chǔ)和管理用戶的密鑰。
小提示:比特幣錢包并不含有比特幣,他只包含密鑰。所謂的幣是記錄在比特幣網(wǎng)絡(luò)的區(qū)塊鏈里的,'幣'是交易輸出的一種形式(通常稱為vout或txout)。
錢包有兩種類型:非確定性錢包和確定性錢包。區(qū)分的標(biāo)準(zhǔn)是密鑰間是否有關(guān)聯(lián)。
非確定性錢包里的密鑰們沒有相關(guān)性,是獨(dú)立的。
確定性錢包里的密鑰由一個(gè)主私鑰衍生而來(被稱為seed,即種子)。最常見的實(shí)現(xiàn)方式是一種類樹狀結(jié)構(gòu),被稱為分層確定性錢包(HD wallet),標(biāo)準(zhǔn)為BIP-32/BIP-44。
確定性錢包從一個(gè)種子初始化而來。為便于使用,種子通常編碼為英文單詞,又稱助記碼(Mnemonic Codes,標(biāo)準(zhǔn)為BIP-39)。
現(xiàn)在,基本上都是HD錢包了,除了Bitcoin core。
錢包最佳實(shí)踐
- 基于BIP-39的助記碼
- 基于BIP-32的HD錢包
- 基于BIP-43的多用途HD錢包
- 基于BIP-44的多幣種、多帳號(hào)錢包
助記符(BIP-39)
BIP-39是助記碼的當(dāng)前工業(yè)標(biāo)準(zhǔn)。它是Trezor硬件錢包公司提出的。目前,BIP-39有兩個(gè)實(shí)現(xiàn)版本:Trezor版本和Electrum錢包。兩者因?yàn)槭褂貌煌脑~典集合而不能互通。
助記符生成示例如下
$bx mnemonic-new ea3138a05e18f4f68f345a40b0e4e264
tuition mean chimney rotate monster kitten devote mercy doll mango decade since
交易
交易是比特幣系統(tǒng)最重要的部分。系統(tǒng)的其他部分都是為了保證交易的創(chuàng)建、驗(yàn)證以及記入全球帳薄。
交易輸出和輸入
比特幣交易的基石是交易輸出(vout)。交易輸出是不可分割的比特幣貨幣(類似于有面額的紙幣),記錄在區(qū)塊鏈上并由全網(wǎng)絡(luò)驗(yàn)證有效。比特幣全節(jié)點(diǎn)跟蹤所有的可用、可花費(fèi)的輸出,這些輸出被稱為UTXO(未花費(fèi)的交易輸出)。
原始的交易解碼后,一般是下面樣子:
{
"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",
}
]
}
每一個(gè)區(qū)塊的第一個(gè)交易被稱為coinbase交易,即比特幣網(wǎng)絡(luò)給礦工的獎(jiǎng)勵(lì)。所以,coinbase交易是沒有input的。
交易輸出
交易輸出包括兩部分:
- 一定量的比特幣,單位是聰(satoshis)
- 一個(gè)加密迷題(花費(fèi)該UTXO的必要條件),又被稱為鎖定腳本(locking script)、見證腳本(witness script)或scriptPubKey。
輸出的序列化結(jié)構(gòu)(開發(fā)人員關(guān)注)
| Size | Field | Description |
|---|---|---|
| 8 bytes(小端) | 總量 | 比特幣總量,單位聰(satoshis) |
| 1-9 bytes | Locking Script的大小 | Locking Script的字節(jié)大小 |
| 可變部分 | Locking Script | 定義花出該輸出的前提條件的腳本 |
交易輸入
交易輸入標(biāo)識(shí)哪個(gè)UTXO將被消費(fèi)(花出)并通過unlocking script證明其所有權(quán)。
其主要包含如下幾部分:
- 一個(gè)交易id, txid
- 一個(gè)UTXO的索引(從0開始)
- 一個(gè)scriptSig,用于unlocking花費(fèi)
- 一個(gè)序列號(hào)
示例如下:
"vin": [
{
"txid": "7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18",
"vout": 0,
"scriptSig" : "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813[ALL] 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf",
"sequence": 4294967295
}
]
交易費(fèi)
大部分交易是包含交易費(fèi)的。交易費(fèi)用于激勵(lì)礦工維護(hù)比特幣網(wǎng)絡(luò)。交易費(fèi)用是隱含在交易中的,其數(shù)值為Fees = Sum(Inputs) – Sum(Outputs)。
交易腳本
比特幣的交易腳本(script)是一種類似于Forth語言的、逆波蘭式、基于堆棧的語言。
比特幣的腳本語言不是圖靈完備的,不支持loop操作
比特幣腳本語言是無狀態(tài)的
比特幣腳本語言簡單,但并不友好。看起來,像是匯編語言
腳本構(gòu)建
比特幣交易驗(yàn)證引擎依賴于兩種腳本:一個(gè)鎖定腳本和一個(gè)解鎖腳本。
鎖定腳本通常稱為scriptPubKey。解鎖腳本通常稱為scriptSig。
交易驗(yàn)證時(shí),引擎執(zhí)行流程是:scriptSig -> scriptPubKey。
示例如下:
[圖片上傳失敗...(image-ec046-1520689362124)]
具體執(zhí)行流程如下:
[圖片上傳失敗...(image-ec5c92-1520689362124)]
數(shù)字簽名
比特幣使用的數(shù)字簽名算法為ECDSA。該算法是一種公鑰加密算法。
數(shù)字簽名有三個(gè)作用:
- 所有權(quán)證明
- 授權(quán)是不可否認(rèn)的(即交易一旦生成,不可否認(rèn))
- 一旦簽名,則交易不可修改(或特定部分不可修改)
高級(jí)交易和腳本
隔離見證的核心部分
比特幣網(wǎng)絡(luò)
區(qū)塊鏈
區(qū)塊鏈數(shù)據(jù)結(jié)構(gòu)是一種后向鏈接的有序鏈表。比特幣客戶端使用Google LevelDB存儲(chǔ)區(qū)塊鏈的元數(shù)據(jù)。
Block數(shù)據(jù)結(jié)構(gòu)
Block Structure
| Size | Field | Description |
|---|---|---|
| 4字節(jié) | 塊大小 | 隨后的塊大小,字節(jié)單位 |
| 80 bytes | Block Header | 由多個(gè)field構(gòu)成 |
| 1–9 bytes (VarInt) | 交易計(jì)數(shù)器 | 該block包含的交易數(shù)目 |
| 可變部分 | 交易的集合 | 記錄在該區(qū)塊上的交易 |
區(qū)塊頭(Block Header)
| Size | Field | Description |
|---|---|---|
| 4 bytes | Version | 協(xié)議的版本號(hào) |
| 32 bytes | Previous Block Hash | 父區(qū)塊的Hash |
| 32 bytes | Merkle Root | Merkle樹的root |
| 4 bytes | 時(shí)間戳 | 區(qū)塊的創(chuàng)建時(shí)間,秒(是個(gè)近似值) |
| 4 bytes | Difficulty Target(難度目標(biāo)) | 該區(qū)塊的PoW難度 |
| 4 bytes | Nonce | PoW算法的一個(gè)計(jì)數(shù)器 |
區(qū)塊標(biāo)識(shí) (Block Identifier)
Block的標(biāo)識(shí)是一個(gè)哈希值(Hash),使用sha256算法對(duì)區(qū)塊頭(Block Header)執(zhí)行兩次哈希操作而來。
創(chuàng)世區(qū)塊的哈希值是:000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
區(qū)塊的Hash值并沒有存儲(chǔ)在區(qū)塊上。當(dāng)節(jié)點(diǎn)收到一個(gè)區(qū)塊時(shí),節(jié)點(diǎn)需要去計(jì)算該節(jié)點(diǎn)的Hash。
另一種標(biāo)識(shí)則是區(qū)塊高度(block height)。創(chuàng)世區(qū)塊從0開始。一個(gè)區(qū)塊一定有一個(gè)高度。但一個(gè)高度并不唯一對(duì)應(yīng)一個(gè)區(qū)塊。這涉及到區(qū)塊競(jìng)爭(zhēng)問題。常見場(chǎng)景是forks(即分叉)。Block Height也不是區(qū)塊數(shù)據(jù)結(jié)構(gòu)的一部分。節(jié)點(diǎn)需要在收到區(qū)塊時(shí)計(jì)算。
創(chuàng)世區(qū)塊(Genesis Block)
比特幣區(qū)塊鏈上的第一個(gè)區(qū)塊被稱為創(chuàng)世區(qū)塊,創(chuàng)建于2009年。它是所有區(qū)塊的祖宗。創(chuàng)世區(qū)塊的UTXO是50BTC,至今未花。創(chuàng)世區(qū)塊上寫有一條信息(已經(jīng)是非常出名了):"The Times 03/Jan/2009 Chancellor on brink of second bailout for banks."。
Merkle Tree
每一個(gè)區(qū)塊均使用Merkle Tree記錄該區(qū)塊上所有交易的摘要。Merkle Tree生成過程如下圖所示。
[圖片上傳失敗...(image-79a62-1520689362124)]
區(qū)塊上存儲(chǔ)Merkle Tree Root節(jié)點(diǎn)的hash。每個(gè)節(jié)點(diǎn)的hash算法均為double-sha256。
SPV (Simplifiled Payment Verification)
SPV節(jié)點(diǎn)不需要全部的交易數(shù)據(jù)也不需要下載全部區(qū)塊,只需要區(qū)塊頭數(shù)據(jù)即可。SPV節(jié)點(diǎn)使用merkle path來驗(yàn)證一個(gè)節(jié)點(diǎn)是否被包含在該區(qū)塊內(nèi)。
SPV節(jié)點(diǎn)驗(yàn)證交易A被包含于區(qū)塊Block_b的基本過程如下:
- SPV節(jié)點(diǎn)向向周邊節(jié)點(diǎn)(peers)廣播其感興趣的交易(以bloom filter形式)
- 當(dāng)一個(gè)peer節(jié)點(diǎn)發(fā)現(xiàn)一條交易包含在bloom filter中,該節(jié)點(diǎn)則返回該區(qū)塊(區(qū)塊頭和一條merkle path)
- SPV節(jié)點(diǎn)使用merkle path驗(yàn)證交易A是否在Block_b中
merkle path如下圖所示:
[圖片上傳失敗...(image-26d469-1520689362124)]
如果要驗(yàn)證交易Hk是否包含在區(qū)塊內(nèi),只需要獲知H(L), H(IJ), H(MNOP),H(ABCDEFGH)這四個(gè)哈希值即可。
Merkle Tree的效率
| 交易數(shù)量 | 區(qū)塊大小 | Merkle Path哈希數(shù) | Path字節(jié)數(shù) |
|---|---|---|---|
| 16條交易 | 4KB | 4 hashes | 128B |
| 512條交易 | 128KB | 9 hashes | 288B |
| 2048條交易 | 512KB | 11 hashes | 352B |
| 65535條交易 | 16MB | 16 hashes | 512B |
比特幣測(cè)試鏈(Test Blockchains)
比特幣是有多條鏈的。由中本聰同學(xué)創(chuàng)建于2009年1月3日的區(qū)塊鏈為主網(wǎng)絡(luò)(mainnet)。還有其他測(cè)試目的的區(qū)塊鏈:testnet(測(cè)試網(wǎng)絡(luò)), segnet(隔離見證網(wǎng)絡(luò)), regtest。
- testnet
testnet擁有主網(wǎng)絡(luò)的所有特征。通常,testnet網(wǎng)絡(luò)上的幣是沒有價(jià)值的(因?yàn)槠渫诘V難度比較低),但事實(shí)并非如此。因?yàn)榭偸怯型婕沂褂胊sic來挖礦,從而導(dǎo)致測(cè)試網(wǎng)絡(luò)挖幣也是一件困難的事情。目前的解決方案是從一個(gè)新的創(chuàng)世區(qū)塊重啟測(cè)試網(wǎng)絡(luò),并重設(shè)難度。
目前的測(cè)試網(wǎng)絡(luò)為testnet3(重啟于2011年)。
bitcoind -testnet
- segnet
2016年,為了支持SegNet的開發(fā)測(cè)試,一個(gè)特定目的的測(cè)試網(wǎng)絡(luò)啟動(dòng)。(目前已不再是必須的,因?yàn)閟egwit已經(jīng)被testnet3引入)
- Regtest
本地區(qū)塊鏈
$ bitcoind -regtest
挖礦和共識(shí)
挖礦是確保比特幣去中心化安全性的機(jī)制。比特幣是一種經(jīng)濟(jì)激勵(lì)機(jī)制。
礦工負(fù)責(zé)驗(yàn)證新的交易并記錄在全球帳薄上。挖出一個(gè)新區(qū)塊的平均時(shí)間是10分鐘。而記錄在區(qū)塊鏈上的交易則被認(rèn)為是確認(rèn)過的。
比特幣的確認(rèn)時(shí)間目前比較長,一個(gè)小時(shí)之上。
礦工有兩種獎(jiǎng)勵(lì):交易費(fèi)和區(qū)塊獎(jiǎng)勵(lì)。為了獲得獎(jiǎng)勵(lì),礦工需要解決一個(gè)數(shù)學(xué)難題。比特幣采用PoW方案來解決這個(gè)難題(工作量證明-Proof-of-Work)。答案被記錄在新區(qū)塊中并作為一個(gè)憑據(jù)。該憑據(jù)可以證明礦工花費(fèi)了一定的算力來解決這個(gè)問題。
這個(gè)過程稱為挖礦,因?yàn)楠?jiǎng)勵(lì)(比特幣發(fā)生成)旨在模擬收益遞減,就像開采貴金屬一樣。比特幣總量固定而且區(qū)塊生成的比特幣每四年或210000個(gè)區(qū)塊減半。2009年一個(gè)區(qū)塊獎(jiǎng)勵(lì)是50個(gè)比特幣,2012年11月為25個(gè)比特幣,2016年7月則為12.5個(gè)。到2140年,不會(huì)再有新的比特幣生成。
目前,交易費(fèi)只占礦工收入的0.5%。而隨著獎(jiǎng)勵(lì)指數(shù)級(jí)下降,區(qū)塊上的交易日漸增多,比特幣礦業(yè)收入的更大比例將來自交易費(fèi)用。
從發(fā)行上來看,比特幣是具有通縮特性的。