第5章 交易

5.2.3 比特幣交易在比特幣網絡中的傳播

一旦一筆比特幣交易被發送到任意一個連接至比特幣網絡的節點,這筆交易將會被該節點驗證。如果交易被驗證有效,該節點將會將這筆交易傳播到這個節點所連接的其他節點;同時,交易發起者會收到一條表示交易有效并被接受的返回信息。如果這筆交易被驗證為無效,這個節點會拒絕接受這筆交易且同時返回給交易發起者一條表示交易被拒絕的信息。

比特幣網絡是一個點對點網絡,這意味著每一個比特幣節點都連接到一些其他的比特幣節點(這些其他的節點是在啟動點對點協議時被發現的)。整個比特幣網絡形成了一個松散地連接、且沒有固定拓撲或任何結構的“蛛網”——這使得所有節點的地位都是同等的。比特幣交易相關信息(包括交易和區塊)被傳播——從每一個節點到它連接的其他節點。一筆剛通過驗證且并被傳遞到比特幣網絡中任意節點的交易會被發送到三到四個相鄰節點,而每一個相鄰節點又會將交易發送到三至四個與它們相鄰的節點。以此類推,在幾秒鐘之內,一筆有效的交易就會像指數級擴散的波一樣在網絡中傳播,直到所有連接到網絡的節點都接收到它。

比特幣網絡被設計為能高效且靈活地傳遞交易和區塊至所有節點的模式,因而比特幣網絡能抵御入侵。為了避免垃圾信息的濫發、拒絕服務攻擊或其他針對比特幣系統的惡意攻擊,每一個節點在傳播每一筆交易之前均進行獨立驗證。 一個異常交易所能到達的節點不會超過一個。

5.3 交易結構

交易的鎖定時間

鎖定時間定義了能被加到區塊鏈里的最早的交易時間。在大多數交易里,它被設置成0,用來表示立即執行。如果鎖定時間不是0并且小于5億,就被視為區塊高度,意指在這個指定的區塊高度之前,該交易沒有被包含在區塊鏈里。如果鎖定時間大于5億,則它被當作是一個Unix紀元時間戳(從1970年1月1日以來的秒數),并且在這個指定時點之前,該交易沒有被包含在區塊鏈里。鎖定時間的使用相當于將一張紙質支票的生效時間予以后延。

5.4 交易的輸出和輸入

比特幣交易的基本單位是未經使用的一個交易輸出,簡稱UTXO。UTXO是不能再分割、被所有者鎖住或記錄于區塊鏈中的并被整個網絡識別成貨幣單位的一定量的比特幣貨幣。比特幣網絡監測著以百萬為單位的所有可用的(未花費的)UTXO。當一個用戶接收比特幣時,金額被當作UTXO記錄到區塊鏈里。這樣,一個用戶的比特幣會被當作UTXO分散到數百個交易和數百個區塊中。實際上,并不存在儲存比特幣地址或賬戶余額的地點,只有被所有者鎖住的、分散的UTXO。“一個用戶的比特幣余額”,這個概念是一個通過比特幣錢包應用創建的派生之物。比特幣錢包通過掃描區塊鏈并聚合所有屬于該用戶的UTXO來計算該用戶的余額。

在比特幣的世界里既沒有賬戶,也沒有余額,只有分散到區塊鏈里的UTXO。

盡管UTXO可以是任意值,但只要它被創造出來了,就像不能被切成兩半的硬幣一樣不可再分了。如果一個UTXO比一筆交易所需量大,它仍會被當作一個整體而消耗掉,但同時會在交易中生成零頭。例如,你有20比特幣的UTXO并且想支付1比特幣,那么你的交易必須消耗掉整個20比特幣的UTXO并且產生兩個輸出:一個是支付了1比特幣給接收人,另一個是支付19比特幣的找零到你的錢包。這樣的話,大部分比特幣交易都會產生找零。

被交易消耗的UTXO被稱為交易輸入,由交易創建的UTXO被稱為交易輸出。通過這種方式,一定量的比特幣價值在不同所有者之間轉移,并在交易鏈中消耗和創建UTXO。一筆比特幣交易通過使用所有者的簽名來解鎖UTXO,并通過使用新的所有者的比特幣地址來鎖定并創建UTXO。

