1 package txscript
2 3 import (
4 "fmt"
5 )
6 7 // ErrorCode identifies a kind of script error.
8 type ErrorCode int
9 10 // These constants are used to identify a specific ScriptError.
11 const (
12 // ErrInternal is returned if internal consistency checks fail. In practice
13 // this error should never be seen as it would mean there is an error in the
14 // engine logic.
15 ErrInternal ErrorCode = iota
16 17 // Failures related to improper API usage.
18 19 // ErrInvalidFlags is returned when the passed flags to NewEngine contain an
20 // invalid combination.
21 ErrInvalidFlags
22 // ErrInvalidIndex is returned when an out-of-bounds index is passed to a
23 // function.
24 ErrInvalidIndex
25 // ErrUnsupportedAddress is returned when a concrete type that implements a
26 // util.Address is not a supported type.
27 ErrUnsupportedAddress
28 // ErrNotMultisigScript is returned from CalcMultiSigStats when the provided
29 // script is not a multisig script.
30 ErrNotMultisigScript
31 // ErrTooManyRequiredSigs is returned from MultiSigScript when the specified
32 // number of required signatures is larger than the number of provided public
33 // keys.
34 ErrTooManyRequiredSigs
35 // ErrTooMuchNullData is returned from NullDataScript when the length of the
36 // provided data exceeds MaxDataCarrierSize.
37 ErrTooMuchNullData
38 39 // Failures related to final execution state.
40 41 // ErrEarlyReturn is returned when OP_RETURN is executed in the script.
42 ErrEarlyReturn
43 // ErrEmptyStack is returned when the script evaluated without error, but
44 // terminated with an empty top stack element.
45 ErrEmptyStack
46 // ErrEvalFalse is returned when the script evaluated without error but
47 // terminated with a false top stack element.
48 ErrEvalFalse
49 // ErrScriptUnfinished is returned when CheckErrorCondition is called on a
50 // script that has not finished executing.
51 ErrScriptUnfinished
52 // ErrInvalidProgramCounter is...
53 ErrInvalidProgramCounter
54 // ErrScriptDone is returned when an attempt to execute an opcode is made
55 // once all of them have already been executed. This can happen due to things
56 // such as a second call to Execute or calling Step after all opcodes have
57 // already been executed.
58 59 // Failures related to exceeding maximum allowed limits.
60 61 // ErrScriptTooBig is returned if a script is larger than MaxScriptSize.
62 ErrScriptTooBig
63 // ErrElementTooBig is returned if the size of an element to be pushed to the
64 // stack is over MaxScriptElementSize.
65 ErrElementTooBig
66 // ErrTooManyOperations is returned if a script has more than MaxOpsPerScript
67 // opcodes that do not push data.
68 ErrTooManyOperations
69 // ErrStackOverflow is returned when stack and altstack combined depth is
70 // over the limit.
71 ErrStackOverflow
72 // ErrInvalidPubKeyCount is returned when the number of public keys specified
73 // for a multsig is either negative or greater than MaxPubKeysPerMultiSig.
74 ErrInvalidPubKeyCount
75 // ErrInvalidSignatureCount is returned when the number of signatures
76 // specified for a multisig is either negative or greater than the number of
77 // public keys.
78 ErrInvalidSignatureCount
79 // ErrNumberTooBig is returned when the argument for an opcode that expects
80 // numeric input is larger than the expected maximum number of bytes. For the
81 // most part, opcodes that deal with stack manipulation via offsets,
82 // arithmetic, numeric comparison, and boolean logic are those that this
83 // applies to. However, any opcode that expects numeric input may fail with
84 // this code.
85 ErrNumberTooBig
86 87 // Failures related to verification operations.
88 89 // ErrVerify is returned when OP_VERIFY is encountered in a script and
90 // the top item on the data stack does not evaluate to true.
91 ErrVerify
92 // ErrEqualVerify is returned when OP_EQUALVERIFY is encountered in a script
93 // and the top item on the data stack does not evaluate to true.
94 ErrEqualVerify
95 // ErrNumEqualVerify is returned when OP_NUMEQUALVERIFY is encountered in a
96 // script and the top item on the data stack does not evaluate to true.
97 ErrNumEqualVerify
98 // ErrCheckSigVerify is returned when OP_CHECKSIGVERIFY is encountered in a
99 // script and the top item on the data stack does not evaluate to true.
100 ErrCheckSigVerify
101 // ErrCheckMultiSigVerify is returned when OP_CHECKMULTISIGVERIFY is
102 // encountered in a script and the top item on the data stack does not
103 // evaluate to true.
104 ErrCheckMultiSigVerify
105 // Failures related to improper use of opcodes.
106 107 // ErrDisabledOpcode is returned when a disabled opcode is encountered in a
108 // script.
109 ErrDisabledOpcode
110 // ErrReservedOpcode is returned when an opcode marked as reserved is
111 // encountered in a script.
112 ErrReservedOpcode
113 // ErrMalformedPush is returned when a data push opcode tries to push more
114 // bytes than are left in the script.
115 ErrMalformedPush
116 // ErrInvalidStackOperation is returned when a stack operation is attempted
117 // with a number that is invalid for the current stack size.
118 ErrInvalidStackOperation
119 // ErrUnbalancedConditional is returned when an OP_ELSE or OP_ENDIF is
120 // encountered in a script without first having an OP_IF or OP_NOTIF or the
121 // end of script is reached without encountering an OP_ENDIF when an OP_IF or
122 // OP_NOTIF was previously encountered.
123 ErrUnbalancedConditional
124 125 // Failures related to malleability.
126 127 // ErrMinimalData is returned when the ScriptVerifyMinimalData flag is set
128 // and the script contains push operations that do not use the minimal opcode
129 // required.
130 ErrMinimalData
131 // ErrInvalidSigHashType is returned when a signature hash type is not one of
132 // the supported types.
133 ErrInvalidSigHashType
134 // ErrSigTooShort is returned when a signature that should be a
135 // canonically-encoded DER signature is too short.
136 ErrSigTooShort
137 // ErrSigTooLong is returned when a signature that should be a
138 // canonically-encoded DER signature is too long.
139 ErrSigTooLong
140 // ErrSigInvalidSeqID is returned when a signature that should be a
141 // canonically-encoded DER signature does not have the expected ASN.1
142 // sequence ID.
143 ErrSigInvalidSeqID
144 // ErrSigInvalidDataLen is returned a signature that should be a
145 // canonically-encoded DER signature does not specify the correct number of
146 // remaining bytes for the R and S portions.
147 ErrSigInvalidDataLen
148 // ErrSigMissingSTypeID is returned a signature that should be a
149 // canonically-encoded DER signature does not provide the ASN.1 type ID for
150 // S.
151 ErrSigMissingSTypeID
152 // ErrSigMissingSLen is returned when a signature that should be a
153 // canonically-encoded DER signature does not provide the length of S.
154 ErrSigMissingSLen
155 // ErrSigInvalidSLen is returned a signature that should be a
156 // canonically-encoded DER signature does not specify the correct number of
157 // bytes for the S portion.
158 ErrSigInvalidSLen
159 // ErrSigInvalidRIntID is returned when a signature that should be a
160 // canonically-encoded DER signature does not have the expected ASN.1 integer
161 // ID for R.
162 ErrSigInvalidRIntID
163 // ErrSigZeroRLen is returned when a signature that should be a
164 // canonically-encoded DER signature has an R length of zero.
165 ErrSigZeroRLen
166 // ErrSigNegativeR is returned when a signature that should be a
167 // canonically-encoded DER signature has a negative value for R.
168 ErrSigNegativeR
169 // ErrSigTooMuchRPadding is returned when a signature that should be a
170 // canonically-encoded DER signature has too much padding for R.
171 ErrSigTooMuchRPadding
172 // ErrSigInvalidSIntID is returned when a signature that should be a
173 // canonically-encoded DER signature does not have the expected ASN.1 integer
174 // ID for S.
175 ErrSigInvalidSIntID
176 // ErrSigZeroSLen is returned when a signature that should be a
177 // canonically-encoded DER signature has an S length of zero.
178 ErrSigZeroSLen
179 // ErrSigNegativeS is returned when a signature that should be a
180 // canonically-encoded DER signature has a negative value for S.
181 ErrSigNegativeS
182 // ErrSigTooMuchSPadding is returned when a signature that should be a
183 // canonically-encoded DER signature has too much padding for S.
184 ErrSigTooMuchSPadding
185 // ErrSigHighS is returned when the ScriptVerifyLowS flag is set and the
186 // script contains any signatures whose S values are higher than the half
187 // order.
188 ErrSigHighS
189 // ErrNotPushOnly is returned when a script that is required to only push
190 // data to the stack performs other operations. A couple of cases where this
191 // applies is for a pay-to-script-hash signature script when bip16 is active
192 // and when the ScriptVerifySigPushOnly flag is set.
193 ErrNotPushOnly
194 // ErrSigNullDummy is returned when the ScriptStrictMultiSig flag is set and
195 // a multisig script has anything other than 0 for the extra dummy argument.
196 ErrSigNullDummy
197 // ErrPubKeyType is returned when the ScriptVerifyStrictEncoding flag is set
198 // and the script contains invalid public keys.
199 ErrPubKeyType
200 // ErrCleanStack is returned when the ScriptVerifyCleanStack flag is set, and
201 // after evalution, the stack does not contain only a single element.
202 ErrCleanStack
203 // ErrNullFail is returned when the ScriptVerifyNullFail flag is set and
204 // signatures are not empty on failed checksig or checkmultisig operations.
205 ErrNullFail
206 // ErrWitnessMalleated is returned if ScriptVerifyWitness is set and a native
207 // p2wsh program is encountered which has a non-empty sigScript.
208 ErrWitnessMalleated
209 // ErrWitnessMalleatedP2SH is returned if ScriptVerifyWitness if set and the
210 // validation logic for nested p2sh encounters a sigScript which isn't *exactyl*
211 // a datapush of the witness program.
212 ErrWitnessMalleatedP2SH
213 // Failures related to soft forks.
214 215 // ErrDiscourageUpgradableNOPs is returned when the
216 // ScriptDiscourageUpgradableNops flag is set and a NOP opcode is encountered
217 // in a script.
218 ErrDiscourageUpgradableNOPs
219 // ErrNegativeLockTime is returned when a script contains an opcode that
220 // interprets a negative lock time.
221 ErrNegativeLockTime
222 // ErrUnsatisfiedLockTime is returned when a script contains an opcode that
223 // involves a lock time and the required lock time has not been reached.
224 ErrUnsatisfiedLockTime
225 // ErrMinimalIf is returned if ScriptVerifyWitness is set and the operand of an
226 // OP_IF/OP_NOF_IF are not either an empty vector or [0x01].
227 ErrMinimalIf
228 // ErrDiscourageUpgradableWitnessProgram is returned if ScriptVerifyWitness is
229 // set and the versino of an executing witness program is outside the set of
230 // currently defined witness program vesions.
231 ErrDiscourageUpgradableWitnessProgram
232 // Failures related to segregated witness.
233 234 // ErrWitnessProgramEmpty is returned if ScriptVerifyWitness is set and the
235 // witness stack itself is empty.
236 ErrWitnessProgramEmpty
237 // ErrWitnessProgramMismatch is returned if ScriptVerifyWitness is set and the
238 // witness itself for a p2wkh witness program isn't *exactly* 2 items or if the
239 // witness for a p2wsh isn't the sha255 of the witness script.
240 ErrWitnessProgramMismatch
241 // ErrWitnessProgramWrongLength is returned if ScriptVerifyWitness is set and
242 // the length of the witness program violates the length as dictated by the
243 // current witness version.
244 ErrWitnessProgramWrongLength
245 // ErrWitnessUnexpected is returned if ScriptVerifyWitness is set and a
246 // transaction includes witness data but doesn't spend an which is a witness
247 // program (nested or native).
248 ErrWitnessUnexpected
249 // ErrWitnessPubKeyType is returned if ScriptVerifyWitness is set and the public
250 // key used in either a check-sig or check-multi-sig isn't serialized in a
251 // compressed format.
252 ErrWitnessPubKeyType
253 // numErrorCodes is the maximum error code number used in tests. This entry MUST
254 // be the last entry in the enum.
255 numErrorCodes
256 )
257 258 // Map of ErrorCode values back to their constant names for pretty printing.
259 var errorCodeStrings = map[ErrorCode]string{
260 ErrInternal: "ErrInternal",
261 ErrInvalidFlags: "ErrInvalidFlags",
262 ErrInvalidIndex: "ErrInvalidIndex",
263 ErrUnsupportedAddress: "ErrUnsupportedAddress",
264 ErrNotMultisigScript: "ErrNotMultisigScript",
265 ErrTooManyRequiredSigs: "ErrTooManyRequiredSigs",
266 ErrTooMuchNullData: "ErrTooMuchNullData",
267 ErrEarlyReturn: "ErrEarlyReturn",
268 ErrEmptyStack: "ErrEmptyStack",
269 ErrEvalFalse: "ErrEvalFalse",
270 ErrScriptUnfinished: "ErrScriptUnfinished",
271 ErrInvalidProgramCounter: "ErrInvalidProgramCounter",
272 ErrScriptTooBig: "ErrScriptTooBig",
273 ErrElementTooBig: "ErrElementTooBig",
274 ErrTooManyOperations: "ErrTooManyOperations",
275 ErrStackOverflow: "ErrStackOverflow",
276 ErrInvalidPubKeyCount: "ErrInvalidPubKeyCount",
277 ErrInvalidSignatureCount: "ErrInvalidSignatureCount",
278 ErrNumberTooBig: "ErrNumberTooBig",
279 ErrVerify: "ErrVerify",
280 ErrEqualVerify: "ErrEqualVerify",
281 ErrNumEqualVerify: "ErrNumEqualVerify",
282 ErrCheckSigVerify: "ErrCheckSigVerify",
283 ErrCheckMultiSigVerify: "ErrCheckMultiSigVerify",
284 ErrDisabledOpcode: "ErrDisabledOpcode",
285 ErrReservedOpcode: "ErrReservedOpcode",
286 ErrMalformedPush: "ErrMalformedPush",
287 ErrInvalidStackOperation: "ErrInvalidStackOperation",
288 ErrUnbalancedConditional: "ErrUnbalancedConditional",
289 ErrMinimalData: "ErrMinimalData",
290 ErrInvalidSigHashType: "ErrInvalidSigHashType",
291 ErrSigTooShort: "ErrSigTooShort",
292 ErrSigTooLong: "ErrSigTooLong",
293 ErrSigInvalidSeqID: "ErrSigInvalidSeqID",
294 ErrSigInvalidDataLen: "ErrSigInvalidDataLen",
295 ErrSigMissingSTypeID: "ErrSigMissingSTypeID",
296 ErrSigMissingSLen: "ErrSigMissingSLen",
297 ErrSigInvalidSLen: "ErrSigInvalidSLen",
298 ErrSigInvalidRIntID: "ErrSigInvalidRIntID",
299 ErrSigZeroRLen: "ErrSigZeroRLen",
300 ErrSigNegativeR: "ErrSigNegativeR",
301 ErrSigTooMuchRPadding: "ErrSigTooMuchRPadding",
302 ErrSigInvalidSIntID: "ErrSigInvalidSIntID",
303 ErrSigZeroSLen: "ErrSigZeroSLen",
304 ErrSigNegativeS: "ErrSigNegativeS",
305 ErrSigTooMuchSPadding: "ErrSigTooMuchSPadding",
306 ErrSigHighS: "ErrSigHighS",
307 ErrNotPushOnly: "ErrNotPushOnly",
308 ErrSigNullDummy: "ErrSigNullDummy",
309 ErrPubKeyType: "ErrPubKeyType",
310 ErrCleanStack: "ErrCleanStack",
311 ErrNullFail: "ErrNullFail",
312 ErrDiscourageUpgradableNOPs: "ErrDiscourageUpgradableNOPs",
313 ErrNegativeLockTime: "ErrNegativeLockTime",
314 ErrUnsatisfiedLockTime: "ErrUnsatisfiedLockTime",
315 ErrWitnessProgramEmpty: "ErrWitnessProgramEmpty",
316 ErrWitnessProgramMismatch: "ErrWitnessProgramMismatch",
317 ErrWitnessProgramWrongLength: "ErrWitnessProgramWrongLength",
318 ErrWitnessMalleated: "ErrWitnessMalleated",
319 ErrWitnessMalleatedP2SH: "ErrWitnessMalleatedP2SH",
320 ErrWitnessUnexpected: "ErrWitnessUnexpected",
321 ErrMinimalIf: "ErrMinimalIf",
322 ErrWitnessPubKeyType: "ErrWitnessPubKeyType",
323 ErrDiscourageUpgradableWitnessProgram: "ErrDiscourageUpgradableWitnessProgram",
324 }
325 326 // String returns the ErrorCode as a human-readable name.
327 func (e ErrorCode) String() string {
328 if s := errorCodeStrings[e]; s != "" {
329 return s
330 }
331 return fmt.Sprintf("Unknown ErrorCode (%d)", int(e))
332 }
333 334 // ScriptError identifies a script-related error. It is used to indicate three
335 // classes of errors:
336 //
337 // 1) Script execution failures due to violating one of the many requirements
338 // imposed by the script engine or evaluating to false
339 // 2) Improper API usage by callers
340 // 3) Internal consistency check failures
341 //
342 // The caller can use type assertions on the returned errors to access the
343 // ErrorCode field to ascertain the specific reason for the error. As an
344 // additional convenience, the caller may make use of the IsErrorCode function
345 // to check for a specific error code.
346 type ScriptError struct {
347 ErrorCode ErrorCode
348 Description string
349 }
350 351 // ScriptError satisfies the error interface and prints human-readable errors.
352 func (e ScriptError) Error() string {
353 return e.Description
354 }
355 356 // scriptError creates an ScriptError given a set of arguments.
357 func scriptError(c ErrorCode, desc string) ScriptError {
358 return ScriptError{ErrorCode: c, Description: desc}
359 }
360 361 // IsErrorCode returns whether or not the provided error is a script error with
362 // the provided error code.
363 func IsErrorCode(e error, c ErrorCode) bool {
364 serr, ok := e.(ScriptError)
365 return ok && serr.ErrorCode == c
366 }
367