簡單地說,交易輸入是指向UTXO的指標。它們指向特定的UTXO,並被交易雜湊和在區塊鏈中記錄UTXO的序列號作為參考。若想支付UTXO,一個交易的輸入也需要包含一個解鎖指令碼,用來滿足UTXO的支付條件。解鎖指令碼通常是一個簽名,用來證明對於在鎖定指令碼中的比特幣地址擁有所有權。
當用戶付款時,他的錢包透過選擇可用的UTXO來構造一筆交易。比如說,要支付0.015比特幣,錢包應用會選擇一個0.01 UTXO和一個0.005 UTXO,使用它們加在一起來得到想要的付款額。
在例5-3中,我們展示了一種貪心演算法來為了得到特定的付款額而選擇可用的UTXO。在例中,可用的UTXO被提供在一個常數陣列中。但在實際中,可用的UTXO被一個遠端過程呼叫比特幣核心,或者被一個如例5-1中的第三方應用程式介面,來檢索出來。
例5-3 一個計算會被髮送的比特幣總量的指令碼
# 使用貪心演算法從UTXO列表中選擇輸出。from sys import argv class OutputInfo: def __init__(self, tx_hash, tx_index, value): self.tx_hash = tx_hash self.tx_index = tx_index self.value = value def __repr__(self): return "<%s:%s with %s Satoshis>" % (self.tx_hash, self.tx_index, self.value) # 為了傳送,從未花費的輸出列表中選出最優輸出。# 返回輸出列表,並且把其他的改動傳送到改變地址。def select_outputs_greedy(unspent, min_value): # 如果是空的話認為是失敗了。 if not unspent: return None # 分割成兩個列表。 lessers = [utxo for utxo in unspent if utxo.value < min_value] greaters = [utxo for utxo in unspent if utxo.value >= min_value] key_func = lambda utxo: utxo.value if greaters: # 非空。尋找最小的greater。 min_greater = min(greaters) change = min_greater.value - min_value return [min_greater], change # 沒有找到greaters。重新嘗試若干更小的。 # 從大到小排序。我們需要儘可能地使用最小的輸入量。 lessers.sort(key=key_func, reverse=True) result = [] accum = 0 for utxo in lessers: result.append(utxo) accum += utxo.value if accum >= min_value: change = accum - min_value return result, "Change: %d Satoshis" % change # 沒有找到。 return None, 0 def main(): unspent = [ OutputInfo("ebadfaa92f1fd29e2fe296eda702c48bd11ffd52313e986e99ddad9084062167", 1, 8000000), OutputInfo("6596fd070679de96e405d52b51b8e1d644029108ec4cbfe451454486796a1ecf", 0, 16050000), OutputInfo("b2affea89ff82557c60d635a2a3137b8f88f12ecec85082f7d0a1f82ee203ac4", 0, 10000000), OutputInfo("7dbc497969c7475e45d952c4a872e213fb15d45e5cd3473c386a71a1b0c136a1", 0, 25000000), OutputInfo("55ea01bd7e9afd3d3ab9790199e777d62a0709cf0725e80a7350fdb22d7b8ec6", 17, 5470541), OutputInfo("12b6a7934c1df821945ee9ee3b3326d07ca7a65fd6416ea44ce8c3db0c078c64", 0, 10000000), OutputInfo("7f42eda67921ee92eae5f79bd37c68c9cb859b899ce70dba68c48338857b7818", 0, 16100000), ] if len(argv) > 1: target = long(argv[1]) else: target = 55000000 print "For transaction amount %d Satoshis (%f bitcoin) use: " % (target, target/ 10.0**8) print select_outputs_greedy(unspent, target) if __name__ == "__main__": main()
如果我們不使用引數執行select-utxo.py指令碼,它會試圖為一筆五千五百萬聰(0.55比特幣)的付款構造一組UTXO。如果你提供一個指定的付款額作為引數,指令碼會選擇UTXO來完成指定的付款額。在例5-4中,我們執行指令碼來試著完成一筆0.5比特幣,或者說是五千萬聰的付款。
例5-4 執行select-utxo.py
$ python select-utxo.py 50000000For transaction amount 50000000 Satoshis (0.500000 bitcoin) use:([<7dbc497969c7475e45d952c4a872e213fb15d45e5cd3473c386a71a1b0c136a1:0 with 25000000Satoshis>, <7f42eda67921ee92eae5f79bd37c68c9cb859b899ce70dba68c48338857b7818:0 with 16100000 Satoshis>,<6596fd070679de96e405d52b51b8e1d644029108ec4cbfe451454486796a1ecf:0 with 16050000 Satoshis>], 'Change: 7150000 Satoshis')
一旦UTXO被選中,錢包會為每個UTXO生成包含簽名的解鎖指令碼,由此讓它們變得可以透過滿足鎖定指令碼的條件來被支付。錢包把這些UTXO作為參考,並且連同解鎖指令碼一起作為輸入加到交易中。表5-3展示了交易輸入的結構。
表5-3 交易輸入的結構
尺寸 |
欄位 |
說明 |
32個位元組 |
交易 |
指向交易包含的被花費的UTXO的雜湊指標 |
4個位元組 |
輸出索引 |
被花費的UTXO的索引號,第一個是0 |
1–9個位元組(可變整數) |
解鎖指令碼尺寸 |
用位元組表示的後面的解鎖指令碼長度 |
變長 |
解鎖指令碼 |
一個達到UTXO鎖定指令碼中的條件的指令碼 |
4個位元組 |
序列號 |
目前未被使用的交易替換功能,設成0xFFFFFFFF |
序列號是用來覆蓋在交易鎖定時間之前失效的交易,這是一專案前沒有在比特幣中用到的功能。大多數交易把這個值設定成最大的整數(0xFFFFFFFF)並且被比特幣網路忽略。如果一次交易有非零的鎖定時間,那麼它至少需要有一個序列號比0xFFFFFFFF低的輸入來啟用鎖定時間。
#歐易OKEx##比特幣[超話]##數字貨幣#