對于輸出和輸入鏈來說,有一個例外,它是一種特殊的交易類型,稱為Coinbase交易。這是每個區塊中的首個交易。這種交易存在的原因是作為對挖礦的獎勵而產生全新的可用于支付的比特幣給“贏家”礦工。這也就是為什么比特幣可以在挖礦過程中被創造出來。

5.4.1 交易輸出

UTXO被每一個全節點比特幣客戶端在一個儲存于內存中的數據庫所追蹤,該數據庫也被稱為“UTXO集”或者“UTXO池”。新的交易從UTXO集中消耗(支付)一個或多個輸出。

交易輸出包含兩部分:

? 一定量的比特幣,被命名為“聰”,是最小的比特幣單位;

?一個鎖定腳本,也被當作是“障礙”,提出支付輸出所必須被滿足的條件以“鎖住”這筆總額。

交易輸出把用聰表示的一定數量的比特幣,和特定的定義了支付輸出所必須被滿足的條件的障礙,或者叫鎖定腳本,關聯到了一起。在大多數情況下,鎖定腳本會把輸出鎖在一個特定的比特幣地址上,從而把一定數量的比特幣的所有權轉移到新的所有者上。當Alice在Bob的咖啡店為一杯咖啡付款時,Alice的交易創造了0.015比特幣的輸出,在咖啡店的比特幣地址上成為一種障礙,或者說是被鎖在了咖啡店的比特幣地址上。那0.015比特幣輸出被記錄到區塊鏈中,并且成為UTXO的一部分,也就是作為可用余額出現在Bob的錢包里。當Bob選擇使用這筆款項進行支付時,他的交易會釋放障礙,通過提供一個包含Bob私鑰的解鎖腳本來解鎖輸出。

5.4.2 交易輸入

簡單地說,交易輸入是指向UTXO的指針。它們指向特定的UTXO,并被交易哈希和在區塊鏈中記錄UTXO的序列號作為參考。若想支付UTXO,一個交易的輸入也需要包含一個解鎖腳本,用來滿足UTXO的支付條件。解鎖腳本通常是一個簽名,用來證明對于在鎖定腳本中的比特幣地址擁有所有權。

5.4.3 交易費

交易費可當作是為了包含(挖礦)一筆交易到下一個區塊中的一種鼓勵,也可當作是對于欺詐交易和任何種類的系統濫用,在每一筆交易上通過征收一筆小成本的稅而造成的一種妨礙。交易費被挖出這個區塊的礦工得到,并且記錄在這個交易的區塊鏈中。

交易費基于交易的尺寸,用千字節來計算,而不是比特幣的價值。總的來說,交易費基于市場所設置,生效于比特幣網絡中。礦工依據許多不同的標準,按重要性對交易進行排序,這包括費用,并且甚至可能在某種特定情況下免費處理交易。交易費影響處理優先級,這意味著有足夠費用的交易會更可能地被包含在下一個挖出的區塊中;與此同時,交易費不足或者沒有交易費的交易可能會被推遲,基于盡力而為的原則在幾個區塊之后被處理,甚至可能根本不被處理。交易費不是強制的,而且沒有交易費的交易也許最終會被處理,但是,包含交易費將提高處理優先級。

5.4.4 把交易費加到交易中

交易的數據結構沒有交易費的字段。相反地,交易費通過所有輸入的總和,以及所有輸出的總和之間的差來表示。從所????有輸入中扣掉所有輸出之后的多余的量會被礦工收集走。

交易費被作為輸入減輸出的余量:

交易費 = 求和(所有輸入) - 求和(所有輸出)?????

如果你要構造你自己的交易,你必須確認你沒有疏忽地包含了一筆少于輸入的、量非常大的費用。這意味著你必須計算所有的輸入,如果必要的話進行找零,不然的話,結果就是你給了礦工一筆可觀的勞動費!

舉例來說,如果你消耗了一個20比特幣的UTXO來完成1比特幣的付款,你必須包含一筆19比特幣的找零回到你的錢包。否則,那剩下的19比特幣會被當作交易費,并且會被挖出你的交易到一個區塊中的礦工收走。盡管你會受到高優先級的處理,并且讓一個礦工喜出望外,但這很可能不是你想要的。如果你忘記了在手動構造的交易中增加找零的輸出,系統會把找零當作交易費來處理。“不用找了!”也許不是你想要的結果。

