signature=d74871422a22d225c49d50d42082d60a,bitcoinbook_2nd_zh

交易的輸出和輸入

比特幣交易的基本構建區塊是 交易的輸出 transaction output 。交易輸出是不可分割的比特幣貨幣,記錄在區塊鏈中,被整個網路識別為有效的。比特幣完整節點跟蹤所有可用和可花費的輸出,稱為 未花費的交易輸出 unspent transaction outputs 或 UTXO 。所有UTXO的集合被稱為 UTXO set ,目前有數以百萬的UTXO。UTXO集的大小隨著新UTXO的增加而增長,並在UTXO被消耗時縮小。每個交易都表示UTXO集中的更改(狀態轉移)。

當我們說用戶的錢包"收到"比特幣時,意思是錢包檢測到一個可以使用該錢包控制的密鑰來花費的UTXO。因此,用戶的比特幣"餘額"是用戶錢包可以花費的所有UTXO的總和,可以分散在數百個交易和數百個區塊中。餘額的概念是由錢包應用創建的。錢包掃描區塊鏈並將錢包可以使用它的密鑰花費的任何UTXO彙總計算用戶的餘額。大多數錢包維護資料庫或使用資料庫服務來儲存它們可以花費的所有UTXO的快照。

一個交易輸出可以有一個任意的(整數)等於satoshis倍數的值作為。正如美元可以分為小數點後兩位數字一樣,比特幣可以被分為小數點後八位,作為satoshis。儘管輸出可以具有任意值,但一旦創建就是不可分割的。這是需要強調的輸出的一個重要特徵:輸出是 不連續的 和 不可分割的 的價值,以整數satoshis為單位。未使用的輸出只能由交易全部花費。

如果UTXO大於交易的期望值,它仍然必須全部使用,並且必須在交易中生成零錢。換句話說,如果你有一個價值20比特幣的UTXO,並且只需要支付1比特幣,那麼你的交易必須消費整個20比特幣的UTXO,併產生兩個輸出:一個支付1比特幣給你想要的收款人,另一個支付19比特幣回到你的錢包。由於交易輸出的不可分割性,大多數比特幣交易將不得不產生零錢。

想象一下,一個購物者購買了1.50美元的飲料,並試圖從她的錢包找到硬幣和鈔票的組合,以支付1.50美元。如果可能,購物者將找到正好的零錢,例如,一美元鈔票和兩個二十五分硬幣(0.25美元),或小面值(六個二十五分硬幣)的組合;或者,直接向店主支付5美元,她會得到3.50美元的找零,放回她的錢包並且可用於未來的交易。

同樣,比特幣交易必須從用戶的UTXO創建,無論用戶有什麼樣的面額。用戶無法將UTXO削減一半,就像不能將美元分成兩半使用一樣。用戶的錢包應用通常會從用戶的可用UTXO中進行選擇,使組合的金額大於或等於期望交易金額。

與現實一樣,比特幣應用可以使用多種策略來滿足支付需求:合併幾個較小的單位,找到正好的零錢,或者使用比交易價值更大的單元並進行找零。所有這些花費UTXO的複雜操作都由用戶的錢包自動完成,對用戶不可見。只有在編寫程序構建來自UTXO的原始交易時才有意義。

交易消耗先前記錄的未使用的交易輸出,並創建可供未來交易使用的新交易輸出。這樣,大量的比特幣價值通過創建UTXO的交易鏈在所有者之間轉移。

輸出和輸入鏈的例外是稱為 幣基 coinbase 交易的特殊類型的交易,它是每個區塊中的第一個交易。這筆交易由"獲勝"的礦工設置,創建全新的比特幣並支付給該礦工作為挖礦獎勵。此特殊的coinbase交易不消費UTXO,相反,它有一種稱為"coinbase"的特殊輸入類型。這就是比特幣在挖礦過程中創造的貨幣數量,正如我們將在 [minig] 中看到的那樣。

Tip

先有的什麼?輸入還是輸出?雞還是雞蛋?嚴格地說,輸出是第一位的,因為產生新比特幣的幣基交易沒有輸入,是憑空產生的輸出。

交易輸出

每筆比特幣交易都產生輸出,這些輸出記錄在比特幣賬本上。除了一個例外(參見 [op_return] ),幾乎所有這些輸出都創造了稱為UTXO的可支付的比特幣,由整個網路認可並可供所有者在未來的交易中花費。

