精通比特幣第二版筆記

[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的基本過程如下:

  1. SPV節(jié)點(diǎn)向向周邊節(jié)點(diǎn)(peers)廣播其感興趣的交易(以bloom filter形式)
  2. 當(dāng)一個(gè)peer節(jié)點(diǎn)發(fā)現(xiàn)一條交易包含在bloom filter中,該節(jié)點(diǎn)則返回該區(qū)塊(區(qū)塊頭和一條merkle path)
  3. 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ā)行上來看,比特幣是具有通縮特性的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容