Eugenia的錢包應用想要構造一個單筆大額付款交易,它必須從可用的、由很多小數額構成的大的UTXO集合中尋求錢幣來源。這意味著交易的結果是從上百個小數額的UTXO中作為輸入,但只有一個輸出用來付給出版商。輸入數量這么巨大的交易會比一千字節要大,也許總尺寸會達到兩至三千字節。結果是它需要更高的交易費來滿足0.0001比特幣的網絡費。

Eugenia的錢包應用會通過測量交易的大小,乘以每千字節需要的交易費,來計算適當的交易費。很多錢包會通過多付交易費的方式來確保大交易被立即處理。高交易費不是因為Eugenia付的錢很多,而是因為她的交易很復雜并且尺寸很大——交易費是與參加交易的比特幣值無關的。

5.5 交易鏈條和孤立交易

有的時候組成整個鏈條的所有交易依賴于他們自己——比如父交易、子交易和孫交易——而他們又被同時創造出來,來滿足復雜交易的工作流程。這需要在一個交易的父交易被簽名之前,有一個合法的子交易被簽名。舉個例子,這是CoinJoin交易使用的一項技術,這項技術可以讓多方同時加入交易,從而保護他們隱私。當一條交易鏈被整個網絡傳送時,他們并不能總是按照相同的順序到達目的地。有時,子交易在父交易之前到達。在這種情況下,節點會首先收到一個子交易,而不能找到他參考的父交易。節點不會立即拋棄這個子交易,而是放到一個臨時池中,并等著接收它的父交易,與此同時廣播這個子交易給其他節點。沒有父交易的交易池被稱作孤立交易池。一旦接收到了父交易,所有與這個父交易創建的UTXO有關的孤塊會從池中釋放出來,遞歸地重新驗證,然后整條交易鏈就會被交易池包括進去,并等待著被區塊所挖走。交易鏈可以是任意長度并且可以被任意數量的批次同時傳走。在孤立池中保留孤塊的機制保證了其他合法的交易不會只是因為父交易被耽誤了而被拋棄,并且無論接收順序,最終整個鏈會以正確的順序重新構造出來。

內存中儲存的孤立交易數量是有限制的,這是為了防止針對比特幣節點的拒絕服務攻擊(DoS)。這個限制被定義在比特幣涉及到的客戶端的源代碼中的 MAX_ORPHAN_TRANSACTIONS 。如果池中的孤立交易數量達到了 MAX_ORPHAN_TRANSACTIONS ,一個或多個的、被隨機選出的孤立交易會被池拋棄,直到池的大小回到限制以內。

5.6 比特幣交易腳本和腳本語言

比特幣客戶端通過執行一個用類Forth腳本語言編寫的腳本驗證比特幣交易。鎖定腳本被寫入UTXO,同時它往往包含一個用同種腳本語言編寫的簽名。當一筆比特幣交易被驗證時,每一個輸入值中的解鎖腳本被與其對應的鎖定腳本同時(互不干擾地)執行,從而查看這筆交易是否滿足使用條件。

如今,大多數經比特幣網絡處理的交易是以“Alice付給Bob”的形式存在的。同時,它們是以一種稱為“P2PKH”(Pay-to-Public-Key-Hash)腳本為基礎的。然而,通過使用腳本來鎖定輸出和解鎖輸入意味著通過使用編程語言,比特幣交易可以包含無限數量的條件。當然,比特幣交易并不限于“Alice付給Bob” 的形式和模式。比特幣交易驗證并不基于一個不變的模式,而是通過運行腳本語言來實現。這種語言可以表達出多到數不盡的條件變種。這也是比特幣作為一種“可編程的貨幣”所擁有的權力。

5.6.1 腳本創建(鎖定與解鎖)

比特幣的交易驗證引擎依賴于兩類腳本來驗證比特幣交易:一個鎖定腳本和一個解鎖腳本。