每個完整節點比特幣客戶端都跟蹤UTXO。新交易消耗(花費)UTXO集合的一個或多個輸出。

交易輸出由兩部分組成:

一些比特幣,最小單位為 聰 satoshis

定義了花費這些輸出所需條件的加密謎題

這個謎題也被稱為 鎖定腳本 locking script ,見證腳本 witness script ,或者 scriptPubKey。

在 交易腳本和腳本語言 中詳細討論了前面提到的鎖定腳本中使用的交易腳本語言。

現在,我們來看看Alice的交易( 交易背後 ),看看我們是否可以識別輸出。在JSON編碼中,輸出位於名為 vout 的陣列(列表)中:

"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",

}

]

如你所見,該交易包含兩個輸出。每個輸出由一個值和一個加密謎題定義。在Bitcoin Core顯示的編碼中,該值以比特幣為單位,但在交易本身中,它被記錄為以satoshis為單位的整數。每個輸出的第二部分是設置消費條件的加密謎題。 Bitcoin Core將其顯示為 scriptPubKey 並展示了該腳本的人類可讀的表示。

鎖定和解鎖UTXO的主題將在稍後的 創建腳本 ( 鎖定 + 解鎖 ) 中討論。在 交易腳本和腳本語言 中討論了 scriptPubKey 中使用的腳本語言。但在深入研究這些話題之前,我們需要了解交易輸入和輸出的總體結構。

交易序列化 —— 輸出

當交易通過網路傳輸或在應用程式之間交換時,它們是 序列化 的。序列化是將資料結構的內部表示轉換為可以一次傳輸一個位元組的格式(也稱為位元組流)的過程。序列化最常用於對通過網路傳輸或儲存在檔案中的資料結構進行編碼。交易輸出的序列化格式展示在 Transaction output serialization 中。

Table 1. Transaction output serialization

Size

Field

Description

8 位元組 (小端序)

數量 Amount

以聰(satoshis = 10-8 bitcoin) 為單位的比特幣價值

1——9 位元組 (VarInt)

鎖定腳本的大小 Locking-Script Size

後面的鎖定腳本的位元組數

變數

鎖定腳本 Locking-Script

定義花費該輸出的條件的腳本

大多數比特幣庫和框架在內部不以位元組流的形式儲存交易,因為每次需要訪問單個欄位時都需要進行復雜的解析。為了方便和易讀,比特幣庫在資料結構(通常是物件導向的結構)中儲存交易。

從交易的位元組流表示轉換為庫的內部表示資料結構的過程稱為 反序列化 deserialization 或 交易解析 transaction parsing 。轉換回位元組流以通過網路進行傳輸,進行雜湊或儲存在硬碟上的過程稱為 序列化 serialization。大多數比特幣庫具有用於交易序列化和反序列化的內置函數。

Example 1. Alice’s transaction, serialized and presented in hexadecimal notation

0100000001186f9f998a5aa6f048e51dd8419a14d8a0f1a8a2836dd73

4d2804fe65fa35779000000008b483045022100884d142d86652a3f47

ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039

ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813

01410484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade84

16ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc1

7b4a10fa336a8d752adfffffffff0260e31600000000001976a914ab6

8025513c3dbd2f7b92a94e0581f5d50f654e788acd0ef800000000000

1976a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac

00000000

這裡有一些提示:

0.015比特幣是1,500,000聰. 十六進制表示為 16 e3 60 .

在序列化的交易中,16 e3 60 以小端序(低位位元組在前)編碼,所以看起來是: 60 e3 16。

scriptPubKey 的長度是 25 位元組, 十六進制表示為 19 。

交易輸入

交易輸入標識(通過引用)將使用哪個UTXO並通過解鎖腳本提供所有權證明。

為了建立交易,錢包從其控制的UTXO中選擇具有足夠價值的UTXO進行所請求的付款。有時候一個UTXO就足夠了,有時候需要多個UTXO。對於將用於進行此項付款的每個UTXO,錢包將創建一個指向UTXO的輸入,並使用解鎖腳本將其解鎖。

