-
Notifications
You must be signed in to change notification settings - Fork 80
/
txsizes.go
249 lines (228 loc) · 8.09 KB
/
txsizes.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
package spvwallet
// Copyright (c) 2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
/* Copied here from a btcd internal package*/
import (
"github.com/btcsuite/btcd/wire"
)
// Worst case script and input/output size estimates.
const (
// RedeemP2PKHSigScriptSize is the worst case (largest) serialize size
// of a transaction input script that redeems a compressed P2PKH output.
// It is calculated as:
//
// - OP_DATA_73
// - 72 bytes DER signature + 1 byte sighash
// - OP_DATA_33
// - 33 bytes serialized compressed pubkey
RedeemP2PKHSigScriptSize = 1 + 73 + 1 + 33
// RedeemP2SHMultisigSigScriptSize is the worst case (largest) serialize size
// of a transaction input script that redeems a 2 of 3 P2SH multisig output with compressed keys.
// It is calculated as:
//
// - OP_0
// - OP_DATA_72
// - 72 bytes DER signature
// - OP_DATA_72
// - 72 bytes DER signature
// - OP_PUSHDATA
// - OP_2
// - OP_DATA_33
// - 33 bytes serialized compressed pubkey
// - OP_DATA_33
// - 33 bytes serialized compressed pubkey
// - OP_DATA_33
// - 33 bytes serialized compressed pubkey
// - OP3
// - OP_CHECKMULTISIG
RedeemP2SH2of3MultisigSigScriptSize = 1 + 1 + 72 + 1 + 72 + 1 + 1 + 1 + 33 + 1 + 33 + 1 + 33 + 1 + 1
// RedeemP2SH1of2MultisigSigScriptSize is the worst case (largest) serialize size
// of a transaction input script that redeems a 1 of 2 P2SH multisig output with compressed keys.
// It is calculated as:
//
// - OP_0
// - OP_DATA_72
// - 72 bytes DER signature
// - OP_PUSHDATA
// - OP_1
// - OP_DATA_33
// - 33 bytes serialized compressed pubkey
// - OP_DATA_33
// - 33 bytes serialized compressed pubkey
// - OP2
// - OP_CHECKMULTISIG
RedeemP2SH1of2MultisigSigScriptSize = 1 + 1 + 72 + 1 + 1 + 1 + 33 + 1 + 33 + 1 + 1
// RedeemP2SHMultisigTimelock1SigScriptSize is the worst case (largest) serialize size
// of a transaction input script that redeems a compressed P2SH timelocked multisig using the timeout.
// It is calculated as:
//
// - OP_DATA_72
// - 72 bytes DER signature
// - OP_0
// - OP_PUSHDATA
// - OP_IF
// - OP_2
// - OP_DATA_33
// - 33 bytes serialized compressed pubkey
// - OP_DATA_33
// - 33 bytes serialized compressed pubkey
// - OP_DATA_33
// - 33 bytes serialized compressed pubkey
// - OP3
// - OP_CHECKMULTISIG
// - OP_ELSE
// - OP_PUSHDATA
// - 2 byte block height
// - OP_CHECKSEQUENCEVERIFY
// - OP_DROP
// - OP_DATA_33
// - 33 bytes serialized compressed pubkey
// - OP_CHECKSIG
// - OP_ENDIF
RedeemP2SHMultisigTimelock1SigScriptSize = 1 + 72 + 1 + 1 + 1 + 1 + 1 + 33 + 1 + 33 + 1 + 33 + 1 + 1 + 1 + 1 + 2 + 1 + 1 + 1 + 33 + 1 + 1
// RedeemP2SHMultisigTimelock2SigScriptSize is the worst case (largest) serialize size
// of a transaction input script that redeems a compressed P2SH timelocked multisig without using the timeout.
// It is calculated as:
//
// - OP_0
// - OP_DATA_72
// - 72 bytes DER signature
// - OP_DATA_72
// - 72 bytes DER signature
// - OP_1
// - OP_PUSHDATA
// - OP_IF
// - OP_2
// - OP_DATA_33
// - 33 bytes serialized compressed pubkey
// - OP_DATA_33
// - 33 bytes serialized compressed pubkey
// - OP_DATA_33
// - 33 bytes serialized compressed pubkey
// - OP3
// - OP_CHECKMULTISIG
// - OP_ELSE
// - OP_PUSHDATA
// - 2 byte block height
// - OP_CHECKSEQUENCEVERIFY
// - OP_DROP
// - OP_DATA_33
// - 33 bytes serialized compressed pubkey
// - OP_CHECKSIG
// - OP_ENDIF
RedeemP2SHMultisigTimelock2SigScriptSize = 1 + 1 + 72 + +1 + 72 + 1 + 1 + 1 + 1 + 1 + 33 + 1 + 33 + 1 + 33 + 1 + 1 + 1 + 1 + 2 + 1 + 1 + 1 + 33 + 1 + 1
// P2PKHPkScriptSize is the size of a transaction output script that
// pays to a compressed pubkey hash. It is calculated as:
//
// - OP_DUP
// - OP_HASH160
// - OP_DATA_20
// - 20 bytes pubkey hash
// - OP_EQUALVERIFY
// - OP_CHECKSIG
P2PKHPkScriptSize = 1 + 1 + 1 + 20 + 1 + 1
// RedeemP2PKHInputSize is the worst case (largest) serialize size of a
// transaction input redeeming a compressed P2PKH output. It is
// calculated as:
//
// - 32 bytes previous tx
// - 4 bytes output index
// - 1 byte script len
// - signature script
// - 4 bytes sequence
RedeemP2PKHInputSize = 32 + 4 + 1 + RedeemP2PKHSigScriptSize + 4
// RedeemP2SH2of3MultisigInputSize is the worst case (largest) serialize size of a
// transaction input redeeming a compressed P2SH 2 of 3 multisig output. It is
// calculated as:
//
// - 32 bytes previous tx
// - 4 bytes output index
// - 1 byte script len
// - 4 bytes sequence
/// - witness discounted signature script
RedeemP2SH2of3MultisigInputSize = 32 + 4 + 1 + 4 + (RedeemP2SH2of3MultisigSigScriptSize / 4)
// RedeemP2SH1of2MultisigInputSize is the worst case (largest) serialize size of a
// transaction input redeeming a compressed P2SH 2 of 3 multisig output. It is
// calculated as:
//
// - 32 bytes previous tx
// - 4 bytes output index
// - 1 byte script len
// - 4 bytes sequence
/// - witness discounted signature script
RedeemP2SH1of2MultisigInputSize = 32 + 4 + 1 + 4 + (RedeemP2SH1of2MultisigSigScriptSize / 4)
// RedeemP2SHMultisigTimelock1InputSize is the worst case (largest) serialize size of a
// transaction input redeeming a compressed p2sh timelocked multig output with using the timeout. It is
// calculated as:
//
// - 32 bytes previous tx
// - 4 bytes output index
// - 1 byte script len
// - 4 bytes sequence
/// - witness discounted signature script
RedeemP2SHMultisigTimelock1InputSize = 32 + 4 + 1 + 4 + (RedeemP2SHMultisigTimelock1SigScriptSize / 4)
// RedeemP2SHMultisigTimelock2InputSize is the worst case (largest) serialize size of a
// transaction input redeeming a compressed P2SH timelocked multisig output without using the timeout. It is
// calculated as:
//
// - 32 bytes previous tx
// - 4 bytes output index
// - 1 byte script len
// - 4 bytes sequence
/// - witness discounted signature script
RedeemP2SHMultisigTimelock2InputSize = 32 + 4 + 1 + 4 + (RedeemP2SHMultisigTimelock2SigScriptSize / 4)
// P2PKHOutputSize is the serialize size of a transaction output with a
// P2PKH output script. It is calculated as:
//
// - 8 bytes output value
// - 1 byte compact int encoding value 25
// - 25 bytes P2PKH output script
P2PKHOutputSize = 8 + 1 + P2PKHPkScriptSize
)
type InputType int
const (
P2PKH InputType = iota
P2SH_1of2_Multisig
P2SH_2of3_Multisig
P2SH_Multisig_Timelock_1Sig
P2SH_Multisig_Timelock_2Sigs
)
// EstimateSerializeSize returns a worst case serialize size estimate for a
// signed transaction that spends inputCount number of compressed P2PKH outputs
// and contains each transaction output from txOuts. The estimated size is
// incremented for an additional P2PKH change output if addChangeOutput is true.
func EstimateSerializeSize(inputCount int, txOuts []*wire.TxOut, addChangeOutput bool, inputType InputType) int {
changeSize := 0
outputCount := len(txOuts)
if addChangeOutput {
changeSize = P2PKHOutputSize
outputCount++
}
var redeemScriptSize int
switch inputType {
case P2PKH:
redeemScriptSize = RedeemP2PKHInputSize
case P2SH_1of2_Multisig:
redeemScriptSize = RedeemP2SH1of2MultisigInputSize
case P2SH_2of3_Multisig:
redeemScriptSize = RedeemP2SH2of3MultisigInputSize
case P2SH_Multisig_Timelock_1Sig:
redeemScriptSize = RedeemP2SHMultisigTimelock1InputSize
case P2SH_Multisig_Timelock_2Sigs:
redeemScriptSize = RedeemP2SHMultisigTimelock2InputSize
}
// 10 additional bytes are for version, locktime, and segwit flags
return 10 + wire.VarIntSerializeSize(uint64(inputCount)) +
wire.VarIntSerializeSize(uint64(outputCount)) +
inputCount*redeemScriptSize +
SumOutputSerializeSizes(txOuts) +
changeSize
}
// SumOutputSerializeSizes sums up the serialized size of the supplied outputs.
func SumOutputSerializeSizes(outputs []*wire.TxOut) (serializeSize int) {
for _, txOut := range outputs {
serializeSize += txOut.SerializeSize()
}
return serializeSize
}