鎖定腳本是一個放在一個輸出值上的“障礙”,同時它明確了今后花費這筆輸出的條件。由于鎖定腳本往往含有一個公鑰(即比特幣地址),在歷史上它曾被稱作一個腳本公鑰代碼。由于認識到這種腳本技術存在著更為寬泛的可能性,在本書中,我們將它稱為一個“鎖定腳本”。在大多數比特幣應用源代碼中,腳本公鑰代碼便是我們所說的鎖定腳本。解鎖腳本是一個“解決”或滿足被鎖定腳本在一個輸出上設定的花費條件的腳本,同時它將允許輸出被消費。解鎖腳本是每一筆比特幣交易輸出的一部分,而且往往含有一個被用戶的比特幣錢包(通過用戶的私鑰)生成的數字簽名。由于解鎖腳本常常包含一個數字簽名,因此它曾被稱作ScriptSig。在大多數比特幣應用的源代碼中,ScriptSig便是我們所說的解鎖腳本。考慮到更寬泛的鎖定腳本要求,在本書中,我們將它稱為“解鎖腳本”。但并非所有解鎖腳本都一定會包含簽名。

每一個比特幣客戶端會通過同時執行鎖定和解鎖腳本來驗證一筆交易。對于比特幣交易中的每一個輸入,驗證軟件會先檢索輸入所指向的UTXO。這個UTXO包含一個定義了花費條件的鎖定腳本。接下來,驗證軟件會讀取試圖花費這個UTXO的輸入中所包含的解鎖腳本,并執行這兩個腳本。

首先,使用堆棧執行引擎執行解鎖腳本。如果解鎖腳本在執行過程中未報錯(沒有懸空操作符),主堆棧(非其它堆棧)將被復制,然后腳本將被執行。如果采用從解鎖腳本處復制而來的數據執行鎖定腳本的結果為真,那么解鎖腳本就成功地滿足了鎖定腳本所設置的條件,因而,該輸入是一個能使用該UTXO的有效授權。如果在執行完組合腳本后的結果不是真,那么輸入就不是有效的,因為它并未能滿足UTXO中所設置的使用該筆資金的條件。注意,UTXO是永久性地記錄在區塊鏈中的,因此它不會因一筆新交易所發起的無效嘗試而變化或受影響。只有一筆有效的能準確滿足UTXO條件的交易才會導致UTXO被標記為“已使用”,然后從有效的(未使用)UTXO集中所移除。

圖5-1是最為常見類型的比特幣交易(向公鑰哈希進行一筆支付)的解鎖和鎖定腳本樣本,該樣本展示了在腳本驗證之前將解鎖腳本和鎖定腳本串聯而成的組合腳本。

5.6.2 腳本語言

比特幣腳本語言被稱為基于棧語言,因為它使用的數據結構被稱為棧。棧是一個非常簡單的數據結構,它可以被理解成為一堆卡片。棧允許兩類操作:入棧和出棧。入棧是在棧頂部增加一個項目,出棧則是從棧頂部移除一個項目。

腳本語言通過從左至右地處理每個項目的方式執行腳本。數字(常數)被推送至堆棧,操作符向堆棧推送(或移除)一個或多個參數,對它們進行處理,甚至可能會向堆棧推送一個結果。例如,OP_ADD將從堆棧移除兩個項目,將二者相加,然后再將二者相加之和推送到堆棧。

條件操作符評估一項條件,產生一個真或假的結果。例如,OP_EQUAL從堆棧移除兩個項目,假如二者相等則推送真(表示為1),假如二者不等則推送為假(表示為0)。比特幣交易腳本常含條件操作符,當一筆交易有效時,就會產生真的結果。

使用部分算數運算示例腳本作用鎖定腳本:3 OP_ADD 5 OP_EQUAL

該腳本能被以解鎖腳本為輸入的一筆交易所滿足,解鎖腳本為:2

驗證軟件將鎖定和解鎖腳本組合起來:2 3 OP_ADD 5 OP_EQUAL

正如在圖5-2中所看到的,當腳本被執行時,結果是OP_TRUE,從而使得交易有效。不僅該筆交易的輸出鎖定腳本有效,同時UTXO也能被任何知曉這個運算技巧(知道是數字2)的人所使用

如果堆棧頂部的結果顯示為真(標記為{0×01}),即為任何非零值或腳本執行后堆棧為空情形,則交易有效。如果堆棧頂部的結果顯示為假(0字節空值,標記為{})或腳本執行被操作符禁止,如OP_VERIFY、OP_RETURN,或有條件終止如OP_ENDIF,則交易無效。