讓我們更詳細地看看輸入的組成部分。輸入的第一部分是指向UTXO的指針,引用交易的雜湊值和輸出索引,該索引標識該交易中特定的UTXO。第二部分是一個解鎖腳本,由錢包構建,為了滿足UTXO中設置的花費條件。大多數情況下,解鎖腳本是證明比特幣所有權的數位簽章和公鑰。但是,並非所有解鎖腳本都包含簽名。第三部分是序列號,稍後將進行討論。

考慮 交易背後 中的示例,交易的輸出是 vin 陣列:

The transaction inputs in Alice’s transaction

"vin": [

{

"txid": "7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18",

"vout": 0,

"scriptSig" : "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813[ALL] 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf",

"sequence": 4294967295

}

]

如你所見,列表中只有一個輸入(因為這個UTXO包含足夠的值來完成此次付款)。輸入包含四個元素:

交易ID,引用包含正在使用的UTXO的交易

輸出索引( vout ),標識使用來自該交易的哪個UTXO(第一個從0開始)

scriptSig,滿足UTXO上的條件的腳本,用於解鎖並花費

一個序列號(後面討論)

在Alice的交易中,輸入指向交易ID:

7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18

輸出索引 0(即由該交易創建的第一個UTXO)。解鎖腳本由Alice的錢包構建,首先檢索引用的UTXO,檢查其鎖定腳本,然後使用它構建必要的解鎖腳本以滿足它。

只看輸入內容,你可能已經注意到我們對這個UTXO一無所知,只有對包含它的交易的引用。我們不知道它的價值(satoshi的數量),也不知道設置花費條件的鎖定腳本。要找到這些訊息,我們必須通過檢索底層交易來檢索引用的UTXO。請注意,因為輸入值沒有明確說明,我們還必須使用引用的UTXO來計算將在此次交易中支付的費用(請參見 交易費用 )。

不僅Alice的錢包需要檢索輸入中引用的UTXO。一旦這個交易被廣播到網路中,每個驗證節點也將需要檢索在交易輸入中引用的UTXO以驗證交易。

這些交易本身似乎不完整,因為它們缺乏上下文。他們在其輸入中引用UTXO,但不檢索該UTXO,我們不知道輸入值或鎖定條件。在編寫比特幣軟體時,只要你想要驗證交易,計算費用或檢查解鎖腳本,你的程式碼首先必須從區塊鏈中檢索引用的UTXO,以便構建輸入中引用的UTXO隱含但不包括的上下文。例如,要計算支付的費用金額,你必須知道輸入和輸出值的總和。如果不檢索輸入中引用的UTXO,則不知道它們的價值。因此,像單筆交易中計費的看似簡單的操作實際上涉及多個交易的多個步驟和數據。

我們可以使用在檢索Alice的交易時使用的相同的Bitcoin Core命令序列( getrawtransaction 和 decoderawtransaction )。得到前面輸入中引用的UTXO:

Alice’s UTXO from the previous transaction, referenced in the input

"vout": [

{

"value": 0.10000000,

"scriptPubKey": "OP_DUP OP_HASH160 7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 OP_EQUALVERIFY OP_CHECKSIG"

}

]

我們看到這個UTXO的值為 0.1 BTC,包含一個鎖定腳本( scriptPubKey ): "OP_DUP OP_HASH160…​".

Tip

為了完全理解Alice的交易,我們必須檢索輸入引用的交易。幾乎每個比特幣庫和API中都有一個函數,用於檢索以前的交易和未使用的交易輸出。

交易序列化 —— 輸入

當交易被序列化以便在網路上傳輸時,它們的輸入被編碼為位元組流,如 Transaction input serialization 所示。

Table 2. Transaction input serialization

Size

Field

Description

32 位元組

交易的雜湊值 Transaction Hash

指向包含要花費的UTXO的交易的指針

4 位元組

輸出的索引 Output Index

要花費的UTXO的索引,從0開始

1——9 位元組 (VarInt)

解鎖腳本的大小 Unlocking-Script Size

後面的解鎖腳本的位元組長度

變數

解鎖腳本 Unlocking-Script

滿足UTXO鎖定腳本條件的腳本

4 位元組

序列號 Sequence Number

用於鎖定時間(locktime)或禁用 (0xFFFFFFFF)

與輸出一樣,看看是否能夠在序列化格式中查找來自Alice的交易的輸入。首先,解碼的輸入如下:

