如何在發送前計算交易大小(Legacy Non-Segwit - P2PKH/P2SH)
我知道我支付每 kB 的交易費用,所以在我通過 RPC api 發送之前,我如何計算交易的大小。我使用比特幣經營一個網站,我不能讓使用者的餘額變成負數,所以我需要知道他們是否有足夠的餘額來支付費用。
假設您花費的所有輸入都來自正常的“支付到地址”交易,那麼每個輸入將為交易貢獻 180(正負 1)字節。每個輸出向事務添加 34 個字節。並且始終存在固定的額外 10 個字節。
“加或減 1”來自於每個輸入都需要一個簽名才能聲明的事實。簽名包含兩個 32 字節的值,但如果其中任何一個值的第一個字節
0x80
或更多,則它0x00
前面有一個字節。所以我假設兩者之一是高的,另一個是低的。這樣,每個輸入我最多會偏離一個字節。因此,如果您的交易有
in
輸入和out
輸出,則交易大小(以字節為單位)將為:in*180 + out*34 + 10 plus or minus 'in'
例如,這個交易有 40 個輸入和 16 個輸出。這給了我們一個交易規模
40*180 + 16*34 + 10 +- 40
即
7754 +- 40
字節。實際大小是7761
字節。如果輸入來自“pay to pubkey”交易,那麼輸入小於“pay to address”交易。這對於“支付腳本雜湊”輸入也將有所不同,具體取決於如何/是否實現。
編輯:這筆交易是用在Linode搶劫案中被盜的比特幣進行的,交易規模為1337,可能是在區塊鏈中故意使用了leetspeak。
Edit2:現在壓縮的公鑰很常見,每個輸入都短了 32 個字節,所以現在的交易大小是:
in*148 + out*34 + 10 plus or minus 'in'
以下是基於協議文件的一些計算。
比特幣交易由以下部分組成:
版本(4 字節)
TxIn 計數 (1 ~ 9B)
對於每個 TxIn:
- 外點 (36B)
- 腳本長度 (1 ~ 9B)
- 腳本簽名(?)
- 序列 (4B)
TxOut 計數 (1 ~ 9B)
對於每個 TxOut:
- 價值 (8B)
- 腳本長度(1 ~ 9B)*
- 腳本 (?)*
鎖定時間 (4B)
假設創建了一個標準的 P2SH/P2PKH 交易,星號標記的腳本長度將綁定到 1 個字節,因為腳本長度被編碼為一個可變整數;而用星號標記的腳本大小將綁定到 24 字節,因為它只包含一個腳本雜湊。
因此,總而言之,如果我們向 P2SH/P2PKH 地址付款,我們可以假設每個 TxOut 的最大邊界為 34 個字節,因為每個輸出腳本中有 4 個操作碼。可以在這裡找到一個很好的細分。
假設我們為 TxIn 花費 P2PKH 外點。我們的 ScriptSig(由 72 字節的 DER 編碼交易簽名 + 33 字節的公鑰組成)大小為 146 字節,而我們的腳本長度將僅消耗 1 字節,因為 ScriptSig 的大小小於 0xFD。
因此,一個標準的 P2PKH/P2SH 交易花費一個可贖回的UTXO和一個基本的 ScriptSig 只支付一個輸出是 189 字節。否則,我們還可以將其進一步概括為:
in
標記 TxIns 的數量
out
標記 TxOuts 的數量假設
in
< 254 和out
< 254。P2SH/P2PKH 交易大小 =
in
* 146 +out
* 33 + 10計算由複雜輸入資助的 P2SH/P2PKH 交易的大小(即,可使用 M-of-N 簽名的 UTXO,散列時間鎖定合約)本質上是困難的,並且取決於用於生成 scriptHash 的redeemScript 的複雜性之前的 P2SH 交易。