5.6.3 圖靈非完備性

比特幣腳本語言包含許多操作,但都故意限定為一種重要的方式——沒有循環或者復雜流控制功能以外的其他條件的流控制。這樣就保證了腳本語言的圖靈非完備性,這意味著腳本的復雜性有限,交易可執行的次數也可預見。腳本并不是一種通用語言,施加的這些限制確保該語言不被用于創造無限循環或其它類型的邏輯炸彈,這樣的炸彈可以植入在一筆交易中,通過引起拒絕服務的方式攻擊比特幣網絡。受限制的語言能防止交易激活機制被人當作薄弱環節而加以利用。

5.7 標準交易

五大標準腳本分別為P2PKH、P2PK、MS(限15個密鑰)、P2SH和OP_Return。

5.7.1 P2PKH(Pay-to-Public-Key-Hash)

比特幣網絡上的大多數交易都是P2PKH交易,此類交易都含有一個鎖定腳本,該腳本由公鑰哈希實現阻止輸出功能,公鑰哈希即為廣為人知的比特幣地址。由P2PKH腳本鎖定的輸出可以通過鍵入公鑰和由相應私鑰創設的數字簽名得以解鎖。

比特幣交易示例

假設alice要向bob支付0.015比特幣, alice會用到一個UTXO(假設是單輸入,單輸出),這個UTXO帶有一個鎖定腳本,為交易設置“障礙”。

鎖定腳本如下:

OP_DUP OP_HASH160 be10f0a78f5ac63e8746f7f2e62a5663eed05788 OP_EQUALVERIFY OP_CHECKSIG

OP_DUP:復制棧頂數據,然后該數據放置棧頂

OP_HASH160:對棧頂數據執行ripemd160(sha256(data)) (這其實是兩次摘要計算,不詳述)

be10f0a…:bob的比特幣地址

OP_EQUALVERIFY:對比棧頂的兩個數據,如果相等都被移除

OP_CHECKSIG:驗證簽名

bob如果要接收這筆比特幣(另一種說法是bob可以引用該筆輸出),就要給出一個解鎖腳本,然后解鎖腳本和鎖定腳本組合后執行的結果為真才能確認交易有效。

解鎖腳本如下:

3046022100ba1427639c9f67f2ca1088d0140318a98cb1e84f604dc90ae00ed7a5f9c61cab02210094233d018f2f014a5864c9e0795f13735780cafd51b950f503534a6af246aca30103a63ab88e75116b313c6de384496328df2656156b8ac48c75505cd20a4890f5ab

看起來是一堆數字,其實『簽名』和『公鑰』(sig & pubkey)的組合。簽名是bob的私鑰對該筆交易的信息加密的結果,公鑰就是指的bob的公鑰。

由于私鑰只有bob才知道,所以也只有他才能拿出正確的簽名。

Alice下達了向Bob咖啡館的比特幣地址支付0.015比特幣的支付指令,該筆交易的輸出內容為以下形式的鎖定腳本:OP_DUP OP_HASH160OP_EQUAL OP_CHECKSIG腳本中的 Cafe Public Key Hash 即為咖啡館的比特幣地址,但這個地址不是基于Base58Check編碼的。事實上,大多數比特幣地址都顯示為十六進制碼,而不是大家所熟知的以1開頭的基于Bsase58Check編碼的比特幣地址。鎖定腳本的解鎖版腳本是:將兩個腳本結合起來可以形成如下有效組合腳本:OP_DUP OP_HASH160 OP_EQUAL OP_CHECKSIG

只有當解鎖版腳本與鎖定版腳本的設定條件相匹配時,執行組合有效腳本時才會顯示結果為真(Ture)。即只有當解鎖腳本得到了咖啡館的有效簽名,交易執行結果才會被通過(結果為真),該有效簽名是從與公鑰哈希相匹配的咖啡館的私鑰中所獲取的。

5.7.2 P2PK(Pay-to-Public-Key)

與P2PKH相比,P2PK模式更為簡單。與P2PKH模式含有公鑰哈希的模式不同,在P2PK腳本模式中,公鑰本身已經存儲在鎖定腳本中,而且代碼長度也更短。P2PKH是由Satoshi創建的,主要目的一方面為使比特幣地址更簡短,另一方面也使之更方便使用。P2PK目前在Coinbase交易中最為常見,Coinbase交易由老的采礦軟件產生,目前還沒更新至P2PKH。

