关键词(文中可能以英文表示):

隔离见证= SegWit =隔离见证 BIP=比特币改进提案 地址=比特币地址 txin=比特币交易输入 UTXO=未花费的交易输出 P2PKH=支付给PubKey哈希 P2SH=支付脚本哈希 P2WPKH=支付给见证人公共密钥哈希 scriptPubKey=输出的锁定脚本 scriptSig=用于解析scriptPubKey的解锁脚本 redeemScript=功能类似于scriptPubKey的脚本。它的一个副本被散列以创建P2SH地址,另一副本被放置在支出签名脚本中以强制执行其条件。 其他术语:多重签名,密钥哈希,Sighash,空白,轻量级钱包,孤立块,重定向周期

隔离验证钱包开发指南Part I(基本篇)

本篇文章大部分内容可在BIP141, BIP143, BIP144, BIP145 中找到。请将本篇文章视为阅读其他相关文章前的首要参考,及作为一需要完成及应避免事项的清单。

基本隔离验证支持

为了达到基本的隔离验证相容,钱包必须实作所有本章所描述功能:

送到P2SH

一个隔离验证相容钱包必须支持P2SH(BIP16) 及其address 格式。 就付款来说,钱包必须能转换一P2SH address成scriptPubKey,并建立交易。 对收款来说,钱包必须能建立一基于P2WPKH 脚本(本文稍后会描述)的P2SH address,并能识别出送到该address 的交易。 以上是必须的要求,即使钱包只接受单签名的收付款。

建立P2SH-P2WPKH Address

一个P2SH-P2WPKH address 可比拟比特币原本的单签名P2PKH address (address 其prefix 为1)。 像是任何P2SH address, P2SH-P2WPKH address 其prefix 为3。 直到有P2SH-P2WPKH UTXO被花费并揭露redeemScript,才得以分辨一个P2SH-P2WPKH address和non-segwit P2SH address(例如一个non-segwit multi-signature address)。 当收款只需要一个公钥时(像P2PKH),应使用P2SH-P2WPKH address。 P2SH-P2WPKH使用和P2PKH相同的公钥,但有一个重要的例外:公钥使用在P2SH-P2WPKH必须被压缩,ie大小33 bytes,以0x02或0x03开头。使用不同格式像是没有压缩过的公钥可能导致不可回溯的资金遗失。 创建一个P2SH-P2WPKH address: 计算公钥经SHA256在经RIPEMD160的值(keyhash)。虽然计算keyhash的公式和P2PKH相同,为了隐私和预防不小心用到没有压缩过的公钥,应避免重复使用keyhash。 P2SHredeemScript都是22 bytes。它是以OP_0为开始,接着keyhash(ie0x0014{20-byte keyhash})。 和所有P2SH相同,scriptPubKey是OP_HASH160 hash160(redeemScript) OP_EQUAL,然后address是相对应的P2SH address其prefix为3。

交易序列化

一个隔离验证相容的钱包必须支持原本的交易格式,像是nVersion|txins|txouts|nLockTime。 一个隔离验证相容的钱包必须支持新的序列化格式,像是nVersion|marker|flag|txins|txouts|witness|nLockTime: nVersion,txins,txouts,及nLockTime的格式和原本格式相同 marker必须是0x00 flag必须是0x01 witness是所有交易的witness data 的序列化结果: 所有txin 都连结到一个witness 栏位。所以,并没有数字指出有多少个witness 栏位,因为有多少txin 就代表有多少witness 栏位。 每个witness栏位都会始于一个compactSizeinteger指出有多少个项目在stack中。如果stack中有witness项目的话,会接再compactSizeinteger之后。 每个witness项目都始于一个compactSizeinteger表示该项目的bytes数。 如果该txin 没有连结任何witness data,它对应的witness 栏位就是0x00,表示stack 中的项目数为零。 如果所有txin都没有连结到任何witness data,该交易必须序列化成原本的交易格式,没有marker,flag及witness。例如,如果没有txin是来自segwit UTXO,该交易就必须序列化成原本的交易格式。(例外:coinbase交易) 交易的范例可以在BIP143 中的范例找到。钱包开发者可以用该范例测试他们的实作是否正确抓取交易资料以符合新的序列化格式。

