2018-06-29 16:58:31 +00:00
|
|
|
// Copyright (c) 2013-2017 The btcsuite developers
|
|
|
|
|
// Copyright (c) 2015-2018 The Decred developers
|
2015-04-20 20:55:13 +00:00
|
|
|
// Use of this source code is governed by an ISC
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package txscript
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
)
|
|
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ErrorCode identifies a kind of script error.
|
|
|
|
|
type ErrorCode int
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// These constants are used to identify a specific Error.
|
|
|
|
|
const (
|
|
|
|
|
// ErrInternal is returned if internal consistency checks fail. In
|
|
|
|
|
// practice this error should never be seen as it would mean there is an
|
|
|
|
|
// error in the engine logic.
|
|
|
|
|
ErrInternal ErrorCode = iota
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ---------------------------------------
|
|
|
|
|
// Failures related to improper API usage.
|
|
|
|
|
// ---------------------------------------
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ErrInvalidIndex is returned when an out-of-bounds index is passed to
|
|
|
|
|
// a function.
|
|
|
|
|
ErrInvalidIndex
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ErrInvalidSigHashSingleIndex is returned when an attempt is
|
|
|
|
|
// made to sign an input with the SigHashSingle hash type and an
|
|
|
|
|
// index that is greater than or equal to the number of outputs.
|
|
|
|
|
ErrInvalidSigHashSingleIndex
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ErrUnsupportedAddress is returned when a concrete type that
|
|
|
|
|
// implements a dcrutil.Address is not a supported type.
|
|
|
|
|
ErrUnsupportedAddress
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ErrNotMultisigScript is returned from CalcMultiSigStats when the
|
|
|
|
|
// provided script is not a multisig script.
|
|
|
|
|
ErrNotMultisigScript
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ErrTooManyRequiredSigs is returned from MultiSigScript when the
|
|
|
|
|
// specified number of required signatures is larger than the number of
|
|
|
|
|
// provided public keys.
|
|
|
|
|
ErrTooManyRequiredSigs
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ErrMalformedCoinbaseNullData is returned when the nulldata output
|
|
|
|
|
// of a coinbase transaction that is used to ensure the coinbase has a
|
|
|
|
|
// unique hash is not properly formed.
|
|
|
|
|
ErrMalformedCoinbaseNullData
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ErrTooMuchNullData is returned from NullDataScript when the length of
|
|
|
|
|
// the provided data exceeds MaxDataCarrierSize.
|
|
|
|
|
ErrTooMuchNullData
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ------------------------------------------
|
|
|
|
|
// Failures related to final execution state.
|
|
|
|
|
// ------------------------------------------
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ErrEarlyReturn is returned when OP_RETURN is executed in the script.
|
|
|
|
|
ErrEarlyReturn
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ErrEmptyStack is returned when the script evaluated without error,
|
|
|
|
|
// but terminated with an empty top stack element.
|
|
|
|
|
ErrEmptyStack
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ErrEvalFalse is returned when the script evaluated without error but
|
|
|
|
|
// terminated with a false top stack element.
|
|
|
|
|
ErrEvalFalse
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ErrScriptUnfinished is returned when CheckErrorCondition is called on
|
|
|
|
|
// a script that has not finished executing.
|
|
|
|
|
ErrScriptUnfinished
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ErrScriptDone is returned when an attempt to execute an opcode is
|
|
|
|
|
// made once all of them have already been executed. This can happen
|
|
|
|
|
// due to things such as a second call to Execute or calling Step after
|
|
|
|
|
// all opcodes have already been executed.
|
|
|
|
|
ErrInvalidProgramCounter
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// -----------------------------------------------------
|
|
|
|
|
// Failures related to exceeding maximum allowed limits.
|
|
|
|
|
// -----------------------------------------------------
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ErrScriptTooBig is returned if a script is larger than MaxScriptSize.
|
|
|
|
|
ErrScriptTooBig
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ErrElementTooBig is returned if the size of an element to be pushed
|
|
|
|
|
// to the stack is over MaxScriptElementSize.
|
|
|
|
|
ErrElementTooBig
|
2015-04-20 20:55:13 +00:00
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// ErrTooManyOperations is returned if a script has more than
|
|
|
|
|
// MaxOpsPerScript opcodes that do not push data.
|
|
|
|
|
ErrTooManyOperations
|
2015-04-20 20:55:13 +00:00
|
|
|
|
|
|
|
|
// ErrStackOverflow is returned when stack and altstack combined depth
|
|
|
|
|
// is over the limit.
|
2018-06-29 16:58:31 +00:00
|
|
|
ErrStackOverflow
|
|
|
|
|
|
|
|
|
|
// ErrInvalidPubKeyCount is returned when the number of public keys
|
|
|
|
|
// specified for a multsig is either negative or greater than
|
|
|
|
|
// MaxPubKeysPerMultiSig.
|
|
|
|
|
ErrInvalidPubKeyCount
|
|
|
|
|
|
|
|
|
|
// ErrInvalidSignatureCount is returned when the number of signatures
|
|
|
|
|
// specified for a multisig is either negative or greater than the
|
|
|
|
|
// number of public keys.
|
|
|
|
|
ErrInvalidSignatureCount
|
|
|
|
|
|
|
|
|
|
// ErrNumOutOfRange is returned when the argument for an opcode that
|
|
|
|
|
// expects numeric input is larger than the expected maximum number of
|
|
|
|
|
// bytes. For the most part, opcodes that deal with stack manipulation
|
|
|
|
|
// via offsets, arithmetic, numeric comparison, and boolean logic are
|
|
|
|
|
// those that this applies to. However, any opcode that expects numeric
|
|
|
|
|
// input may fail with this code.
|
|
|
|
|
ErrNumOutOfRange
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------
|
|
|
|
|
// Failures related to verification operations.
|
|
|
|
|
// --------------------------------------------
|
|
|
|
|
|
|
|
|
|
// ErrVerify is returned when OP_VERIFY is encountered in a script and
|
|
|
|
|
// the top item on the data stack does not evaluate to true.
|
|
|
|
|
ErrVerify
|
|
|
|
|
|
|
|
|
|
// ErrEqualVerify is returned when OP_EQUALVERIFY is encountered in a
|
|
|
|
|
// script and the top item on the data stack does not evaluate to true.
|
|
|
|
|
ErrEqualVerify
|
|
|
|
|
|
|
|
|
|
// ErrNumEqualVerify is returned when OP_NUMEQUALVERIFY is encountered
|
|
|
|
|
// in a script and the top item on the data stack does not evaluate to
|
|
|
|
|
// true.
|
|
|
|
|
ErrNumEqualVerify
|
|
|
|
|
|
|
|
|
|
// ErrCheckSigVerify is returned when OP_CHECKSIGVERIFY is encountered
|
|
|
|
|
// in a script and the top item on the data stack does not evaluate to
|
|
|
|
|
// true.
|
|
|
|
|
ErrCheckSigVerify
|
|
|
|
|
|
|
|
|
|
// ErrCheckSigVerify is returned when OP_CHECKMULTISIGVERIFY is
|
|
|
|
|
// encountered in a script and the top item on the data stack does not
|
|
|
|
|
// evaluate to true.
|
|
|
|
|
ErrCheckMultiSigVerify
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------
|
|
|
|
|
// Failures related to improper use of opcodes.
|
|
|
|
|
// --------------------------------------------
|
|
|
|
|
|
|
|
|
|
// ErrP2SHStakeOpCodes is returned when one or more stake opcodes are
|
|
|
|
|
// found in the redeem script of a pay-to-script-hash script.
|
|
|
|
|
ErrP2SHStakeOpCodes
|
|
|
|
|
|
|
|
|
|
// ErrDisabledOpcode is returned when a disabled opcode is encountered
|
|
|
|
|
// in a script.
|
|
|
|
|
ErrDisabledOpcode
|
|
|
|
|
|
|
|
|
|
// ErrReservedOpcode is returned when an opcode marked as reserved
|
|
|
|
|
// is encountered in a script.
|
|
|
|
|
ErrReservedOpcode
|
|
|
|
|
|
|
|
|
|
// ErrMalformedPush is returned when a data push opcode tries to push
|
|
|
|
|
// more bytes than are left in the script.
|
|
|
|
|
ErrMalformedPush
|
|
|
|
|
|
|
|
|
|
// ErrInvalidStackOperation is returned when a stack operation is
|
|
|
|
|
// attempted with a number that is invalid for the current stack size.
|
|
|
|
|
ErrInvalidStackOperation
|
|
|
|
|
|
|
|
|
|
// ErrUnbalancedConditional is returned when an OP_ELSE or OP_ENDIF is
|
|
|
|
|
// encountered in a script without first having an OP_IF or OP_NOTIF or
|
|
|
|
|
// the end of script is reached without encountering an OP_ENDIF when
|
|
|
|
|
// an OP_IF or OP_NOTIF was previously encountered.
|
|
|
|
|
ErrUnbalancedConditional
|
|
|
|
|
|
|
|
|
|
// ErrNegativeSubstrIdx is returned when an OP_SUBSTR, OP_LEFT, or
|
|
|
|
|
// OP_RIGHT opcode encounters a negative index.
|
|
|
|
|
ErrNegativeSubstrIdx
|
|
|
|
|
|
|
|
|
|
// ErrOverflowSubstrIdx is returned when an OP_SUBSTR, OP_LEFT, or
|
|
|
|
|
// OP_RIGHT opcode encounters an index that is larger than the max
|
|
|
|
|
// allowed index that can operate on the string or the start index
|
|
|
|
|
// is greater than the end index for OP_SUBSTR.
|
|
|
|
|
ErrOverflowSubstrIdx
|
|
|
|
|
|
|
|
|
|
// ErrNegativeRotation is returned when an OP_ROTL or OP_ROTR attempts
|
|
|
|
|
// to perform a rotation with a negative rotation count.
|
|
|
|
|
ErrNegativeRotation
|
|
|
|
|
|
|
|
|
|
// ErrOverflowRotation is returned when an OP_ROTL or OP_ROTR opcode
|
|
|
|
|
// encounters a rotation count that is larger than the maximum allowed
|
|
|
|
|
// value for a uint32 bit rotation.
|
|
|
|
|
ErrOverflowRotation
|
|
|
|
|
|
|
|
|
|
// ErrDivideByZero is returned when an OP_DIV of OP_MOD attempts to
|
|
|
|
|
// divide by zero.
|
|
|
|
|
ErrDivideByZero
|
|
|
|
|
|
|
|
|
|
// ErrNegativeRotation is returned when an OP_LSHIFT or OP_RSHIFT opcode
|
|
|
|
|
// attempts to perform a shift with a negative count.
|
|
|
|
|
ErrNegativeShift
|
|
|
|
|
|
|
|
|
|
// ErrOverflowShift is returned when an OP_LSHIFT or OP_RSHIFT opcode
|
|
|
|
|
// encounters a shift count that is larger than the maximum allowed value
|
|
|
|
|
// for a shift.
|
|
|
|
|
ErrOverflowShift
|
|
|
|
|
|
|
|
|
|
// ---------------------------------
|
|
|
|
|
// Failures related to malleability.
|
|
|
|
|
// ---------------------------------
|
|
|
|
|
|
|
|
|
|
// ErrMinimalData is returned when the ScriptVerifyMinimalData flag
|
2015-04-20 20:55:13 +00:00
|
|
|
// is set and the script contains push operations that do not use
|
|
|
|
|
// the minimal opcode required.
|
2018-06-29 16:58:31 +00:00
|
|
|
ErrMinimalData
|
|
|
|
|
|
|
|
|
|
// ErrInvalidSigHashType is returned when a signature hash type is not
|
|
|
|
|
// one of the supported types.
|
|
|
|
|
ErrInvalidSigHashType
|
|
|
|
|
|
|
|
|
|
// ErrSigTooShort is returned when the ScriptVerifyDERSignatures flag is
|
|
|
|
|
// set and a signature that should be a canonically-encoded DER
|
|
|
|
|
// signature is too short.
|
|
|
|
|
ErrSigTooShort
|
|
|
|
|
|
|
|
|
|
// ErrSigTooLong is returned when the ScriptVerifyDERSignatures flag is
|
|
|
|
|
// set and a signature that should be a canonically-encoded DER
|
|
|
|
|
// signature is too long.
|
|
|
|
|
ErrSigTooLong
|
|
|
|
|
|
|
|
|
|
// ErrSigInvalidSeqID is returned when the ScriptVerifyDERSignatures
|
|
|
|
|
// flag is set and a signature that should be a canonically-encoded DER
|
|
|
|
|
// signature does not have the expected ASN.1 sequence ID.
|
|
|
|
|
ErrSigInvalidSeqID
|
|
|
|
|
|
|
|
|
|
// ErrSigInvalidDataLen is returned when the ScriptVerifyDERSignatures
|
|
|
|
|
// flag is set and a signature that should be a canonically-encoded DER
|
|
|
|
|
// signature does not specify the correct number of remaining bytes for
|
|
|
|
|
// the R and S portions.
|
|
|
|
|
ErrSigInvalidDataLen
|
|
|
|
|
|
|
|
|
|
// ErrSigMissingSTypeID is returned when the ScriptVerifyDERSignatures
|
|
|
|
|
// flag is set and a signature that should be a canonically-encoded DER
|
|
|
|
|
// signature does not provide the ASN.1 type ID for S.
|
|
|
|
|
ErrSigMissingSTypeID
|
|
|
|
|
|
|
|
|
|
// ErrSigMissingSLen is returned when the ScriptVerifyDERSignatures flag
|
|
|
|
|
// is set and a signature that should be a canonically-encoded DER
|
|
|
|
|
// signature does not provide the length of S.
|
|
|
|
|
ErrSigMissingSLen
|
|
|
|
|
|
|
|
|
|
// ErrSigInvalidSLen is returned when the ScriptVerifyDERSignatures flag
|
|
|
|
|
// is set and a signature that should be a canonically-encoded DER
|
|
|
|
|
// signature does not specify the correct number of bytes for the S
|
|
|
|
|
// portion.
|
|
|
|
|
ErrSigInvalidSLen
|
|
|
|
|
|
|
|
|
|
// ErrSigInvalidRIntID is returned when the ScriptVerifyDERSignatures
|
|
|
|
|
// flag is set and a signature that should be a canonically-encoded DER
|
|
|
|
|
// signature does not have the expected ASN.1 integer ID for R.
|
|
|
|
|
ErrSigInvalidRIntID
|
|
|
|
|
|
|
|
|
|
// ErrSigZeroRLen is returned when the ScriptVerifyDERSignatures flag is
|
|
|
|
|
// set and a signature that should be a canonically-encoded DER
|
|
|
|
|
// signature has an R length of zero.
|
|
|
|
|
ErrSigZeroRLen
|
|
|
|
|
|
|
|
|
|
// ErrSigNegativeR is returned when the ScriptVerifyDERSignatures flag
|
|
|
|
|
// is set and a signature that should be a canonically-encoded DER
|
|
|
|
|
// signature has a negative value for R.
|
|
|
|
|
ErrSigNegativeR
|
|
|
|
|
|
|
|
|
|
// ErrSigTooMuchRPadding is returned when the ScriptVerifyDERSignatures flag
|
|
|
|
|
// is set and a signature that should be a canonically-encoded DER
|
|
|
|
|
// signature has too much padding for R.
|
|
|
|
|
ErrSigTooMuchRPadding
|
|
|
|
|
|
|
|
|
|
// ErrSigInvalidSIntID is returned when the ScriptVerifyDERSignatures
|
|
|
|
|
// flag is set and a signature that should be a canonically-encoded DER
|
|
|
|
|
// signature does not have the expected ASN.1 integer ID for S.
|
|
|
|
|
ErrSigInvalidSIntID
|
|
|
|
|
|
|
|
|
|
// ErrSigZeroSLen is returned when the ScriptVerifyDERSignatures flag is
|
|
|
|
|
// set and a signature that should be a canonically-encoded DER
|
|
|
|
|
// signature has an S length of zero.
|
|
|
|
|
ErrSigZeroSLen
|
|
|
|
|
|
|
|
|
|
// ErrSigNegativeS is returned when the ScriptVerifyDERSignatures flag
|
|
|
|
|
// is set and a signature that should be a canonically-encoded DER
|
|
|
|
|
// signature has a negative value for S.
|
|
|
|
|
ErrSigNegativeS
|
|
|
|
|
|
|
|
|
|
// ErrSigTooMuchSPadding is returned when the ScriptVerifyDERSignatures flag
|
|
|
|
|
// is set and a signature that should be a canonically-encoded DER
|
|
|
|
|
// signature has too much padding for S.
|
|
|
|
|
ErrSigTooMuchSPadding
|
|
|
|
|
|
|
|
|
|
// ErrSigHighS is returned when the ScriptVerifyDERSignatures flag is
|
|
|
|
|
// set and a signature that should be a canonically-encoded DER signature
|
|
|
|
|
// has an S value that is higher than the curve half order.
|
|
|
|
|
ErrSigHighS
|
|
|
|
|
|
|
|
|
|
// ErrNotPushOnly is returned when a script that is required to only
|
|
|
|
|
// push data to the stack performs other operations. A couple of cases
|
|
|
|
|
// where this applies is for a pay-to-script-hash signature script when
|
|
|
|
|
// bip16 is active and when the ScriptVerifySigPushOnly flag is set.
|
|
|
|
|
ErrNotPushOnly
|
|
|
|
|
|
|
|
|
|
// ErrPubKeyType is returned when the ScriptVerifyStrictEncoding
|
|
|
|
|
// flag is set and the script contains invalid public keys.
|
|
|
|
|
ErrPubKeyType
|
|
|
|
|
|
|
|
|
|
// ErrCleanStack is returned when the ScriptVerifyCleanStack flag
|
|
|
|
|
// is set, and after evalution, the stack does not contain only a
|
|
|
|
|
// single element.
|
|
|
|
|
ErrCleanStack
|
|
|
|
|
|
|
|
|
|
// -------------------------------
|
|
|
|
|
// Failures related to soft forks.
|
|
|
|
|
// -------------------------------
|
|
|
|
|
|
|
|
|
|
// ErrDiscourageUpgradableNOPs is returned when the
|
|
|
|
|
// ScriptDiscourageUpgradableNops flag is set and a NOP opcode is
|
|
|
|
|
// encountered in a script.
|
|
|
|
|
ErrDiscourageUpgradableNOPs
|
|
|
|
|
|
|
|
|
|
// ErrNegativeLockTime is returned when a script contains an opcode that
|
|
|
|
|
// interprets a negative lock time.
|
|
|
|
|
ErrNegativeLockTime
|
|
|
|
|
|
|
|
|
|
// ErrUnsatisfiedLockTime is returned when a script contains an opcode
|
|
|
|
|
// that involves a lock time and the required lock time has not been
|
|
|
|
|
// reached.
|
|
|
|
|
ErrUnsatisfiedLockTime
|
|
|
|
|
|
|
|
|
|
// numErrorCodes is the maximum error code number used in tests. This
|
|
|
|
|
// entry MUST be the last entry in the enum.
|
|
|
|
|
numErrorCodes
|
2015-04-20 20:55:13 +00:00
|
|
|
)
|
|
|
|
|
|
2018-06-29 16:58:31 +00:00
|
|
|
// Map of ErrorCode values back to their constant names for pretty printing.
|
|
|
|
|
var errorCodeStrings = map[ErrorCode]string{
|
|
|
|
|
ErrInternal: "ErrInternal",
|
|
|
|
|
ErrInvalidIndex: "ErrInvalidIndex",
|
|
|
|
|
ErrInvalidSigHashSingleIndex: "ErrInvalidSigHashSingleIndex",
|
|
|
|
|
ErrUnsupportedAddress: "ErrUnsupportedAddress",
|
|
|
|
|
ErrNotMultisigScript: "ErrNotMultisigScript",
|
|
|
|
|
ErrTooManyRequiredSigs: "ErrTooManyRequiredSigs",
|
|
|
|
|
ErrMalformedCoinbaseNullData: "ErrMalformedCoinbaseNullData",
|
|
|
|
|
ErrTooMuchNullData: "ErrTooMuchNullData",
|
|
|
|
|
ErrEarlyReturn: "ErrEarlyReturn",
|
|
|
|
|
ErrEmptyStack: "ErrEmptyStack",
|
|
|
|
|
ErrEvalFalse: "ErrEvalFalse",
|
|
|
|
|
ErrScriptUnfinished: "ErrScriptUnfinished",
|
|
|
|
|
ErrInvalidProgramCounter: "ErrInvalidProgramCounter",
|
|
|
|
|
ErrScriptTooBig: "ErrScriptTooBig",
|
|
|
|
|
ErrElementTooBig: "ErrElementTooBig",
|
|
|
|
|
ErrTooManyOperations: "ErrTooManyOperations",
|
|
|
|
|
ErrStackOverflow: "ErrStackOverflow",
|
|
|
|
|
ErrInvalidPubKeyCount: "ErrInvalidPubKeyCount",
|
|
|
|
|
ErrInvalidSignatureCount: "ErrInvalidSignatureCount",
|
|
|
|
|
ErrNumOutOfRange: "ErrNumOutOfRange",
|
|
|
|
|
ErrVerify: "ErrVerify",
|
|
|
|
|
ErrEqualVerify: "ErrEqualVerify",
|
|
|
|
|
ErrNumEqualVerify: "ErrNumEqualVerify",
|
|
|
|
|
ErrCheckSigVerify: "ErrCheckSigVerify",
|
|
|
|
|
ErrCheckMultiSigVerify: "ErrCheckMultiSigVerify",
|
|
|
|
|
ErrP2SHStakeOpCodes: "ErrP2SHStakeOpCodes",
|
|
|
|
|
ErrDisabledOpcode: "ErrDisabledOpcode",
|
|
|
|
|
ErrReservedOpcode: "ErrReservedOpcode",
|
|
|
|
|
ErrMalformedPush: "ErrMalformedPush",
|
|
|
|
|
ErrInvalidStackOperation: "ErrInvalidStackOperation",
|
|
|
|
|
ErrUnbalancedConditional: "ErrUnbalancedConditional",
|
|
|
|
|
ErrNegativeSubstrIdx: "ErrNegativeSubstrIdx",
|
|
|
|
|
ErrSigTooMuchSPadding: "ErrSigTooMuchSPadding",
|
|
|
|
|
ErrOverflowSubstrIdx: "ErrOverflowSubstrIdx",
|
|
|
|
|
ErrNegativeRotation: "ErrNegativeRotation",
|
|
|
|
|
ErrOverflowRotation: "ErrOverflowRotation",
|
|
|
|
|
ErrDivideByZero: "ErrDivideByZero",
|
|
|
|
|
ErrNegativeShift: "ErrNegativeShift",
|
|
|
|
|
ErrOverflowShift: "ErrOverflowShift",
|
|
|
|
|
ErrMinimalData: "ErrMinimalData",
|
|
|
|
|
ErrInvalidSigHashType: "ErrInvalidSigHashType",
|
|
|
|
|
ErrSigTooShort: "ErrSigTooShort",
|
|
|
|
|
ErrSigTooLong: "ErrSigTooLong",
|
|
|
|
|
ErrSigInvalidSeqID: "ErrSigInvalidSeqID",
|
|
|
|
|
ErrSigInvalidDataLen: "ErrSigInvalidDataLen",
|
|
|
|
|
ErrSigMissingSTypeID: "ErrSigMissingSTypeID",
|
|
|
|
|
ErrSigMissingSLen: "ErrSigMissingSLen",
|
|
|
|
|
ErrSigInvalidSLen: "ErrSigInvalidSLen",
|
|
|
|
|
ErrSigInvalidRIntID: "ErrSigInvalidRIntID",
|
|
|
|
|
ErrSigZeroRLen: "ErrSigZeroRLen",
|
|
|
|
|
ErrSigNegativeR: "ErrSigNegativeR",
|
|
|
|
|
ErrSigTooMuchRPadding: "ErrSigTooMuchRPadding",
|
|
|
|
|
ErrSigInvalidSIntID: "ErrSigInvalidSIntID",
|
|
|
|
|
ErrSigZeroSLen: "ErrSigZeroSLen",
|
|
|
|
|
ErrSigNegativeS: "ErrSigNegativeS",
|
|
|
|
|
ErrSigHighS: "ErrSigHighS",
|
|
|
|
|
ErrNotPushOnly: "ErrNotPushOnly",
|
|
|
|
|
ErrPubKeyType: "ErrPubKeyType",
|
|
|
|
|
ErrCleanStack: "ErrCleanStack",
|
|
|
|
|
ErrDiscourageUpgradableNOPs: "ErrDiscourageUpgradableNOPs",
|
|
|
|
|
ErrNegativeLockTime: "ErrNegativeLockTime",
|
|
|
|
|
ErrUnsatisfiedLockTime: "ErrUnsatisfiedLockTime",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// String returns the ErrorCode as a human-readable name.
|
|
|
|
|
func (e ErrorCode) String() string {
|
|
|
|
|
if s := errorCodeStrings[e]; s != "" {
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
return fmt.Sprintf("Unknown ErrorCode (%d)", int(e))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Error identifies a script-related error. It is used to indicate three
|
|
|
|
|
// classes of errors:
|
|
|
|
|
// 1) Script execution failures due to violating one of the many requirements
|
|
|
|
|
// imposed by the script engine or evaluating to false
|
|
|
|
|
// 2) Improper API usage by callers
|
|
|
|
|
// 3) Internal consistency check failures
|
|
|
|
|
//
|
|
|
|
|
// The caller can use type assertions on the returned errors to access the
|
|
|
|
|
// ErrorCode field to ascertain the specific reason for the error. As an
|
|
|
|
|
// additional convenience, the caller may make use of the IsErrorCode function
|
|
|
|
|
// to check for a specific error code.
|
|
|
|
|
type Error struct {
|
|
|
|
|
ErrorCode ErrorCode
|
|
|
|
|
Description string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Error satisfies the error interface and prints human-readable errors.
|
|
|
|
|
func (e Error) Error() string {
|
|
|
|
|
return e.Description
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// scriptError creates an Error given a set of arguments.
|
|
|
|
|
func scriptError(c ErrorCode, desc string) Error {
|
|
|
|
|
return Error{ErrorCode: c, Description: desc}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// IsErrorCode returns whether or not the provided error is a script error with
|
|
|
|
|
// the provided error code.
|
|
|
|
|
func IsErrorCode(err error, c ErrorCode) bool {
|
|
|
|
|
serr, ok := err.(Error)
|
|
|
|
|
return ok && serr.ErrorCode == c
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// IsDERSigError returns whether or not the provided error is a script error
|
|
|
|
|
// with one of the error codes which are caused due to encountering a signature
|
|
|
|
|
// that is not a canonically-encoded DER signature.
|
|
|
|
|
//
|
|
|
|
|
// Note that the strict DER signature checks are only performed if scripts
|
|
|
|
|
// are executed with the ScriptVerifyDERSignatures flag.
|
|
|
|
|
func IsDERSigError(err error) bool {
|
|
|
|
|
serr, ok := err.(Error)
|
|
|
|
|
if !ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch serr.ErrorCode {
|
|
|
|
|
case ErrSigTooShort, ErrSigTooLong, ErrSigInvalidSeqID,
|
|
|
|
|
ErrSigInvalidDataLen, ErrSigMissingSTypeID, ErrSigMissingSLen,
|
|
|
|
|
ErrSigInvalidSLen, ErrSigInvalidRIntID, ErrSigZeroRLen, ErrSigNegativeR,
|
|
|
|
|
ErrSigTooMuchRPadding, ErrSigInvalidSIntID, ErrSigZeroSLen,
|
|
|
|
|
ErrSigNegativeS, ErrSigTooMuchSPadding, ErrSigHighS:
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
}
|