本文翻譯自 Segregated Witness Wallet Development Guide 习劫。
Key Terms(文中可能以英文表示):
- Segregated Witness = SegWit = segwit
- BIP = Bitcoin Improvement Proposals
- address = bitcoin address
- txin = bitcoin transaction input
- UTXO = Unspent Transaction Output
- P2PKH = Pay To PubKey Hash
- P2SH = Pay to script hash
- P2WPKH = Pay to Witness Public Key Hash
- scriptPubKey = the locking script of an output
- scriptSig = the unlocking script to resolve an scriptPubKey
- redeemScript = A script similar in function to a scriptPubKey. One copy of it is hashed to create a P2SH address and another copy is placed in the spending signature script to enforce its conditions.
- Other terms:
- multi-signature, keyhash, Sighash, air-gapped, light-weight wallet, orphaned block, retarget cycle
隔離驗(yàn)證錢包開發(fā)指南 Part I(基本篇)
本篇文章大部分內(nèi)容可在 BIP141, BIP143, BIP144, BIP145 中找到法严。請(qǐng)將本篇文章視為閱讀其他相關(guān)文章前的首要參考芥被,及作為一需要完成及應(yīng)避免事項(xiàng)的清單。
基本隔離驗(yàn)證支持
為了達(dá)到基本的隔離驗(yàn)證相容,錢包必須實(shí)作所有本章所描述功能:
送到 P2SH
- 一個(gè)隔離驗(yàn)證相容錢包必須支持 P2SH(BIP16) 及其 address 格式断国。
- 就付款來(lái)說(shuō)贤姆,錢包必須能轉(zhuǎn)換一 P2SH address 成
scriptPubKey
,并建立交易稳衬。 - 對(duì)收款來(lái)說(shuō)霞捡,錢包必須能建立一基于 P2WPKH 腳本(本文稍后會(huì)描述)的 P2SH address,并能識(shí)別出送到該 address 的交易薄疚。
- 以上是必須的要求碧信,即使錢包只接受單簽章的收付款。
建立 P2SH-P2WPKH Address
- 一個(gè) P2SH-P2WPKH address 可比擬比特幣原本的單簽章 P2PKH address (address 其 prefix 為 1)街夭。
- 像是任何 P2SH address, P2SH-P2WPKH address 其 prefix 為 3砰碴。
- 直到有 P2SH-P2WPKH UTXO 被花費(fèi)并揭露
redeemScript
,才得以分辨一個(gè) P2SH-P2WPKH address 和 non-segwit P2SH address(例如一個(gè) non-segwit multi-signature address)板丽。 - 當(dāng)收款只需要一個(gè)公鑰時(shí)(像 P2PKH)呈枉,應(yīng)使用 P2SH-P2WPKH address。
- P2SH-P2WPKH 使用和 P2PKH 相同的公鑰埃碱,但有一個(gè)重要的例外:公鑰使用在 P2SH-P2WPKH 必須被壓縮猖辫,i.e. 大小 33 bytes,以
0x02
或0x03
開頭砚殿。使用不同格式像是沒(méi)有壓縮過(guò)的公鑰可能導(dǎo)致不可回溯的資金遺失啃憎。 - 創(chuàng)建一個(gè) P2SH-P2WPKH address:
- 計(jì)算公鑰經(jīng) SHA256 在經(jīng) RIPEMD160 的值(
keyhash
)。雖然計(jì)算keyhash
的公式和 P2PKH 相同似炎,為了隱私和預(yù)防不小心用到?jīng)]有壓縮過(guò)的公鑰辛萍,應(yīng)避免重復(fù)使用keyhash
。 - P2SH
redeemScript
都是 22 bytes羡藐。它是以OP_0
為開始贩毕,接著keyhash
(i.e.0x0014{20-byte keyhash}
)。 - 和所有 P2SH 相同仆嗦,scriptPubKey 是
OP_HASH160 hash160(redeemScript) OP_EQUAL
辉阶, 然后 address 是相對(duì)應(yīng)的 P2SH address 其 prefix 為 3。
- 計(jì)算公鑰經(jīng) SHA256 在經(jīng) RIPEMD160 的值(
交易序列化
- 一個(gè)隔離驗(yàn)證相容的錢包必須支援原本的交易格式欧啤,像是
nVersion|txins|txouts|nLockTime
。 - 一個(gè)隔離驗(yàn)證相容的錢包必須支援新的序列化格式启上,像是
nVersion|marker|flag|txins|txouts|witness|nLockTime
:-
nVersion
,txins
,txouts
, 及nLockTime
的格式和原本格式相同 -
marker
必須是0x00
-
flag
必須是0x01
-
witness
是所有交易的 witness data 的序列化結(jié)果:- 所有 txin 都連結(jié)到一個(gè) witness 欄位邢隧。所以,并沒(méi)有數(shù)字指出有多少個(gè) witness 欄位冈在,因?yàn)橛卸嗌?txin 就代表有多少 witness 欄位倒慧。
- 每個(gè) witness 欄位都會(huì)始于一個(gè)
compactSize
integer 指出有多少個(gè)項(xiàng)目在 stack 中。如果 stack 中有 witness 項(xiàng)目的話,會(huì)接再compactSize
integer 之后纫谅。 - 每個(gè) witness 項(xiàng)目都始于一個(gè)
compactSize
integer 表示該項(xiàng)目的 bytes 數(shù)炫贤。 - 如果該 txin 沒(méi)有連結(jié)任何 witness data,它對(duì)應(yīng)的 witness 欄位就是 0x00付秕,表示 stack 中的項(xiàng)目數(shù)為零兰珍。
-
- 如果所有 txin 都沒(méi)有連結(jié)到任何 witness data,該交易必須序列化成原本的交易格式询吴,沒(méi)有
marker
,flag
及witness
掠河。例如,如果沒(méi)有 txin 是來(lái)自 segwit UTXO猛计,該交易就必須序列化成原本的交易格式唠摹。(例外:coinbase 交易) - 交易的范例可以在 BIP143 中的范例找到。錢包開發(fā)者可以用該范例測(cè)試他們的實(shí)作是否正確抓取交易資料以符合新的序列化格式奉瘤。
交易 ID
- 在隔離驗(yàn)證中勾拉,每一個(gè)交易會(huì)有 2 個(gè) ID。
-
txid
的定義保持不變:原本交易的序列化格式經(jīng)過(guò)兩次 SHA256盗温。 - 一個(gè)新的
wtxid
被定義為新的序列化格式加上 witnes data 經(jīng)過(guò)兩次 SHA256藕赞。 - 如果一個(gè)交易沒(méi)有任何 witness data,它的
txid
和wtxid
是一樣的肌访。 -
txid
還是一個(gè)交易主要的識(shí)別符:-
txid
必須用在 txin 中找默,用以指到上一個(gè) output - 如果一個(gè)錢包或服務(wù)目前使用
txid
來(lái)識(shí)別交易,預(yù)期更新后也是用相同方式吼驶。
-
P2SH-P2WPKH 簽章生成和驗(yàn)證
- 對(duì)花費(fèi) non-segwit UTXO 來(lái)說(shuō)惩激,產(chǎn)生簽章的演算法沒(méi)變。
- 對(duì)花費(fèi) P2SH-P2WPKH 來(lái)說(shuō):
- scriptSig 必須只有包含一個(gè)項(xiàng)目蟹演,就是
redeemScript
风钻。 - 對(duì)應(yīng)的 witness 欄位 必須 包含剛好兩個(gè)項(xiàng)目,一個(gè)簽章和公鑰酒请。
- 有一個(gè)新的簽章生成演算法被描述在 BIP143骡技。開發(fā)者必須謹(jǐn)慎的根據(jù)指示,并使用 BIP143 中的范例以確保他們可以重新制作
sighash
羞反。 - BIP143 中的簽章生成演算法包含了所有被花費(fèi)的 input布朦,簡(jiǎn)化了 air-gapped 輕量錢包和硬體錢包的設(shè)計(jì)。
- 請(qǐng)注意對(duì) P2SH-P2WPKH昼窗,
scriptCode
都是 26 bytes 其中包含一開始的 size byte是趴,像是0x1976a914{20-byte keyhash}88ac
,而不是redeemScript
或scriptPubKey
澄惊。 - Example
- scriptSig 必須只有包含一個(gè)項(xiàng)目蟹演,就是
網(wǎng)路服務(wù)(可選的)
- 如果錢包會(huì)透過(guò)比特幣 P2P 網(wǎng)路收送交易唆途,那網(wǎng)路服務(wù)是必須的富雅。
- 隔離驗(yàn)證相容的節(jié)點(diǎn)會(huì)透過(guò) message 中的 service 欄位:
NODE_WITNESS = (1 << 3)
公布他是支援隔離驗(yàn)證。(可參考 Protocol documentation) - 交易不包含驗(yàn)證資料(因此被序列化為原本的格式)肛搬,可被送到支援或不支援
NODE_WITNESS
的節(jié)點(diǎn)没佑。 - 交易如花費(fèi) segwit UTXOs(因此被序列化為新的格式),必須被送到支援
NODE_WITNESS
的節(jié)點(diǎn)温赔。 - 交易花費(fèi) segwit UTXOs 但其驗(yàn)證資料被剝奪(因此被序列化為原本的格式)蛤奢,應(yīng)被送到節(jié)點(diǎn)不支援
NODE_WITNESS
。然而在激活隔離驗(yàn)證之后這種交易是不合法且不會(huì)被接受到區(qū)塊中让腹。 - 網(wǎng)路服務(wù)的細(xì)節(jié)可以在 BIP144 中找到远剩。
使用者隱私
- 在隔離驗(yàn)證剛開始被激活的時(shí)候,比特幣網(wǎng)路可能會(huì)有隔離驗(yàn)證的交易數(shù)量限制骇窍。
- 使用隔離驗(yàn)證交易當(dāng)它還不普遍時(shí)瓜晤,可能使比特幣較容易被追蹤。
- 使用 P2SH-P2WPKH 作為預(yù)設(shè)的找錢 output 也可能有隱私上的影響腹纳。
交易手續(xù)費(fèi)估計(jì)
- 一個(gè)新的測(cè)量標(biāo)準(zhǔn)被定義以取代交易大小痢掠,叫"virtual size"(
vsize
)。 - 交易的
vsize
等于 3 倍于原本序列化結(jié)果的大小嘲恍,再加上新的序列化結(jié)果大小足画,再除 4 并進(jìn)位成整數(shù)。例如佃牛,如果一個(gè)交易新的序列化結(jié)果是 200 bytes淹辞,再移除掉marker
,flag
, 和witness
欄位后是 99 bytes,vsize
進(jìn)位后是 (99 * 3 + 200) / 4 = 125俘侠。 - 非隔離驗(yàn)證交易的
vsize
就是原本的 size象缀。 - 交易手續(xù)費(fèi)的估計(jì)應(yīng)是透過(guò)比較交易的
vsize
而不是 size。 - 開發(fā)者們應(yīng)注意在估計(jì)手續(xù)費(fèi)時(shí)不要犯差四倍錯(cuò)誤(忘記除 4)爷速。
升級(jí)的安全性
- 絕對(duì)不可以讓一般使用者在隔離驗(yàn)證完全被激活之前央星,產(chǎn)生任何 P2SH-P2WPKH 或其他隔離驗(yàn)證的 address。在激活前惫东,使用 P2SH-P2WPKH 或其他隔離驗(yàn)證的 address 可能導(dǎo)致永久的資金遺失莉给。
- 同樣地,絕對(duì)不可以找錢至隔離驗(yàn)證的 output 在激活之前廉沮。
- 隔離驗(yàn)證激活被定義在 BIP9颓遏。在 2016/11/15 之后和 2017/11/15 之前,如果在一個(gè) retarget cycle 的 2016 個(gè) block 之中有 1916 個(gè) blocks 示意為預(yù)備好的滞时,隔離驗(yàn)證會(huì)在下一個(gè) retarget cycle 被激活叁幢。
- 如果一個(gè)錢包沒(méi)有支援 BIP9,升級(jí)版不應(yīng)該被釋出直到被激活時(shí)漂洋。
- 如果擔(dān)心有些礦工不遵守新的規(guī)則遥皂,升級(jí)的錢包應(yīng)該延遲直到證據(jù)顯示大多數(shù)的礦工遵守新的規(guī)則。違反規(guī)則是很明顯的刽漂,透過(guò)不合法的的 orphaned blocks 顯示出來(lái)演训。
向后兼容
- 應(yīng)維持支援使用 P2PKH(address 其 prefix 為 1)進(jìn)行交易。