精通比特幣第二版筆記

[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閱讀 228,546評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容