官網(wǎng)原文:本章原文 建議打開原版對照著英文版同時(shí)閱讀杆煞。
官網(wǎng)原文:在git上閱讀 建議打開原版對照著英文版同時(shí)閱讀账胧。
互動(dòng)留言: 上報(bào)修改建議 當(dāng)然你也可以直接在github修改郑象。
回到目錄
中文共享閱讀:https://github.com/gdwwl/MasterBitcoin2CN
7.1介紹
在上一章中,我們介紹了比特幣交易的基本元素熏纯,并且查看了最常見的交易腳本類型桃熄,即P2PKH腳本。在本章中恨锚,我們將介紹更高級的腳本宇驾,以及如何使用它來構(gòu)建具有復(fù)雜條件的交易。
首先猴伶,我們將看看多重簽名腳本课舍。接下來,我們將檢查第二個(gè)最常見的交易腳本Pay-to-Script-Hash他挎,它打開了一個(gè)復(fù)雜腳本的整個(gè)世界筝尾。然后,我們將檢查新的腳本操作符办桨,通過時(shí)間鎖定將比特幣添加時(shí)間維度筹淫。
7.2多重簽名
多重簽名腳本設(shè)置了一個(gè)條件,其中N個(gè)公鑰被記錄在腳本中呢撞,并且至少有M個(gè)必須提供簽名來解鎖資金损姜。這也稱為M-N方案,其中N是密鑰的總數(shù)殊霞,M是驗(yàn)證所需的簽名的數(shù)量摧阅。例如,2/3的多重簽名是三個(gè)公鑰被列為潛在簽名人绷蹲,/其中至少有兩個(gè)必須用于為有效的交易創(chuàng)建簽名才能花費(fèi)資金/改為:至少有2個(gè)有效的簽名才能花費(fèi)資金/棒卷。此時(shí),標(biāo)準(zhǔn)多重簽名腳本限制在最多15個(gè)列出的公鑰祝钢,這意味著您可以從1到15之間的多重簽名或該范圍內(nèi)的任何組合執(zhí)行任何操作比规。在本書發(fā)布之前,限制15個(gè)已列出的/鍵/可能會(huì)被解除拦英,因此請檢查isStandard()函數(shù)以查看當(dāng)前網(wǎng)絡(luò)接受的內(nèi)容蜒什。
設(shè)置M-N多重簽名條件的鎖定腳本的一般形式是:
M <Public Key 1> <Public Key 2> ... <Public Key N> N CHECKMULTISIG
/其中N是列出的公鑰的總數(shù),M是花費(fèi)輸出所需的簽名的數(shù)量龄章。改為:
M是花費(fèi)輸出所需的簽名的數(shù)量吃谣,N是列出的公鑰的總數(shù)乞封。/
設(shè)置2到3多重簽名條件的鎖定腳本如下所示:
2 <Public Key A> <Public Key B> <Public Key C> 3 CHECKMULTISIG
上述鎖定腳本可由含有簽名和公鑰的腳本予以解鎖:
<Signature B> <Signature C>
或者由3個(gè)存檔公鑰中的任意2個(gè)相一致的私鑰簽名組合予以解鎖。
兩個(gè)腳本組合將形成一個(gè)驗(yàn)證腳本:
<Signature B> <Signature C> 2 <Public Key A> <Public Key B> <Public Key C> 3 CHECKMULTISIG
當(dāng)執(zhí)行時(shí)岗憋,只有當(dāng)未解鎖版腳本與解鎖腳本設(shè)置條件相匹配時(shí)肃晚,組合腳本才顯示得到結(jié)果為真(Ture)。上述例子中相應(yīng)的設(shè)置條件即為:未解鎖腳本是否含有3個(gè)公鑰中的任意2個(gè)/相一致的 改為相對應(yīng)/私鑰的有效簽名仔戈。
CHECKMULTISIG執(zhí)行中的bug
CHECKMULTISIG的執(zhí)行中有一個(gè)bug关串,需要一些輕微的解決方法。 當(dāng)CHECKMULTISIG執(zhí)行時(shí)监徘,它應(yīng)該消耗 堆棧(stack) 上的M + N + 2個(gè)項(xiàng)目作為參數(shù)晋修。 然而,由于該錯(cuò)誤凰盔,CHECKMULTISIG將彈出(pop)超出預(yù)期的額外值或一個(gè)值墓卦。
我們來看看這個(gè)更詳細(xì)的/使用以前的/驗(yàn)證示例:
<Signature B> <Signature C> 2 <Public Key A> <Public Key B> <Public Key C> 3 CHECKMULTISIG
首先,CHECKMULTISIG彈出最上面的項(xiàng)目户敬,這是N(在這個(gè)例子中N是“3”)落剪。然后它彈出N個(gè)項(xiàng)目,這是可以簽名的公鑰尿庐。在這個(gè)例子中忠怖,公鑰A,B和C.然后抄瑟,它彈出一個(gè)項(xiàng)目凡泣,即M,仲裁(需要多少個(gè)簽名)皮假。這里M = 2鞋拟。此時(shí),CHECKMULTISIG應(yīng)彈出最終的M個(gè)項(xiàng)目钞翔,這些是簽名严卖,并查看它們是否有效席舍。然而布轿,不幸的是,實(shí)施中的錯(cuò)誤導(dǎo)致CHECKMULTISIG再彈出一個(gè)項(xiàng)目(總共M + 1個(gè))来颤。檢查簽名時(shí)汰扭,不考慮額外的項(xiàng)目,因此它對CHECKMULTISIG本身沒有直接影響福铅。但是萝毛,必須存在額外的值,因?yàn)槿绻淮嬖诨瑒t當(dāng)CHECKMULTISIG嘗試彈出空堆棧時(shí)笆包,會(huì)導(dǎo)致堆棧錯(cuò)誤和腳本失敾防俊(將交易標(biāo)記為無效)。因?yàn)轭~外的項(xiàng)目被忽略庵佣,它可以是任何東西歉胶,但通常使用0。
因?yàn)檫@個(gè)bug成為共識(shí)規(guī)則的一部分巴粪,所以現(xiàn)在它必須永遠(yuǎn)被復(fù)制通今。因此,正確的腳本驗(yàn)證將如下所示:
0 <Signature B> <Signature C> 2 <Public Key A> <Public Key B> <Public Key C> 3 CHECKMULTISIG
這樣解鎖腳本就不是下面的:
<Signature B> <Signature C>
而是:
0 <Signature B> <Signature C>
從現(xiàn)在開始肛根,如果你看到一個(gè)multisig解鎖腳本辫塌,你應(yīng)該期望看到一個(gè)額外的0開始,其唯一的目的是解決一個(gè)bug派哲,意外地成為一個(gè)共識(shí)規(guī)則的解決方法臼氨。
//增加解釋 譯者注:即保證例子中有3個(gè)私鑰簽名(其中2有效簽名,其中1個(gè)為0的無效簽名)對應(yīng)3個(gè)公鑰用于檢查多重簽名芭届,從而保證腳本不產(chǎn)生bug一也。/
7.3 P2SH(Pay-to-Script-Hash)
P2SH在2012年被作為一種新型、強(qiáng)大喉脖、且能大大簡化復(fù)雜交易腳本的交易類型而引入椰苟。為進(jìn)一步解釋P2SH的必要性,讓我們先看一個(gè)實(shí)際的例子树叽。
在第1章中舆蝴,我們曾介紹過Mohammed,一個(gè)迪拜的電子產(chǎn)品進(jìn)口商题诵。Mohammed的公司采用比特幣多重簽名作為其公司會(huì)計(jì)賬簿記賬要求洁仗。多重簽名腳本是比特幣高級腳本最為常見的運(yùn)用之一,是一種具有相當(dāng)大影響力的腳本性锭。針對所有的顧客支付(即應(yīng)收賬款)赠潦,Mohammed的公司要求采用多重簽名交易〔莞裕基于多重簽名機(jī)制她奥,顧客的任何支付都需要至少兩個(gè)簽名才能解鎖,一個(gè)來自Mohammed怎棱,另一個(gè)來自其合伙人或擁有備份鑰匙的代理人哩俭。這樣的多重簽名機(jī)制能為公司治理提供管控便利,同時(shí)也能有效防范盜竊拳恋、挪用和遺失凡资。
最終的腳本非常長:
2 <Mohammed's Public Key> <Partner1 Public Key> <Partner2 Public Key> <Partner3 Public Key> <Attorney Public Key> 5 OP_C HECKMULTISIG
雖然多重簽名十分強(qiáng)大,但其使用起來還是多有不便谬运∠读蓿基于之前的腳本垦藏,Mohammed必須在客戶付款前將該腳本發(fā)送給每一位客戶,而每一位顧客也必須使用特制的能產(chǎn)生客戶交易腳本的比特幣錢包軟件伞访,每位顧客還得學(xué)會(huì)如何利用腳本來完成交易膝藕。此外,由于腳本可能包含特別長的公鑰咐扭,最終的交易腳本可能是最初交易腳本長度的5倍之多芭挽。額外長度的腳本將給客戶造成費(fèi)用負(fù)擔(dān)。最后蝗肪,一個(gè)長的交易腳本將一直記錄在所有節(jié)點(diǎn)的隨機(jī)存儲(chǔ)器的UTXO集中袜爪,直到該筆資金被使用。/所有這些都使得在實(shí)際交易中采用復(fù)雜輸出腳本從而顯得困難重重薛闪。/改為:采用這種復(fù)雜輸出腳本使得在實(shí)際交易中變得困難重重辛馆。/
P2SH正是為了解決這一實(shí)際難題而被引入的,它旨在使復(fù)雜腳本的運(yùn)用能與直接向比特幣地址支付一樣簡單豁延。在P2SH 支付中昙篙,復(fù)雜的鎖定腳本被電子指紋所取代,/電子指紋為密碼學(xué)哈希 改為電子指紋是指密碼學(xué)中的哈希值/诱咏。當(dāng)一筆交易試圖支付UTXO時(shí)苔可,要解鎖支付腳本,它必須含有與哈希相匹配的腳本袋狞。P2SH的含義是焚辅,向與該哈希匹配的腳本支付,當(dāng)輸出被支付時(shí)苟鸯,該腳本將在后續(xù)呈現(xiàn)同蜻。
在P2SH交易中,鎖定腳本由哈希/改為:哈希運(yùn)算后的20字節(jié)的散列值/ 取代早处,哈希指代的是贖回腳本/ 建議對照原文再譯/湾蔓。因?yàn)樗谙到y(tǒng)中是在贖回時(shí)出現(xiàn)而不是以鎖定腳本模式出現(xiàn)。表7-1列示了非P2SH腳本砌梆,表7-2列示了P2SH腳本默责。
表7-1不含P2SH的復(fù)雜腳本
從表中可以看出,對于P2SH么库,詳細(xì)描述了輸出(贖回腳本)的條件的復(fù)雜腳本不會(huì)在鎖定腳本中顯示傻丝。 相反,只有它的散列 /散列值 在鎖定腳本中 /增加:呈現(xiàn)/诉儒,并且兌換腳本本身稍后呈現(xiàn) /去掉這/,作為解鎖腳本在輸出花費(fèi)時(shí)的一部分亏掀。 這會(huì)將收費(fèi)和復(fù)雜性的負(fù)擔(dān)從發(fā)送方轉(zhuǎn)移到/收款人(花費(fèi)) / 改為:這使得給礦工的交易費(fèi)用從發(fā)送方轉(zhuǎn)移到收款方忱反,復(fù)雜的計(jì)算工作也從從發(fā)送方轉(zhuǎn)移到收款方泛释。
//整段用中國人能讀懂的方法重譯:
輸出腳本(Redeem Script)中的“2 Pubkey1 Pubkey2 Pubkey3 Pubkey4 Pubkey5 5 CHECKMULTISIG”的內(nèi)容,沒有出現(xiàn)在鎖定腳本(Locking Script 表中第二行內(nèi)容)中温算,但對實(shí)現(xiàn)上很長的一大串的“2 Pubkey1 Pubkey2 Pubkey3 Pubkey4 Pubkey5 5 CHECKMULTISIG”(有520字節(jié))進(jìn)行哈希運(yùn)算后的20字節(jié)的散列值取代之怜校,然后將之(“2 Pubkey1 Pubkey2 Pubkey3 Pubkey4 Pubkey5 5 CHECKMULTISIG”)放到解鎖腳本中(Unlocking Script)。這使得給礦工的交易費(fèi)用從發(fā)送方轉(zhuǎn)移到收款方注竿,并且令復(fù)雜的計(jì)算工作也從從發(fā)送方轉(zhuǎn)移到收款方茄茁。
【譯者注:本段原文描述如下:As you can see from the tables, with P2SH the complex script that details the conditions for spending the output (redeem script) is not presented in the locking script. Instead, only a hash of it is in the locking script and the redeem script itself is presented later, as part of the unlocking script when the output is spent. This shifts the burden in fees and complexity from the sender to the recipient (spender) of the transaction.】
讓我們再看下Mohammed公司的例子,復(fù)雜的多重簽名腳本和相應(yīng)的P2SH腳本巩割。
首先裙顽,Mohammed公司對所有顧客訂單采用多重簽名腳本:
2 <Mohammed's Public Key> <Partner1 Public Key> <Partner2 Public Key> <Partner3 Public Key> <Attorney Public Key> 5 CHECKMULTISIG
如果占位符由實(shí)際的公鑰(以04開頭的520字節(jié))替代,你將會(huì)看到的腳本會(huì)非常地長:
2
04C16B8698A9ABF84250A7C3EA7EEDEF9897D1C8C6ADF47F06CF73370D74DCCA01CDCA79DCC5C395D7EEC6984D83F1F50C900A24DD47F569FD4193AF5DE762C58704A2192968D8655D6A935BEAF2CA23E3FB87A3495E7AF308EDF08DAC3C1FCBFC2C75B4B0F4D0B1B70CD2423657738C0C2B1D5CE65C97D78D0E34224858008E8B49047E63248B75DB7379BE9CDA8CE5751D16485F431E46117B9D0C1837C9D5737812F393DA7D4420D7E1A9162F0279CFC10F1E8E8F3020DECDBC3C0DD389D99779650421D65CBD7149B255382ED7F78E946580657EE6FDA162A187543A9D85BAAA93A4AB3A8F044DADA618D087227440645ABE8A35DA8C5B73997AD343BE5C2AFD94A5043752580AFA1ECED3C68D446BCAB69AC0BA7DF50D56231BE0AABF1FDEEC78A6A45E394BA29A1EDF518C022DD618DA774D207D137AAB59E0B000EB7ED238F4D800 5 CHECKMULTISIG
整個(gè)腳本都可由僅為20個(gè)字節(jié)的密碼哈希所取代宣谈,首先采用SH256哈希算法愈犹,隨后對其運(yùn)用RIPEMD160算法。20字節(jié) 的腳本為:
54c557e07dde5bb6cb791c7a540e0a4796f5e97
一筆P2SH交易運(yùn)用鎖定腳本將輸出與哈希關(guān)聯(lián)闻丑,而不是與前面特別長的腳本所關(guān)聯(lián)漩怎。使用的鎖定腳本為:
HASH160 54c557e07dde5bb6cb791c7a540e0a4796f5e97e EQUAL
正如你所看到的,這個(gè)腳本比前面的長腳本簡短多了嗦嗡。取代“向該5個(gè)多重簽名腳本支付”勋锤,這個(gè)P2SH等同于“向含該哈希的腳本支付”。顧客在向Mohammed公司支付時(shí)侥祭,只需在其支付指令中納入這個(gè)非常簡短的鎖定腳本即可怪得。當(dāng) Mohammed想要花費(fèi)這筆UTXO時(shí),附上原始贖回腳本(與UTXO鎖定的哈希)和必要的解鎖簽名即可卑硫,如:
<Sig1> <Sig2> <2 PK1 PK2 PK3 PK4 PK5 5 CHECKMULTISIG>
兩個(gè)腳本經(jīng)由兩步實(shí)現(xiàn)組合徒恋。
首先,將贖回腳本與鎖定腳本比對以確認(rèn)其與哈希是否匹配:
<2 PK1 PK2 PK3 PK4 PK5 5 CHECKMULTISIG> HASH160 <redeem scriptHash> EQUAL
假如贖回腳本與哈希匹配欢伏,解鎖腳本會(huì)被執(zhí)行以釋放贖回腳本:
<Sig1> <Sig2> 2 PK1 PK2 PK3 PK4 PK5 5 CHECKMULTISIG
本章中描述的幾乎所有腳本只能以P2SH腳本來實(shí)現(xiàn)入挣。 它們不能直接用在UTXO的鎖定腳本中。
7.3.1 P2SH地址
P2SH的另一重要特征是它能將腳本哈希編譯為一個(gè)地址(其定義請見BIP0013 /BIP-13)硝拧。P2SH地址是基于Base58編碼的一 個(gè)含有20個(gè)字節(jié)哈希的腳本径筏,就像比特幣地址是基于Base58編碼的一個(gè)含有20個(gè)字節(jié)的公鑰。由于P2SH地址采用5作為前綴障陶,這導(dǎo)致基于Base58編碼的地址以“3”開頭滋恬。例如,Mohammed的腳本抱究,基于Base58編碼下的P2SH地址變 為“39RF6JqABiHdYHkfChV6USGMe6Nsr66Gzw”恢氯。此時(shí),Mohammed可以將該地址發(fā)送給他的客戶,這些客戶可以 采用任何的比特幣錢包實(shí)現(xiàn)簡單支付勋拟,就像這是一個(gè)比特幣地址一樣勋磕。以“3”為前綴給予客戶這是一種特殊類型的地址的暗示,該地址與一個(gè)腳本相對應(yīng)而非與一個(gè)公鑰相對應(yīng)敢靡,但是它的效果與比特幣地址支付別無二致挂滓。
P2SH地址隱藏了所有的復(fù)雜性,因此啸胧,運(yùn)用其進(jìn)行支付的人將不會(huì)看到腳本赶站。
7.3.2 P2SH的優(yōu)點(diǎn)
與直接使用復(fù)雜腳本以鎖定輸出的方式相比,P2SH具有以下特點(diǎn):
- 在交易輸出中纺念,復(fù)雜腳本由簡短電子指紋取代贝椿,使得交易代碼變短。
- 腳本能被編譯為地址柠辞,支付指令的發(fā)出者和支付者的比特幣錢包不需要復(fù)雜工序就可以執(zhí)行P2SH团秽。
- P2SH將構(gòu)建腳本的重?fù)?dān)轉(zhuǎn)移至接收方,而非發(fā)送方叭首。
- P2SH將長腳本數(shù)據(jù)存儲(chǔ)的負(fù)擔(dān)從輸出方(存儲(chǔ)于UTXO集习勤,影響內(nèi)存)轉(zhuǎn)移至輸入方(存儲(chǔ)在區(qū)塊鏈里面)。
- P2SH將長腳本數(shù)據(jù)存儲(chǔ)的重?fù)?dān)從當(dāng)前(支付時(shí))轉(zhuǎn)移至未來(花費(fèi)時(shí))焙格。
- P2SH將長腳本的交易費(fèi)成本從發(fā)送方轉(zhuǎn)移至接收方图毕,接收方在使用該筆資金時(shí)必須含有贖回腳本。
7.3.3贖回腳本和標(biāo)準(zhǔn)確認(rèn)
在0.9.2版比特幣核心客戶端之前眷唉,P2SH僅限于標(biāo)準(zhǔn)比特幣交易腳本類型(即通過標(biāo)準(zhǔn)函數(shù)檢驗(yàn)的腳本)予颤。這也意味著使用該筆資金的交易中的贖回腳本只能是標(biāo)準(zhǔn)化的P2PK、P2PKH或者多重簽名冬阳,而非RETURN 和P2SH蛤虐。
作為0.9.2版的比特幣核心客戶端,P2SH交易能包含任意有效的腳本肝陪,這使得P2SH標(biāo)準(zhǔn)更為靈活驳庭,也可以用于多種新的或復(fù)雜類型的交易。
請記住不能將P2SH植入P2SH贖回腳本氯窍,因?yàn)镻2SH不能自循環(huán)饲常。雖然在技術(shù)上可以將RETURN包含在贖回腳本中,但由于規(guī)則中沒有策略阻止您執(zhí)行此操作狼讨,因此在驗(yàn)證期間執(zhí)行RETURN將導(dǎo)致交易被標(biāo)記為無效贝淤,因此這是不實(shí)際的。
需要注意的是政供,因?yàn)橼H回腳本只有在你試圖發(fā)送一個(gè)P2SH輸出時(shí)才會(huì)在比特幣網(wǎng)絡(luò)中出現(xiàn)播聪,假如你將輸出與一個(gè)無效的交易哈希鎖定朽基,則它將會(huì)被忽略。該UTXO將會(huì)被成功鎖定犬耻,但是你將不能使用該筆資金踩晶,因?yàn)榻灰字泻汹H回腳本执泰,該腳本因是一個(gè)無效的腳本而不能被接受枕磁。這樣的處理機(jī)制也衍生出一個(gè)風(fēng)險(xiǎn),你可能將比特幣鎖定在一個(gè)未來不能被花費(fèi)的P2SH中术吝。因?yàn)楸忍貛啪W(wǎng)絡(luò)本身會(huì)接受這一P2SH计济,即便它與無效的贖回腳本所對應(yīng)(因?yàn)樵撢H回腳本哈希沒有對其所表征的腳本給出指令)。
注意 | P2SH鎖定腳本包含一個(gè)贖回腳本哈希排苍,該腳本對于贖回腳本本身未提供任何描述沦寂。P2SH交易即便在贖回腳本無效的情況下也會(huì)被認(rèn)為有效。//你可能會(huì)偶然地將以鎖定比特幣以這樣一種未來不能被花費(fèi)的方式予淘衙。改為:如果處理不當(dāng)传藏,有可能會(huì)出現(xiàn)一個(gè)事故,即你的比特幣可能會(huì)被鎖死在P2SH這個(gè)交易中彤守,導(dǎo)致你以后再也不能花費(fèi)這筆比特幣了毯侦。 |
---|
7.4 數(shù)據(jù)記錄輸出(RETURN操作符)
比特幣的/分發(fā)和時(shí)間戳賬戶機(jī)制(也即區(qū)塊鏈) 改為:比特幣的去中心特點(diǎn)和時(shí)間戳賬本機(jī)制,即區(qū)塊鏈技術(shù)/具垫,其潛在運(yùn)用將大大超越支付領(lǐng)域侈离。許多開發(fā)者試圖充分發(fā)揮交易腳本語言的安全性和可恢復(fù)性優(yōu)勢,將其運(yùn)用于電子公證服務(wù)筝蚕、證券認(rèn)證和智能協(xié)議 /合約 等領(lǐng)域卦碾。/比特幣腳本語言的早期運(yùn)用主 要包括在區(qū)塊鏈上創(chuàng)造出交易輸出。改為:很多早期的開發(fā)者利用比特幣這種能將交易數(shù)據(jù)放到區(qū)塊鏈上的技術(shù)進(jìn)行了很多嘗試 /,例如,為文件記錄電子指紋赃承,則任何人都可以通過該機(jī)制在特定的日期建立關(guān)于文檔存在性的證明吭练。
運(yùn)用比特幣的區(qū)塊鏈技術(shù)存儲(chǔ)與比特幣支付不相關(guān)數(shù)據(jù)的做法是一個(gè)有爭議的話題。許多開發(fā)者認(rèn)為其有濫用的嫌疑尊残,因而試圖予以阻止。另一些開發(fā)者則將之視為區(qū)塊鏈技術(shù)強(qiáng)大功能的有力證明,從而試圖給予大力支持绘梦。那些反對非支付相關(guān)應(yīng)用的開發(fā)者認(rèn)為這樣做將引致“區(qū)塊鏈膨脹”,因?yàn)樗械膮^(qū)塊鏈節(jié)點(diǎn)都將以消耗磁盤存儲(chǔ)空間為成本赴魁,負(fù)擔(dān)存儲(chǔ)此類 數(shù)據(jù)的任務(wù)卸奉。更為嚴(yán)重的是,此類交易僅將比特幣地址當(dāng)作自由組合的20個(gè)字節(jié)而使用颖御,進(jìn)而會(huì)產(chǎn)生不能用于交易的UTXO榄棵。因?yàn)楸忍貛诺刂分皇潜划?dāng)作數(shù)據(jù)使用凝颇,并不與私鑰相匹配,所以會(huì)導(dǎo)致UTXO不能被用于交易疹鳄,因而是一種偽支付行為拧略。因此,這些交易永遠(yuǎn)不會(huì)被花費(fèi)瘪弓,所以永遠(yuǎn)不會(huì)從UTXO集中刪除垫蛆,并導(dǎo)致UTXO數(shù)據(jù)庫的大小永遠(yuǎn)增加或“膨脹”。
在0.9版的比特幣核心客戶端上腺怯,通過采用Return操作符最終實(shí)現(xiàn)了妥協(xié)袱饭。Return允許開發(fā)者在交易輸出上增加80字節(jié)的非交易數(shù)據(jù)。然后呛占,與偽交易型的UTXO不同虑乖,Return創(chuàng)造了一種明確的可復(fù)查的非交易型輸出,此類數(shù)據(jù)無需存儲(chǔ)于UTXO集晾虑。Return輸出被記錄在區(qū)塊鏈上疹味,它們會(huì)消耗磁盤空間,也會(huì)導(dǎo)致區(qū)塊鏈規(guī)模的增加帜篇,但 它們不存儲(chǔ)在UTXO集中糙捺,因此也不會(huì)使得UTXO內(nèi)存膨脹,更不會(huì)以消耗代價(jià)高昂的內(nèi)存為代價(jià)使全節(jié)點(diǎn)都不堪重負(fù)坠狡。
RETURN 腳本的樣式:
RETURN <data>
“data”部分被限制為80字節(jié)继找,且多以哈希方式呈現(xiàn),如32字節(jié)的SHA256算法輸出逃沿。許多應(yīng)用都在其前面加上前綴以輔助認(rèn)定婴渡。例如,電子公正服務(wù)的證明材料采用8個(gè)字節(jié)的前綴“DOCPROOF”凯亮,在十六進(jìn)制算法中边臼,相應(yīng)的ASCII碼為 44 4f 43 50 52 4f 4f 46。
請記住 RETURN 不涉及可用于支付的解鎖腳本的特點(diǎn)假消, RETURN 不能使用其輸出中所鎖定的資金柠并,因此它也就沒有必要記錄在蘊(yùn)含潛在成本的UTXO集中,所以 RETURN 實(shí)際是沒有成本的富拗。 RETURN 常為一個(gè)金額為0的比特幣輸出臼予, 因?yàn)槿魏闻c該輸出相對應(yīng)的比特幣都會(huì)永久消失。假如一筆 RETURN 被作為一筆交易的輸入啃沪,腳本驗(yàn)證引擎將會(huì)阻止驗(yàn)證腳本的執(zhí)行粘拾,將標(biāo)記交易為無效。如果你碰巧將 RETURN 的輸出作為另一筆交易的輸入创千,則該交易是無效的缰雇。
一筆標(biāo)準(zhǔn)交易(通過了 isStandard() 函數(shù)檢驗(yàn)的)只能有一個(gè) RETURN 輸出入偷。但是單個(gè)RETURN 輸出能與任意類型的輸出交易進(jìn)行組合。
Bitcoin Core中添加了兩個(gè)新版本的命令行選項(xiàng)械哟。 選項(xiàng)datacarrier控制RETURN交易的中繼和挖掘疏之,默認(rèn)設(shè)置為“1”以允許它們。 選項(xiàng)datacarriersize采用一個(gè)數(shù)字參數(shù)暇咆,指定RETURN腳本的最大大蟹孀Α(以字節(jié)為單位),默認(rèn)為83字節(jié)糯崎,允許最多80個(gè)字節(jié)的RETURN數(shù)據(jù)加上一個(gè)字節(jié)的RETURN操作碼和兩個(gè)字節(jié)的PUSHDATA操作碼几缭。
注意: | 最初提出了RETURN河泳,限制為80字節(jié)沃呢,但是當(dāng)功能被釋放時(shí),限制被減少到40字節(jié)拆挥。 2015年2月薄霜,在Bitcoin Core的0.10版本中,限制提高到80字節(jié)纸兔。 節(jié)點(diǎn)可以選擇不中繼或重新啟動(dòng)RETURN惰瓜,或者只能中繼和挖掘包含少于80字節(jié)數(shù)據(jù)的RETURN。 |
---|
7.5時(shí)間鎖(Timelocks)
時(shí)間鎖是只允許在一段時(shí)間后才允許支出的交易汉矿。比特幣從一開始就有一個(gè)交易級的時(shí)間鎖定功能崎坊。它由交易中的nLocktime字段實(shí)現(xiàn)。在2015年底和2016年中期推出了兩個(gè)新的時(shí)間鎖定功能洲拇,提供UTXO級別的時(shí)間鎖定功能奈揍。這些是CHECKLOCKTIMEVERIFY和CHECKSEQUENCEVERIFY。
時(shí)間鎖對于后期交易和將資金鎖定到將來的日期很有用赋续。更重要的是男翰,時(shí)間鎖將比特幣腳本擴(kuò)展到時(shí)間的維度,為復(fù)雜的多級智能合同打開了大門纽乱。
7.5.1交易鎖定時(shí)間(nLocktime)
比特幣從一開始就有一個(gè)交易級的時(shí)間鎖功能蛾绎。交易鎖定時(shí)間是交易級設(shè)置(交易數(shù)據(jù)結(jié)構(gòu)中的一個(gè)字段),它定義交易有效的最早時(shí)間鸦列,并且可以在網(wǎng)絡(luò)上中繼或添加到區(qū)塊鏈中租冠。鎖定時(shí)間也稱為nLocktime,是來自于Bitcoin Core代碼庫中使用的變量名稱薯嗤。在大多數(shù)交易中將其設(shè)置為零顽爹,以指示即時(shí)傳播和執(zhí)行。如果nLocktime不為零应民,低于5億话原,則將其解釋為塊高度夕吻,這意味著交易無效,并且在指定的塊高度之前未被中繼或包含在塊鏈中繁仁。如果超過5億涉馅,它被解釋為Unix紀(jì)元時(shí)間戳(自Jan-1-1970之后的秒數(shù)),并且交易在指定時(shí)間之前無效黄虱。指定未來塊或時(shí)間的nLocktime的交易必須由始發(fā)系統(tǒng)持有稚矿,并且只有在有效后才被發(fā)送到比特幣網(wǎng)絡(luò)。如果交易在指定的nLocktime之前傳輸?shù)骄W(wǎng)絡(luò)捻浦,那么第一個(gè)節(jié)點(diǎn)就會(huì)拒絕該交易晤揣,并且不會(huì)被中繼到其他節(jié)點(diǎn)。使用nLocktime等同于一張延期支票朱灿。
7.5.1.1交易鎖定時(shí)間限制
nLocktime就是一個(gè)限制昧识,雖然它可以在將來花費(fèi),但是到現(xiàn)在為止盗扒,它并不能使用它們跪楞。我們來解釋一下,下面的例子侣灶。
Alice簽署了一筆交易甸祭,支付給Bob的地址,并將交易nLocktime設(shè)定為3個(gè)月褥影。Alice把這筆交易發(fā)送給Bob池户。有了這個(gè)交易,Alice和Bob知道:
- 在3個(gè)月過去之前凡怎,Bob不能完成交易進(jìn)行變現(xiàn)校焦。
- Bob可以在3個(gè)月后接受交易。
然而: - Alice可以創(chuàng)建另一個(gè)交易栅贴,雙重花費(fèi)相同的輸入斟湃,而不需要鎖定時(shí)間。 因此檐薯,Alice可以在3個(gè)月過去之前花費(fèi)相同的UTXO凝赛。
- Bob不能保證Alice不會(huì)這樣做。
了解交易nLocktime的限制很重要坛缕。 唯一的保證是Bob在3個(gè)月過去之前無法兌換它墓猎。 不能保證Bob得到資金。 為了實(shí)現(xiàn)這樣的保證赚楚,時(shí)間限制必須放在UTXO本身上毙沾,并成為鎖定腳本的一部分,而不是交易宠页。 這是通過下一種形式的時(shí)間鎖定來實(shí)現(xiàn)的左胞,稱為檢查鎖定時(shí)間驗(yàn)證(CLTV)寇仓。
7.5.2檢查鎖定時(shí)間驗(yàn)證Check Lock Time Verify (CLTV)
2015年12月,引入了一種新形式的時(shí)間鎖進(jìn)行比特幣軟分叉升級烤宙。根據(jù)BIP-65中的規(guī)范遍烦,腳本語言添加了一個(gè)名為CHECKLOCKTIMEVERIFY(CLTV)的新腳本操作符。 CLTV是每個(gè)輸出的時(shí)間鎖定躺枕,而不是每個(gè)交易的時(shí)間鎖定服猪,與nLocktime的情況一樣。這允許在應(yīng)用時(shí)間鎖的方式上具有更大的靈活性拐云。
簡單來說罢猪,通過在輸出的贖回腳本中添加CLTV操作碼來限制輸出,從而只能在指定的時(shí)間過后使用叉瘩。
提示 | 當(dāng)nLocktime是交易級時(shí)間鎖定時(shí)膳帕,CLTV是基于輸出的時(shí)間鎖。 |
---|
CLTV不會(huì)取代nLocktime房揭,而是限制特定的UTXO备闲,這樣他們只能在未來的交易中花費(fèi)nLocktime設(shè)置為更大或相等的值 /改為:CLTV不會(huì)取代nLocktime,而是限制特定的UTXO捅暴,并通過將nLocktim設(shè)置為更大或相等的值,從而達(dá)到在未來才能花費(fèi)這筆錢的目的咧纠。
CLTV操作碼采用一個(gè)參數(shù)作為輸入蓬痒,表示為與nLocktime(塊高度或Unix紀(jì)元時(shí)間)相同格式的數(shù)字 。如VERIFY后綴所示漆羔,CLTV如果結(jié)果為FALSE梧奢,則停止執(zhí)行腳本的操作碼類型。如果結(jié)果為TRUE演痒,則繼續(xù)執(zhí)行亲轨。
為了使用CLTV鎖定輸出,將其插入到創(chuàng)建輸出的交易中的輸出的贖回腳本中鸟顺。例如惦蚊,如果Alice支付Bob的地址,輸出通常會(huì)包含一個(gè)這樣的P2PKH腳本:
DUP HASH160 <Bob's Public Key Hash> EQUALVERIFY CHECKSIG
要鎖定一段時(shí)間讯嫂,比如說3個(gè)月以后蹦锋,交易將是一個(gè)P2SH交易,其中包含一個(gè)贖回腳本:
<now + 3 months> CHECKLOCKTIMEVERIFY DROP DUP HASH160 <Bob's Public Key Hash> EQUALVERIFY CHECKSIG
其中<now +3個(gè)月>是從交易開始被挖礦時(shí)間起計(jì)3個(gè)月的塊高度或時(shí)間值:當(dāng)前塊高度+12,960(塊)或當(dāng)前Unix紀(jì)元時(shí)間+7,760,000(秒)∨费浚現(xiàn)在莉掂,不要擔(dān)心CHECKLOCKTIMEVERIFY之后的DROP操作碼,下面很快就會(huì)解釋。
當(dāng)Bob嘗試花費(fèi)這個(gè)UTXO時(shí)千扔,他構(gòu)建了一個(gè)引用UTXO作為輸入的交易憎妙。他使用他的簽名和公鑰在該輸入的解鎖腳本库正,并將交易nLocktime設(shè)置為等于或更大于Alice設(shè)置的CHECKLOCKTIMEVERIFY 時(shí)間鎖。然后厘唾,Bob在比特幣網(wǎng)絡(luò)上廣播交易诀诊。
Bob的交易評估如下。如果Alice設(shè)置的CHECKLOCKTIMEVERIFY參數(shù)小于或等于支出交易的nLocktime阅嘶,腳本執(zhí)行將繼續(xù)(就好像執(zhí)行“無操作”或NOP操作碼一樣)属瓣。否則,腳本執(zhí)行停止讯柔,并且該交易被視為無效抡蛙。
更確切地說,CHECKLOCKTIMEVERIFY失敗并停止執(zhí)行魂迄,標(biāo)記交易無效(來源:BIP-65):
- 堆棧是空的要么
- 堆棧中的頂部項(xiàng)小于0;要么
- 頂層堆棧項(xiàng)和nLocktime字段的鎖定時(shí)間類型(高度或者時(shí)間戳)不相同;要么
- 頂層堆棧項(xiàng)大于交易的nLocktime字段;要么
- 輸入的nSequence字段為0xffffffff粗截。
注意 | CLTV和nLocktime使用相同的格式來描述時(shí)間鎖定,無論是塊高度還是自Unix紀(jì)元以秒鐘以來所經(jīng)過的時(shí)間捣炬。 最重要的是熊昌,在一起使用時(shí),nLocktime的格式必須與輸入中的CLTV格式相匹配湿酸,它們必須以秒為單位引用塊高度或時(shí)間婿屹。 |
---|
執(zhí)行后,如果滿足CLTV推溃,則其之前的時(shí)間參數(shù)仍然作為堆棧中的頂級項(xiàng)昂利,并且可能需要使用DROP進(jìn)行刪除,才能正確執(zhí)行后續(xù)腳本操作碼铁坎。 為此蜂奸,您將經(jīng)常在腳本中看到CHECKLOCKTIMEVERIFY+DROP在一起使用。
通過將nLocktime與CLTV結(jié)合使用硬萍,交易鎖定時(shí)間限制中描述的情況發(fā)生變化扩所。 因?yàn)锳lice鎖定了UTXO本身,所以現(xiàn)在Bob或Alice在3個(gè)月的鎖定時(shí)間到期之前不可能花費(fèi)它朴乖。
通過將時(shí)間鎖定功能直接引入到腳本語言中祖屏,CLTV允許我們開發(fā)一些非常有趣的復(fù)雜腳本。
該標(biāo)準(zhǔn)在BIP-65(CHECKLOCKTIMEVERIFY)中定義(附錄部分)寒砖。
7.5.3相對時(shí)間鎖
nLocktime和CLTV都是絕對時(shí)間鎖定赐劣,它們指定絕對時(shí)間點(diǎn)。接下來的兩個(gè)時(shí)間鎖定功能哩都,我們將要考察的是相對時(shí)間鎖定魁兼,因?yàn)樗鼈儗⑾妮敵龅臈l件指定為從塊鏈接中的輸出確認(rèn)起的經(jīng)過時(shí)間。
相對時(shí)間鎖是有用的,因?yàn)樗鼈冊试S將兩個(gè)或多個(gè)相互依賴的交易鏈接在一起咐汞,同時(shí)對依賴于從先前交易的確認(rèn)所經(jīng)過的時(shí)間的一個(gè)交易施加時(shí)間約束盖呼。換句話說,在UTXO被記錄在塊狀塊之前化撕,時(shí)鐘不開始計(jì)數(shù)几晤。這個(gè)功能在雙向狀態(tài)通道和閃電網(wǎng)絡(luò)中特別有用,我們將在后面章節(jié)[state_channels]中看到植阴。
相對時(shí)間鎖蟹瘾,如絕對時(shí)間鎖定,同時(shí)具有交易級功能和腳本級操作碼掠手。交易級相對時(shí)間鎖定是作為對每個(gè)交易輸入中設(shè)置的交易字段nSequence的值的共識(shí)規(guī)則實(shí)現(xiàn)的憾朴。腳本級相對時(shí)間鎖定使用CHECKSEQUENCEVERIFY(CSV)操作碼實(shí)現(xiàn)。
相對時(shí)間鎖是根據(jù)BIP-68的規(guī)范實(shí)現(xiàn)的喷鸽,相對鎖定時(shí)間使用共同執(zhí)行的序列號和BIP-112众雷,CHECKSEQUENCEVERIFY。
/改為:相對時(shí)間鎖是根據(jù)BIP-68與BIP-112的規(guī)范共同實(shí)現(xiàn)的做祝,其中BIP-68通過與相對時(shí)間鎖運(yùn)用一致性增強(qiáng)的數(shù)字序列實(shí)現(xiàn)砾省,BIP-112中是運(yùn)用到了CHECKSEQUENCEVERIFY這個(gè)操作碼實(shí)現(xiàn)。
BIP-68和BIP-112在2016年5月被激活混槐,作為軟叉升級到共識(shí)規(guī)則编兄。
/改為 BIP-68和BIP-112是在2016年5月作為軟分叉升級時(shí)被激活的一個(gè)共識(shí)規(guī)則。
7.5.4 nSequence相對時(shí)間鎖
可以通過在每個(gè)輸入中設(shè)置nSequence字段來在交易的每個(gè)輸入上設(shè)置相對時(shí)間鎖定纵隔。
/上句改為: 相對時(shí)間鎖定可以在每個(gè)輸入中設(shè)置好翻诉,其方法是在每個(gè)輸入中加多一個(gè)nSequence字段。
7.5.4.1 nSequence的本義
nSequence字段最初是(但從未被正確實(shí)現(xiàn)的)允許在內(nèi)存池中修改交易捌刮。/上句改為:nSequence字段的設(shè)計(jì)初心是想讓交易能在在內(nèi)存中修改,可惜后面從未運(yùn)用過舒岸,使用時(shí)绅作,包含nSequence值低于2^32 (0xFFFFFFFF)的輸入的交易表示尚未“確定”的交易。
/原文:In that use, a transaction containing inputs with nSequence value below 232 (0xFFFFFFFF) indicated a transaction that was not yet "finalized."
/改為:使用nSequence這個(gè)字段時(shí)蛾派,如果輸入的交易的序列值小于2^32 (0xFFFFFFFF)俄认,就表示尚未“確定”的交易。
這樣的交易將在內(nèi)存池中保存洪乍,直到被另一個(gè)交易消耗相同輸入并具有較大nSequence值的代替眯杏。一旦收到一個(gè)交易,其投入的nSequence值為2^32壳澳,那么它將被視為“最終確定”并開采岂贩。
nSequence的原始含義從未被正確實(shí)現(xiàn),并且在不利用時(shí)間鎖定的交易中nSequence的值通常設(shè)置為232巷波。對于具有nLocktime或CHECKLOCKTIMEVERIFY的交易萎津,nSequence值必須設(shè)置為小于232卸伞,以使時(shí)間鎖定器有效。通常設(shè)置為2^32 - 1(0xFFFFFFFE)锉屈。
7.5.4.2 nSequence作為一個(gè)共同執(zhí)行的相對時(shí)間鎖定
由于BIP-68的激活荤傲,新的共識(shí)規(guī)則適用于任何包含nSequence值小于2^31的輸入的交易(bit 1<<31 is not set)。以編程方式颈渊,這意味著如果沒有設(shè)置最高有效(bit 1<<31)遂黍,它是一個(gè)表示“相對鎖定時(shí)間”的標(biāo)志。否則(bit 1<<31set)俊嗽,nSequence值被保留用于其他用途雾家,例如啟用CHECKLOCKTIMEVERIFY,nLocktime乌询,Opt-In-Replace-By-Fee以及其他未來的開發(fā) /新產(chǎn)品榜贴。
nSequence值小于2^31的交易輸入,就被解釋為具有相對時(shí)間鎖定妹田。
/原文Transaction inputs with nSequence values less than 2^31 are interpreted as having a relative timelock.
/改為 一筆輸入交易唬党,當(dāng)輸入腳本中的nSequence值小于2^31時(shí),就是相對時(shí)間鎖定的輸入交易鬼佣。就是這種交易只有在輸入已經(jīng)老化了相對時(shí)間鎖定量后才有效驶拱。/原文:Such a transaction is only valid once the input has aged by the relative timelock amount. 改為:這種交易只有到了相對鎖定時(shí)間后才生效。例如晶衷,具有30個(gè)區(qū)塊的nSequence相對時(shí)間鎖的一個(gè)輸入的交易只有在從輸入中引用的UTXO開始的時(shí)間起至少有30個(gè)塊時(shí)才有效蓝纲。由于nSequence是每個(gè)輸入字段,因此交易可能包含任何數(shù)量的時(shí)間鎖定輸入晌纫,所有這些都必須具有足夠的時(shí)間以使交易有效税迷。交易可以包括時(shí)間鎖定輸入(nSequence <2^31)和沒有相對時(shí)間鎖定(nSequence> = 2^31)的輸入。
nSequence值以塊或秒為單位指定锹漱,但與nLocktime中使用的格式略有不同箭养。類型標(biāo)志用于區(qū)分計(jì)數(shù)塊和計(jì)數(shù)時(shí)間(以秒為單位)的值。類型標(biāo)志設(shè)置在第23個(gè)最低有效位(即值1 << 22)哥牍。如果設(shè)置了類型標(biāo)志毕泌,則nSequence值將被解釋為512秒的倍數(shù)。如果未設(shè)置類型標(biāo)志嗅辣,則nSequence值被解釋為塊數(shù)撼泛。
當(dāng)將nSequence解釋為相對時(shí)間鎖定時(shí),只考慮16個(gè)最低有效位澡谭。一旦評估了標(biāo)志(位32和23)愿题,nSequence值通常用16位掩碼(例如nSequence&0x0000FFFF)“屏蔽”。
下圖顯示由BIP-68定義的nSequence值的二進(jìn)制布局。
[圖片上傳失敗...(image-bae7eb-1512023362597)]
Figure 1. BIP-68 definition of nSequence encoding (Source: BIP-68)
基于nSequence值的一致執(zhí)行的相對時(shí)間鎖定在BIP-68中抠忘。標(biāo)準(zhǔn)定義在BIP-68, Relative lock-time using consensus-enforced sequence numbers.
7.5.5 帶CSV的相對時(shí)間鎖
就像CLTV和nLocktime一樣撩炊,有一個(gè)腳本操作碼用于相對時(shí)間鎖定,它利用腳本中的nSequence值崎脉。該操作碼是CHECKSEQUENCEVERIFY拧咳,通常簡稱為CSV。
在UTXO的贖回腳本中評估時(shí)囚灼,CSV操作碼僅允許在輸入nSequence值大于或等于CSV參數(shù)的交易中進(jìn)行消耗骆膝。實(shí)質(zhì)上,這限制了UTXO的消耗灶体,直到UTXO開采時(shí)間過了一定數(shù)量的塊或秒阅签。
與CLTV一樣,CSV中的值必須與相應(yīng)nSequence值中的格式相匹配蝎抽。如果CSV是根據(jù)塊指定的政钟,那么nSequence也是如此。如果以秒為單位指定CSV樟结,那么nSequence也是如此养交。
當(dāng)幾個(gè)(已經(jīng)形成鏈)交易被保留為“脫鏈”時(shí),創(chuàng)建和簽名這幾個(gè)(已經(jīng)形成鏈)交易但不傳播時(shí)瓢宦,CSV的相對時(shí)間鎖特別有用碎连。在父交易已被傳播,/挖掘和老化到指定的相對時(shí)間鎖定的時(shí)間之前驮履,才能使用子交易鱼辙。/改為:直到消耗完相對鎖定時(shí)間,才能使用子交易玫镐。這個(gè)用例的一個(gè)應(yīng)用可以在state_channels和lightning_network /請加上鏈接 章節(jié)中看到倒戏。
CSV 細(xì)節(jié)參見 BIP-112, CHECKSEQUENCEVERIFY.
7.5.6中位時(shí)間過去Median-Time-Past
作為激活相對時(shí)間鎖定的一部分,時(shí)間鎖定(絕對和相對)的“時(shí)間”方式也發(fā)生了變化恐似。在比特幣中峭梳,墻上時(shí)間(wall time)和共識(shí)時(shí)間之間存在微妙但非常顯著的差異。比特幣是一個(gè)分散的網(wǎng)絡(luò)蹂喻,這意味著每個(gè)參與者都有自己的時(shí)間觀。網(wǎng)絡(luò)上的事件不會(huì)隨時(shí)隨地發(fā)生捂寿。網(wǎng)絡(luò)延遲必須考慮到每個(gè)節(jié)點(diǎn)的角度口四。最終,所有內(nèi)容都被同步秦陋,以創(chuàng)建一個(gè)共同的分類帳蔓彩。比特幣在過去存在的分類賬狀態(tài)中每10分鐘達(dá)成一個(gè)新的共識(shí)。
區(qū)塊頭中設(shè)置的時(shí)間戳由礦工設(shè)定。共識(shí)規(guī)則允許一定的緯度 /改為誤差 來解決分散節(jié)點(diǎn)之間時(shí)鐘精度的差異 /問題赤嚼。然而旷赖,這給礦工造成了一個(gè)不幸的誘惑,即礦工在一段時(shí)間內(nèi)就這么說謊更卒,/然而等孵,這誘惑了礦工去說謊,這以便通過包括還不成熟 /不在范圍內(nèi)的時(shí)間交易來賺取額外費(fèi)用 /礦工費(fèi)蹂空。有關(guān)詳細(xì)信息俯萌,請參閱以下部分。
為了消除謊言和加強(qiáng)時(shí)間安全性的動(dòng)機(jī) /為了杜絕礦工說謊上枕,加強(qiáng)時(shí)間安全性咐熙,在相對時(shí)間的BIPs的同時(shí)提出并激活了1個(gè)新的BIP /在相對時(shí)間鎖的基礎(chǔ)上又新增了一個(gè)BIP。這是BIP-113辨萍,它定義了一個(gè)稱為“中位時(shí)間過去 /(Median-Time-Past)”的新的共識(shí)測量機(jī)制棋恼。
通過取最后11個(gè)塊的時(shí)間戳并找到中位數(shù)來計(jì)算“中位時(shí)間過去”的值。/通過取最后11個(gè)塊的時(shí)間戳并計(jì)算其中位數(shù)作為“中位時(shí)間過去”的值锈玉。那個(gè) /這個(gè) 中間時(shí)間 /值就變成了共識(shí)時(shí)間爪飘,并被用于所有的時(shí)間計(jì)算。過去約兩個(gè)小時(shí)的中間點(diǎn)嘲玫,任何一個(gè)塊的時(shí)間戳的影響減小了悦施。通過合并11個(gè)塊 /通過這個(gè)方法,沒有一個(gè)礦工可以利用時(shí)間戳從具有尚未成熟的時(shí)間段的交易中獲取非法礦工費(fèi)去团。
Median-Time-Past更改了nLocktime抡诞,CLTV,nSequence和CSV的時(shí)間計(jì)算的實(shí)現(xiàn)土陪。由Median-Time-Past計(jì)算的共識(shí)時(shí)間總是大約在掛鐘時(shí)間后一個(gè)小時(shí)昼汗。如果創(chuàng)建時(shí)間鎖交易,那么要在nLocktime鬼雀,nSequence顷窒,CLTV和CSV中進(jìn)行編碼的估計(jì)所需值時(shí),應(yīng)該考慮它源哩。
Median-Time-Past細(xì)節(jié)參見BIP-113.
7.5.7針對費(fèi)用狙擊(Fee Sniping)的時(shí)間鎖定
費(fèi)用狙擊是一種理論攻擊情形鞋吉,礦工試圖從將來的塊(挑選手續(xù)費(fèi)較高的交易)重寫過去的塊,實(shí)現(xiàn)“狙擊”更高費(fèi)用的交易励烦,以最大限度地提高盈利能力谓着。
例如,假設(shè)存在的最高塊是塊#100,000坛掠。如果不是試圖把#100,001號的礦區(qū)擴(kuò)大到區(qū)塊鏈赊锚,那么一些礦工們會(huì)試圖重新挖礦#100,000治筒。這些礦工可以選擇在候選塊#100,000中包括任何有效的交易(尚未開采)。他們不必使用相同的交易來恢復(fù)塊舷蒲。事實(shí)上耸袜,他們有動(dòng)力選擇最有利可圖(最高每kBB)的交易來包含在其中。它們可以包括處于“舊”塊#100,000中的任何交易牲平,以及來自當(dāng)前內(nèi)存池的任何交易堤框。當(dāng)他們重新創(chuàng)建塊#100,000時(shí),他們本質(zhì)上可以將交易從“現(xiàn)在”提取到重寫的“過去”中欠拾。
今天胰锌,這種襲擊并不是非常有利可圖,因?yàn)榛貓?bào)獎(jiǎng)勵(lì)(因?yàn)榘ㄒ欢〝?shù)量的比特幣獎(jiǎng)勵(lì))遠(yuǎn)遠(yuǎn)高于每個(gè)區(qū)塊的總費(fèi)用藐窄。但在未來的某個(gè)時(shí)候资昧,交易費(fèi)將是獎(jiǎng)勵(lì)的大部分(甚至是獎(jiǎng)勵(lì)的整體)。那時(shí)候這種情況變得不可避免了荆忍。
為了防止“費(fèi)用狙擊”格带,當(dāng)Bitcoin Core /錢包 創(chuàng)建交易時(shí),默認(rèn)情況下刹枉,它使用nLocktime將它們限制為“下一個(gè)塊”叽唱。在我們的環(huán)境中,Bitcoin Core /錢包將在任何創(chuàng)建的交易上將nLocktime設(shè)置為100,001微宝。在正常情況下棺亭,這個(gè)nLocktime沒有任何效果 - 交易只能包含在#100,001塊中,這是下一個(gè)區(qū)塊蟋软。
但是在區(qū)塊鏈分叉攻擊的情況下镶摘,由于所有這些交易都將被時(shí)間鎖阻止在#100,001,所以礦工們無法從籌碼中提取高額交易岳守。他們只能在當(dāng)時(shí)有效的任何交易中重新挖礦#100,000凄敢,這導(dǎo)致實(shí)質(zhì)上不會(huì)獲得新的費(fèi)用。
為了實(shí)現(xiàn)這一點(diǎn)湿痢,Bitcoin Core/錢包將所有新交易的nLocktime設(shè)置為<current block #+ 1>涝缝,并將所有輸入上的nSequence設(shè)置為0xFFFFFFFE以啟用nLocktime。
7.6具有流量控制的腳本(條件條款 (Conditional Clauses))
比特幣腳本的一個(gè)更強(qiáng)大的功能是流量控制譬重,也稱為條件條款拒逮。您可能熟悉使用構(gòu)造IF ... THEN ... ELSE的各種編程語言中的流控制。比特幣條件條款看起來有點(diǎn)不同臀规,但是基本上是相同的結(jié)構(gòu)消恍。
在基本層面上,比特幣條件操作碼允許我們構(gòu)建一個(gè)具有兩種解鎖方式的贖回腳本以现,這取決于評估邏輯條件的TRUE / FALSE結(jié)果狠怨。例如,如果x為TRUE邑遏,則贖回腳本為A佣赖,ELSE贖回腳本為B.
此外,比特幣條件表達(dá)式可以無限期地“嵌套”记盒,這意味著這個(gè)條件語句可以包含其中的另外一個(gè)條件憎蛤,另外一個(gè)條件其中包含別的條件等等 。Bitcoin腳本流控制可用于構(gòu)造非常復(fù)雜的腳本纪吮,具有數(shù)百甚至數(shù)千個(gè)可能的執(zhí)行路徑俩檬。嵌套沒有限制,但協(xié)商一致的規(guī)則對腳本的最大大心朊恕(以字節(jié)為單位)施加限制棚辽。
比特幣使用IF,ELSE冰肴,ENDIF和NOTIF操作碼實(shí)現(xiàn)流量控制屈藐。此外,條件表達(dá)式可以包含布爾運(yùn)算符熙尉,如BOOLAND联逻,BOOLOR和NOT。
乍看之下检痰,您可能會(huì)發(fā)現(xiàn)比特幣的流量控制腳本令人困惑包归。那是因?yàn)楸忍貛拍_本是一種堆棧語言。同樣的方式铅歼,當(dāng)1+1看起來“向后”當(dāng)表示為1 1 ADD時(shí)公壤,比特幣中的流控制條款也看起來“向后”(backward)。
在大多數(shù)傳統(tǒng)(程序)編程語言中谭贪,流控制如下所示:
大多數(shù)編程語言中的流控制偽代碼
if (condition):
code to run when condition is true
else:
code to run when condition is false
code to run in either case
在基于堆棧的語言中境钟,比如比特幣腳本,邏輯條件出現(xiàn)在IF之前俭识,這使得它看起來像“向后”慨削,如下所示:
Bitcoin腳本流控制
condition
IF
code to run when condition is true
ELSE
code to run when condition is false
ENDIF
code to run in either case
閱讀Bitcoin腳本時(shí),請記住套媚,評估的條件是在IF操作碼之前缚态。
7.6.1條件條款與VERIFY操作碼
Bitcoin Script /比特幣腳本中的另一種條件是任何以VERIFY結(jié)尾的操作碼。 VERIFY后綴表示如果評估的條件不為TRUE堤瘤,腳本的執(zhí)行將立即終止玫芦,并且該交易被視為無效。
與提供替代執(zhí)行路徑的IF子句不同本辐,VERIFY后綴充當(dāng)保護(hù)子句桥帆,只有在滿足前提條件的情況下才會(huì)繼續(xù)医增。
例如,以下腳本需要Bob的簽名和產(chǎn)生特定哈希的前置映像(秘密地) /? 老虫。 解鎖時(shí)必須滿足這兩個(gè)條件:
1)具有EQUALVERIFY保護(hù)條款的贖回腳本叶骨。
HASH160 <expected hash> EQUALVERIFY <Bob's Pubkey> CHECKSIG
為了兌現(xiàn)這一點(diǎn),Bob必須構(gòu)建一個(gè)解鎖腳本祈匙,提供有效的前圖像和簽名:
2)一個(gè)解鎖腳本以滿足上述贖回腳本瓜贾。
<Bob's Sig> <hash pre-image>
沒有呈現(xiàn)前圖像 /?驾荣,Bob無法訪問檢查其簽名的腳本部分景埃。
該腳本可以用IF編寫:
具有IF保護(hù)條款的兌換腳本
HASH160 <expected hash> EQUAL
IF
<Bob's Pubkey> CHECKSIG
ENDIF
Bob的解鎖腳本是一樣的:
解鎖腳本以滿足上述兌換腳本
<Bob's Sig> <hash pre-image>
使用IF的腳本與使用具有VERIFY后綴的操作碼相同; 他們都作為保護(hù)條款描函。 然而,VERIFY的構(gòu)造更有效率些阅,使用較少的操作碼伞剑。
那么,我們什么時(shí)候使用VERIFY扑眉,什么時(shí)候使用IF纸泄? 如果我們想要做的是附加一個(gè)前提條件(保護(hù)條款),那么驗(yàn)證是更好的腰素。 然而聘裁,如果我們想要有多個(gè)執(zhí)行路徑(流控制),那么我們需要一個(gè)IF ... ELSE流控制子句弓千。
提示 | 諸如EQUAL之類的操作碼會(huì)將結(jié)果(TRUE / FALSE)推送到堆棧上衡便,留下它用于后續(xù)操作碼的評估。 相比之下洋访,操作碼EQUALVERIFY后綴不會(huì)在堆棧上留下任何東西镣陕。 在VERIFY中結(jié)束的操作碼不會(huì)將結(jié)果留在堆棧上。 |
---|
7.6.2在腳本中使用流控制
比特幣腳本中流量控制的一個(gè)非常常見的用途是構(gòu)建一個(gè)提供多個(gè)執(zhí)行路徑的贖回腳本姻政,每個(gè)腳本都有一種不同的贖回UTXO的方式呆抑。
我們來看一個(gè)簡單的例子,我們有兩個(gè)簽名人汁展,Alice和Bob鹊碍,還有一個(gè)可以兌換。 使用多重簽名食绿,這將被表示為1-of-2 多重簽名腳本侈咕。 為了示范,我們將使用IF子句做同樣的事情:
IF
<Alice's Pubkey> CHECKSIG
ELSE
<Bob's Pubkey> CHECKSIG
ENDIF
看這個(gè)贖回腳本器紧,你可能會(huì)想:“條件在哪里耀销?”IF子句之前沒有什么!“
條件不是贖回腳本的一部分铲汪。 相反熊尉,該解鎖腳本將提供該條件罐柳,允許Alice和Bob“選擇”他們想要的執(zhí)行路徑。
Alice用解鎖腳本兌換了這個(gè):
<Alice's Sig> 1
最后的1作為條件(TRUE)帽揪,將使IF子句執(zhí)行Alice具有簽名的第一個(gè)兌換路徑硝清。
為了兌換這個(gè)Bob,他必須通過給IF子句賦一個(gè)FALSE值來選擇第二個(gè)執(zhí)行路徑:
<Bob's Sig> 0
Bob的解鎖腳本在堆棧中放置一個(gè)0转晰,導(dǎo)致IF子句執(zhí)行第二個(gè)(ELSE)腳本,這需要Bob的簽名士飒。
由于可以嵌套IF子句查邢,所以我們可以創(chuàng)建一個(gè)“迷宮”的執(zhí)行路徑。 解鎖腳本可以提供一個(gè)選擇執(zhí)行路徑實(shí)際執(zhí)行的“地圖”:
IF
script A
ELSE
IF
script B
ELSE
script C
ENDIF
ENDIF
在這種情況下酵幕,有三個(gè)執(zhí)行路徑(腳本A扰藕,腳本B和腳本C)。 解鎖腳本以TRUE或FALSE值的形式提供路徑芳撒。 要選擇路徑腳本B邓深,例如,解鎖腳本必須以1 0(TRUE笔刹,F(xiàn)ALSE)結(jié)束芥备。 這些值將被推送到堆棧,以便第二個(gè)值(FALSE)結(jié)束于堆棧的頂部舌菜。 外部IF子句彈出FALSE值并執(zhí)行第一個(gè)ELSE子句萌壳。 然后,TRUE值移動(dòng)到堆棧的頂部日月,并通過內(nèi)部(嵌套)IF來評估袱瓮,選擇B執(zhí)行路徑。
使用這個(gè)結(jié)構(gòu)爱咬,我們可以用數(shù)十或數(shù)百個(gè)執(zhí)行路徑構(gòu)建贖回腳本尺借,每個(gè)腳本提供了一種不同的方式來兌換UTXO。 要花費(fèi)精拟,我們構(gòu)建一個(gè)解鎖腳本燎斩,通過在每個(gè)流量控制點(diǎn)的堆棧上放置相應(yīng)的TRUE和FALSE值來導(dǎo)航執(zhí)行路徑。
7.7復(fù)雜的腳本示例
在本節(jié)中串前,我們將本章中的許多概念合并成一個(gè)例子瘫里。
我們的例子使用了迪拜公司所有者穆罕默德(Mohammed)的故事,他們正在經(jīng)營進(jìn)出口業(yè)務(wù)荡碾。
在這個(gè)例子中谨读,穆罕默德希望用靈活的規(guī)則建立公司資本賬戶。他創(chuàng)建的方案需要不同級別的授權(quán)坛吁,具體取決于時(shí)間鎖定劳殖。 Multisig計(jì)劃的參與者是穆罕默德铐尚,他的兩個(gè)合作伙伴賽義德和扎拉,以及他們的公司律師阿卜杜勒哆姻。三個(gè)合作伙伴根據(jù)多數(shù)規(guī)則作出決定宣增,因此三者中的兩個(gè)必須同意。然而矛缨,如果他們的鑰匙有問題爹脾,他們希望他們的律師能夠用三個(gè)合作伙伴簽名之一收回資金。最后箕昭,如果所有的合作伙伴一段時(shí)間都不可用或無行為能力灵妨,他們希望律師能夠直接管理該帳戶。
這是Mohammed設(shè)計(jì)的腳本:
具有時(shí)間鎖定(Timelock)的變量多重簽名
IF
IF
2
ELSE
<30 days> CHECKSEQUENCEVERIFY DROP
<Abdul the Lawyer's Pubkey> CHECKSIGVERIFY
1
ENDIF
<Mohammed's Pubkey> <Saeed's Pubkey> <Zaira's Pubkey> 3 CHECKMULTISIG
ELSE
<90 days> CHECKSEQUENCEVERIFY DROP
<Abdul the Lawyer's Pubkey> CHECKSIG
ENDIF
Mohammed的腳本使用嵌套的IF ... ELSE流控制子句來實(shí)現(xiàn)三個(gè)執(zhí)行路徑落竹。
在第一個(gè)執(zhí)行路徑中泌霍,該腳本作為三個(gè)合作伙伴的簡單的2-of-3 multisig操作。 該執(zhí)行路徑由第3行和第9行組成述召。第3行將multisig的定額設(shè)置為2(2 - 3)朱转。 該執(zhí)行路徑可以通過在解鎖腳本的末尾設(shè)置TRUE TRUE來選擇:
解鎖第一個(gè)執(zhí)行路徑的腳本(2-of-3 multisig)
0 <Mohammed's Sig> <Zaira's Sig> TRUE TRUE
提示 | 此解鎖腳本開頭的0是因?yàn)镃HECKMULTISIG中的錯(cuò)誤從堆棧中彈出一個(gè)額外的值。 額外的值被CHECKMULTISIG忽略积暖,但它必須存在或腳本失敗 /否則腳本簽名將失敗藤为。 推送0(通常)是錯(cuò)誤的解決方法 / 推送0(通常)是解決bug的方法,如CHECKMULTISIG執(zhí)行中的錯(cuò)誤章節(jié)所述呀酸。 |
---|
第二個(gè)執(zhí)行路徑只能在UTXO創(chuàng)建30天后才能使用凉蜂。 那時(shí)候,它需要簽署阿卜杜勒(Abdul)的律師和三個(gè)合作伙伴之一(三分之一)性誉。 這是通過第7行實(shí)現(xiàn)的窿吩,該行將多選的法定人數(shù)設(shè)置為1。要選擇此執(zhí)行路徑错览,解鎖腳本將以FALSE TRUE結(jié)束:
解鎖第二個(gè)執(zhí)行路徑的腳本(Lawyer + 1-of-3)
0 <Saeed's Sig> <Abdul's Sig> FALSE TRUE
提示 | 為什么先FALSE后TRUE纫雁? 反了嗎?這是因?yàn)檫@兩個(gè)值被推到堆棧倾哺,所以先push FALSE轧邪,然后push TRUE。 因此羞海,第一個(gè)IF操作碼首先彈出的是TRUE忌愚。 |
---|
最后,第三個(gè)執(zhí)行路徑允許阿卜杜勒律師單獨(dú)花費(fèi)資金却邓,但只能在90天之后硕糊。 要選擇此執(zhí)行路徑,解鎖腳本必須以FALSE結(jié)束:
解鎖第三個(gè)執(zhí)行路徑的腳本(僅適用于律師)
<Abdul's Sig> FALSE
在紙上運(yùn)行腳本來查看它在堆棧(stack)上的行為。
閱讀這個(gè)例子還需要考慮幾件事情简十。 看看你能找到答案嗎檬某?
- 為什么律師可以隨時(shí)通過在解鎖腳本中選擇FALSE來兌換第三個(gè)執(zhí)行路徑?
- 在UTXO開采后分別有多少個(gè)執(zhí)行路徑可以使用5,35與105天螟蝙?
- 如果律師失去鑰匙,資金是否流失胰默? 如果91天過去了,你的答案是否會(huì)改變和簸?
- 合作伙伴如何每隔29天或89天“重置”一次,以防止律師獲得資金薯酝?
- 為什么這個(gè)腳本中的一些CHECKSIG操作碼有VERIFY后綴吴菠,而其他的沒有做葵?