"vin": [

{

"txid": "7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18",

"vout": 0,

"scriptSig" : "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813[ALL] 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf",

"sequence": 4294967295

}

],

Example 2. Alice’s transaction, serialized and presented in hexadecimal notation

0100000001186f9f998a5aa6f048e51dd8419a14d8a0f1a8a2836dd73

4d2804fe65fa35779000000008b483045022100884d142d86652a3f47

ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039

ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813

01410484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade84

16ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc1

7b4a10fa336a8d752adfffffffff0260e31600000000001976a914ab6

8025513c3dbd2f7b92a94e0581f5d50f654e788acd0ef800000000000

1976a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac00000

000

提示:

交易ID是以反向位元組順序序列化的,因此它以(十六進制)18 開頭並以 79 結尾

輸出索引是一個4位元組的零,容易識別

scriptSig 的長度為139個位元組,十六進制的 8b

序列號設置為 FFFFFFFF,也易於識別

交易費用

大多數交易包括交易費用,以獎勵比特幣礦工,保證網路安全。費用本身也可以作為一種安全機制,因為攻擊者通過大量交易充斥網路在經濟上是不可行的。 [mining] 更詳細地討論了礦工以及礦工收取的費用和獎勵。

本節探討交易費用如何包含在典型的交易中。大多數錢包會自動計算幷包含交易費用。但是,如果你以寫程式的方式構建交易或使用命令行界面,則必須手動進行計算幷包含這些費用。

交易費用是將交易納入下一個區塊的激勵措施,也是對每次交易徵收小額費用以抵制系統濫用的防範機制。交易費由礦工收集,該礦工將開採在區塊鏈上記錄交易的區塊。

交易費用是以交易數據的大小(KB)計算的,而不是比特幣交易的價值。總體而言,交易費用是根據比特幣網路內的市場力量設定的。礦工根據許多不同的優先條件(包括費用)處理交易,也可能在某些情況下免費處理交易。交易費用會影響處理優先權,這意味著如果交易費用足夠,交易就可能包含在下一個開採區塊中,而費用不足或不收費的交易可能會延遲,在幾個區塊後以盡力而為的方式處理,或者根本不處理。交易費用不是強制性的,沒有費用的交易最終可以被處理;但是,包括交易費用鼓勵優先處理。

隨著時間的推移,交易費用的計算方式以及它們對交易優先級的影響已經發生了變化。起初,交易費用在整個網路中是固定不變的。逐漸地,收費結構放鬆,並可能受到基於網路容量和交易量的市場力量的影響。至少從2016年初開始,比特幣的容量限制已經造成了交易之間的競爭,導致了更高的費用,使免費的交易成為了歷史。免費或低費用的交易很少能被開採,有時甚至不會通過網路傳播。

在Bitcoin Core中,收費中繼策略由 minrelaytxfee 選項設置。當前的預設值是每KB數據0.00001比特幣或0.01毫比特幣。因此,預設情況下,低於0.00001比特幣的交易將被視為免費,並且只在Memory pool有空間時才會被中轉;否則,它們將被丟棄。比特幣節點可以通過調整 minrelaytxfee 的值來覆蓋預設的收費中繼策略。

任何創建交易的比特幣服務,包括錢包,交易所,零售應用等,都 必須 實施動態費用。動態費用可以通過第三方費用估算服務或內置費用估算演算法來實現。如果你不確定,請先從第三方服務開始,如果你希望移除第三方依賴關係,設計並實現自己的演算法。

費用估算演算法根據容量和"競爭"交易提供的費用計算適當的費用。這些演算法的從簡單(最後一個區塊的平均費用或中值費用)到複雜(統計分析)。他們估計必要的費用(每字節多少satoshis),使交易被選中幷包含在一定數量的區塊內的可能性很高。大多數服務為用戶提供選擇高、中、低優先級費用的選項。高優先級意味著用戶支付更高的費用,但交易很可能包含在下一個區塊中。中等和低優先級意味著用戶支付較低的交易費用,但交易可能需要更長時間才能確認。

許多錢包應用使用第三方服務計算費用。一種流行的服務是 http://bitcoinfees.21.co,它提供了一個API和一個可視圖表,顯示了不同優先級的 satoshi/位元組 費用。

Tip