交易ID

在隔离验证中,每一个交易会有2 个ID。 txid的定义保持不变:原本交易的序列化格式经过两次SHA256。 一个新的wtxid被定义为新的序列化格式加上witnes data经过两次SHA256。 如果一个交易没有任何witness data,它的txid和wtxid是一样的。 txid还是一个交易主要的识别符: txid必须用在txin 中,用以指到上一个output 如果一个钱包或服务目前使用txid来识别交易,预期更新后也是用相同方式。

P2SH-P2WPKH 签名生成和验证

对花费non-segwit UTXO 来说,产生签名的算法没变。 对花费P2SH-P2WPKH 来说: scriptSig必须只有包含一个项目,就是redeemScript。 对应的witness 栏位必须包含刚好两个项目,一个签名和公钥。 有一个新的签名生成算法被描述在BIP143。开发者必须谨慎的根据指示,并使用BIP143中的范例以确保他们可以重新制作sighash。 BIP143 中的签名生成算法包含了所有被花费的input,简化了air-gapped 轻量钱包和硬件钱包的设计。 请注意对P2SH-P2WPKH,scriptCode都是26 bytes其中包含一开始的size byte,像是0x1976a914{20-byte keyhash}88ac,而不是redeemScript或scriptPubKey。 Example

网络服务(可选的)

如果钱包会透过比特币P2P网络收送交易,那网络服务是必须的。 隔离验证相容的节点会透过message中的service栏位:NODE_WITNESS = (1 << 3)公布他是支持隔离验证。(可参考Protocol documentation) 交易不包含验证资料(因此被序列化为原本的格式),可被送到支持或不支持NODE_WITNESS的节点。 交易如花费segwit UTXOs(因此被序列化为新的格式),必须被送到支持NODE_WITNESS的节点。 交易花费segwit UTXOs但其验证资料被剥夺(因此被序列化为原本的格式),应被送到节点不支持NODE_WITNESS。然而在激活隔离验证之后这种交易是不合法且不会被接受到区块中。 网络服务的细节可以在BIP144 中找到。

使用者隐私

在隔离验证刚开始被激活的时候,比特币网络可能会有隔离验证的交易数量限制。 使用隔离验证交易当它还不普遍时,可能使比特币较容易被追踪。 使用P2SH-P2WPKH 作为预设的找钱output 也可能有隐私上的影响。

交易手续费估计

一个新的测量标准被定义以取代交易大小,叫”virtual size”(vsize)。 交易的vsize等于3倍于原本序列化结果的大小,再加上新的序列化结果大小,再除4并进位成整数。例如,如果一个交易新的序列化结果是200 bytes,再移除掉marker,flag,和witness栏位后是99 bytes,vsize进位后是(99 * 3 + 200) / 4 = 125。 非隔离验证交易的vsize就是原本的size。 交易手续费的估计应是透过比较交易的vsize而不是size。 开发者们应注意在估计手续费时不要犯差四倍错误(忘记除4)。

升级的安全性

绝对不可以让一般使用者在隔离验证完全被激活之前,产生任何P2SH-P2WPKH 或其他隔离验证的address。在激活前,使用P2SH-P2WPKH 或其他隔离验证的address 可能导致永久的资金遗失。 同样地,绝对不可以找钱至隔离验证的output 在激活之前。 隔离验证激活被定义在BIP9。在2016/11/15 之后和2017/11/15 之前,如果在一个retarget cycle 的2016 个block 之中有1916 个blocks 示意为预备好的,隔离验证会在下一个retarget cycle 被激活。 如果一个钱包没有支持BIP9,升级版不应该被释出直到被激活时。 如果担心有些矿工不遵守新的规则,升级的钱包应该延迟直到证据显示大多数的矿工遵守新的规则。违反规则是很明显的,透过不合法的的orphaned blocks 显示出来。

向后兼容

应维持支持使用P2PKH(address 其prefix 为1)进行交易。