P2PK鎖定版腳本形式如下:?

<Public Key A> OP_CHECKSIG

用于解鎖的腳本是一個簡單簽名:?<Signature from Private Key A>

經由交易驗證軟件確認的組合腳本為:

<Signature from Private Key A>???<Public Key A> OP_CHECKSIG

該腳本只是CHECKSIG操作符的簡單調用,該操作主要是為了驗證簽名是否正確,如果正確,則返回為真(Ture)。

5.7.3 多重簽名

多重簽名腳本設置了這樣一個條件,假如記錄在腳本中的公鑰個數為N,則至少需提供其中的M個公鑰才可以解鎖。這也被稱為M-N組合,其中,N是記錄在腳本中的公鑰總個數,M是使得多重簽名生效的公鑰數閥值(最少數目)。例如,對于一個2-3多重簽名組合而言,存檔公鑰數為3個,至少同時使用其中2個或者2個以上的公鑰時,才能生成激活交易的簽名,通過驗證后才可使用這筆資金。

通用的M-N多重簽名鎖定腳本形式為:

M <Public key 1> ?<Public key 2> ... <Public key N>?N OP_CHECKMULTISIG

其中,N是存檔公鑰總數,M是要求激活交易的最少公鑰數。

5.7.5 P2SH(Pay-to-Script-Hash)

P2SH在2012年被作為一種新型、強大、且能大大簡化復雜交易腳本的交易類型而引入。為進一步解釋P2SH的必要性,讓我們先看一個實際的例子。

在第1章中,我們曾介紹過Mohammed,一個迪拜的電子產品進口商。Mohammed的公司采用比特幣多重簽名作為其公司會計賬簿記賬要求。多重簽名腳本是比特幣高級腳本最為常見的運用之一,是一種具有相當大影響力的腳本。針對所有的顧客支付(即應收賬款),Mohammed的公司要求采用多重簽名交易。基于多重簽名機制,顧客的任何支付都需要至少兩個簽名才能解鎖,一個來自Mohammed,另一個來自其合伙人或擁有備份鑰匙的代理人。這樣的多重簽名機制能為公司治理提供管控便利,同時也能有效防范盜竊、挪用和遺失。

最終的腳本非常長:

2 <Mohammed's Public key> ?<Partner1 Public key> <Partner2 Public key> <Partner3?Public key> <Attorney Public key>5 OP_CHECKMULTISIG

雖然多重簽名十分強大,但其使用起來還是多有不便。基于之前的腳本,Mohammed必須在客戶付款前將該腳本發送給每一位客戶,而每一位顧客也必須使用特制的能產生客戶交易腳本的比特幣錢包軟件,每位顧客還得學會如何利用腳本來完成交易。此外,由于腳本可能包含特別長的公鑰,最終的交易腳本可能是最初交易腳本長度的5倍之多。額外長度的腳本將給客戶造成費用負擔。最后,一個長的交易腳本將一直記錄在所有節點的隨機存儲器的UTXO集中,直到該筆資金被使用。所有這些都使得在實際交易中采用復雜輸出腳本顯得困難重重。

P2SH正是為了解決這一實際難題而被引入的,它旨在使復雜腳本的運用能與直接向比特幣地址支付一樣簡單。在P2SH支付中,復雜的鎖定腳本被電子指紋所取代,電子指紋為密碼學哈希。當一筆交易試圖支付UTXO時,要解鎖支付腳本,它必須含有與哈希相匹配的腳本。P2SH的含義是,向與該哈希匹配的腳本支付,當輸出被支付時,該腳本將在后續呈現。

在P2SH交易中,鎖定腳本由哈希取代,哈希指代的是贖回腳本。因為它在系統中是在贖回時出現而不是以鎖定腳本模式出現。

表5-5 P2SH復雜腳本

正如你在表中所看到的,在P2SH中,出現了花費該筆支出(贖回腳本)條件的復雜腳本,而這在鎖定腳本中并未出現。取而代之,在鎖定腳本中,只出現了哈希,而贖回腳本則在稍后輸出被支付時才作為解鎖腳本的一部分而出現。