比特幣網路上的固定費用已不再可行。設置固定費用的錢包將產生糟糕的用戶體驗,因為交易通常會"卡住",不被驗證。不瞭解比特幣交易和費用的用戶會因為"停滯的"交易感到沮喪,他們會認為錢已經丟失了。

Fee estimation service bitcoinfees.21.co 中的圖表以10 satoshi/位元組的增量顯示實時的費用估算值,以及每個費用範圍內的預期確認時間(以分鐘和區塊數表示)。對於每個費用範圍(例如,61-70 satoshi/位元組),兩個橫條顯示了未確認交易的數量(1405)和過去24小時內的交易總數(102,975)。根據圖表,此時建議的高優先級費用為 80 satoshi /位元組,可能使交易在下一個區塊中開採(0區塊延遲)。交易規模的中位數為226位元組,所以此交易規模的建議費用為 18,080 satoshis(0.00018080 BTC)。

費用估算數據可以通過簡單的HTTP REST API檢索, https://bitcoinfees.21.co/api/v1/fees/recommended. 例如,在命令行中使用 curl 命令:

Using the fee estimation API

$ curl https://bitcoinfees.21.co/api/v1/fees/recommended

{"fastestFee":80,"halfHourFee":80,"hourFee":60}

API返回一個帶有當前費用估計的JSON物件,包含最快速度確認( fasterFee ),三個區塊內確認( halfHourFee )和六個區塊內確認( hourFee )的費用,單位是 satoshi/位元組。

32a87fd97ec57676527bdd8efbeb2511.png

Figure 2. Fee estimation service bitcoinfees.21.co

將費用添加到交易

交易的資料結構沒有費用欄位。相反,費用隱含表示為輸入總和與輸出總和的差額。從所有輸入中扣除所有輸出後剩餘的金額都是礦工收取的費用:

Transaction fees are implied, as the excess of inputs minus outputs:

Fees = Sum(Inputs) – Sum(Outputs)

這是一個有點令人困惑的交易元素,也是需要理解的重要一點,因為如果你正在構建自己的交易,則必須確保你不會花費了很少的輸入卻無意中包含非常高的費用。這意味著你必須考慮所有輸入,必要時創建找零,否則最終會給礦工一個非常高的小費!

例如,如果你使用20比特幣UTXO進行1比特幣支付,則必須將19比特幣零錢輸出回你的錢包。否則,19比特幣將被算作交易費用,並將由礦工在一個區塊中進行交易。雖然你會得到優先處理並讓礦工很高興,但這可能不是你想要的。

Warning

如果你忘記在手動構建的交易中添加找零輸出,則你將支付零錢作為交易費用。 "不用找了!" 可能不是你想要的。

我們再來看看Alice購買咖啡的情況,看看它在實踐中是如何運作的。 Alice 想花0.015比特幣來買咖啡。為確保此交易得到及時處理,她希望包含交易費用,例如0.001。這意味著交易的總成本將是0.016。她的錢包因此必須提供一些UTXO,加起來0.016比特幣或更多,如有必要,可以創建找零。假設她的錢包有一個0.2比特幣的UTXO。因此,它需要消費這個UTXO,創建一個給Bob 0.015的輸出,和一個0.184比特幣的零錢輸出,返回她自己的錢包,剩下0.001比特幣未分配,作為隱含的交易費用。

現在讓我們看看不同的場景。菲律賓的兒童慈善總監Eugenia已經完成了為兒童購買教科書的籌款活動。她收到了來自世界各地的數千人的小額捐款,共計50比特幣,所以她的錢包充滿了非常多的小額未使用輸出(UTXO)。現在她想從本地出版商處購買數百本教科書,用比特幣支付。

Eugenia的錢包應用試圖構建一個較大的付款交易,因此它必須從可用的小金額UTXO集合中獲取資金。這意味著由此產生的交易將有超過一百個小型UTXO輸入,只有一個輸出支付給書籍出版商。具有許多輸入的交易將大於一千位元組,也許幾千位元組大小。因此,它需要比中等規模交易高得多的費用。

Eugenia的錢包應用程式將通過衡量交易規模並將其乘以每千位元組的費用來計算適當的費用。許多錢包會為較大的交易多付費用,以確保交易得到及時處理。較高的費用並不是因為Eugenia花費更多的錢,而是因為她的交易規模更大更復雜 - 收費與交易的比特幣價值無關。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值