首先,Mohammed公司對所有顧客訂單采用多重簽名腳本:

2 <Mohammed's Public key> ?<Partner1 Public key> ?<Partner2 Public key> ?<Partner3 Public key> ?<Attorney Public key> ?5 OP_CHECKMULTISIG

如果占位符由實際的公鑰(以04開頭的520字節)替代,你將會看到的腳本會非常地長:

2

04C16B8698A9ABF84250A7C3EA7EEDEF9897D1C8C6ADF47F06CF73370D74DCCA01CDCA79DCC5C395D7EEC6984D83F1F50C900A24DD47F569FD4193AF5DE762C58704A2192968D8655D6A935BEAF2CA23E3FB87A3495E7AF308EDF08DAC3C1FCBFC2C75B4B0F4D0B1B70CD2423657738C0C2B1D5CE65C97D78D0E34224858008E8B49047E63248B75DB7379BE9CDA8CE5751D16485F431E46117B9D0C1837C9D5737812F393DA7D4420D7E1A9162F0279CFC10F1E8E8F3020DECDBC3C0DD389D99779650421D65CBD7149B255382ED7F78E946580657EE6FDA162A187543A9D85BAAA93A4AB3A8F044DADA618D087227440645ABE8A35DA8C5B73997AD343BE5C2AFD94A5043752580AFA1ECED3C68D446BCAB69AC0A7DF50D56231BE0AABF1FDEEC78A6A45E394BA29A1EDF518C022DD618DA774D207D137AAB59E0B000EB7ED238F4D800 5 OP_CHECKMULTISIG

整個腳本都可由僅為20個字節的密碼哈希所取代,首先采用SH256哈希算法,隨后對其運用RIPEMD160算法。20字節的腳本為:

54c557e07dde5bb6cb791c7a540e0a4796f5e97

一筆P2SH交易運用鎖定腳本將輸出與哈希關聯,而不是與前面特別長的腳本所關聯。使用的鎖定腳本為:

OP_HASH160 54c557e07dde5bb6cb791c7a540e0a4796f5e97e OP_EQUAL

正如你所看到的,這個腳本比前面的長腳本簡短多了。取代“向該5個多重簽名腳本支付”,這個P2SH等同于“向含該哈希的腳本支付”。顧客在向Mohammed公司支付時,只需在其支付指令中納入這個非常簡短的鎖定腳本即可。當Mohammed想要花費這筆UTXO時,附上原始贖回腳本(與UTXO鎖定的哈希)和必要的解鎖簽名即可,如:

<Sig1> ?<Sig2> ?<2 PK1 PK2 PK3 PK4 PK5 5 OP_CHECKMULTISIG>

兩個腳本經由兩步實現組合。首先,將贖回腳本與鎖定腳本比對以確認其與哈希是否匹配:

<2 PK1 PK2 PK3 PK4 PK5 5 OP_CHECKMULTISIG> OP_HASH160 <redeem scriptHash> OP_EQUAL

假如贖回腳本與哈希匹配,解鎖腳本會被執行以釋放贖回腳本:

<Sig1> ?<Sig2> 2 PK1 PK2 PK3 PK4 PK5 5 OP_CHECKMULTISIG

5.7.5.1 P2SH地址

P2SH的另一重要特征是它能將腳本哈希編譯為一個地址(其定義請見BIP0013)

5.7.5.2 P2SH的優點

與直接使用復雜腳本以鎖定輸出的方式相比,P2SH具有以下特點:

1 在交易輸出中,復雜腳本由簡短電子指紋取代,使得交易代碼變短。

2 腳本能被編譯為地址,支付指令的發出者和支付者的比特幣錢包不需要復雜工序就可以執行P2SH。

3 P2SH將構建腳本的重擔轉移至接收方,而非發送方。

4 P2SH將長腳本數據存儲的負擔從輸出方(存儲于UTXO集,影響內存)轉移至輸入方(僅存儲于區塊鏈)。

5 P2SH將長腳本數據存儲的重擔從當前(支付時)轉移至未來(花費時)。

6 P2SH將長腳本的交易費成本從發送方轉移至接收方,接收方在使用該筆資金時必須含有贖回腳本。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容