OSDN Git Service

Thanos did someting
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / txscript / standard.go
diff --git a/vendor/github.com/btcsuite/btcd/txscript/standard.go b/vendor/github.com/btcsuite/btcd/txscript/standard.go
deleted file mode 100644 (file)
index 4c31506..0000000
+++ /dev/null
@@ -1,625 +0,0 @@
-// Copyright (c) 2013-2017 The btcsuite developers
-// Use of this source code is governed by an ISC
-// license that can be found in the LICENSE file.
-
-package txscript
-
-import (
-       "fmt"
-
-       "github.com/btcsuite/btcd/chaincfg"
-       "github.com/btcsuite/btcd/wire"
-       "github.com/btcsuite/btcutil"
-)
-
-const (
-       // MaxDataCarrierSize is the maximum number of bytes allowed in pushed
-       // data to be considered a nulldata transaction
-       MaxDataCarrierSize = 80
-
-       // StandardVerifyFlags are the script flags which are used when
-       // executing transaction scripts to enforce additional checks which
-       // are required for the script to be considered standard.  These checks
-       // help reduce issues related to transaction malleability as well as
-       // allow pay-to-script hash transactions.  Note these flags are
-       // different than what is required for the consensus rules in that they
-       // are more strict.
-       //
-       // TODO: This definition does not belong here.  It belongs in a policy
-       // package.
-       StandardVerifyFlags = ScriptBip16 |
-               ScriptVerifyDERSignatures |
-               ScriptVerifyStrictEncoding |
-               ScriptVerifyMinimalData |
-               ScriptStrictMultiSig |
-               ScriptDiscourageUpgradableNops |
-               ScriptVerifyCleanStack |
-               ScriptVerifyNullFail |
-               ScriptVerifyCheckLockTimeVerify |
-               ScriptVerifyCheckSequenceVerify |
-               ScriptVerifyLowS |
-               ScriptStrictMultiSig |
-               ScriptVerifyWitness |
-               ScriptVerifyDiscourageUpgradeableWitnessProgram |
-               ScriptVerifyMinimalIf |
-               ScriptVerifyWitnessPubKeyType
-)
-
-// ScriptClass is an enumeration for the list of standard types of script.
-type ScriptClass byte
-
-// Classes of script payment known about in the blockchain.
-const (
-       NonStandardTy         ScriptClass = iota // None of the recognized forms.
-       PubKeyTy                                 // Pay pubkey.
-       PubKeyHashTy                             // Pay pubkey hash.
-       WitnessV0PubKeyHashTy                    // Pay witness pubkey hash.
-       ScriptHashTy                             // Pay to script hash.
-       WitnessV0ScriptHashTy                    // Pay to witness script hash.
-       MultiSigTy                               // Multi signature.
-       NullDataTy                               // Empty data-only (provably prunable).
-)
-
-// scriptClassToName houses the human-readable strings which describe each
-// script class.
-var scriptClassToName = []string{
-       NonStandardTy:         "nonstandard",
-       PubKeyTy:              "pubkey",
-       PubKeyHashTy:          "pubkeyhash",
-       WitnessV0PubKeyHashTy: "witness_v0_keyhash",
-       ScriptHashTy:          "scripthash",
-       WitnessV0ScriptHashTy: "witness_v0_scripthash",
-       MultiSigTy:            "multisig",
-       NullDataTy:            "nulldata",
-}
-
-// String implements the Stringer interface by returning the name of
-// the enum script class. If the enum is invalid then "Invalid" will be
-// returned.
-func (t ScriptClass) String() string {
-       if int(t) > len(scriptClassToName) || int(t) < 0 {
-               return "Invalid"
-       }
-       return scriptClassToName[t]
-}
-
-// isPubkey returns true if the script passed is a pay-to-pubkey transaction,
-// false otherwise.
-func isPubkey(pops []parsedOpcode) bool {
-       // Valid pubkeys are either 33 or 65 bytes.
-       return len(pops) == 2 &&
-               (len(pops[0].data) == 33 || len(pops[0].data) == 65) &&
-               pops[1].opcode.value == OP_CHECKSIG
-}
-
-// isPubkeyHash returns true if the script passed is a pay-to-pubkey-hash
-// transaction, false otherwise.
-func isPubkeyHash(pops []parsedOpcode) bool {
-       return len(pops) == 5 &&
-               pops[0].opcode.value == OP_DUP &&
-               pops[1].opcode.value == OP_HASH160 &&
-               pops[2].opcode.value == OP_DATA_20 &&
-               pops[3].opcode.value == OP_EQUALVERIFY &&
-               pops[4].opcode.value == OP_CHECKSIG
-
-}
-
-// isMultiSig returns true if the passed script is a multisig transaction, false
-// otherwise.
-func isMultiSig(pops []parsedOpcode) bool {
-       // The absolute minimum is 1 pubkey:
-       // OP_0/OP_1-16 <pubkey> OP_1 OP_CHECKMULTISIG
-       l := len(pops)
-       if l < 4 {
-               return false
-       }
-       if !isSmallInt(pops[0].opcode) {
-               return false
-       }
-       if !isSmallInt(pops[l-2].opcode) {
-               return false
-       }
-       if pops[l-1].opcode.value != OP_CHECKMULTISIG {
-               return false
-       }
-
-       // Verify the number of pubkeys specified matches the actual number
-       // of pubkeys provided.
-       if l-2-1 != asSmallInt(pops[l-2].opcode) {
-               return false
-       }
-
-       for _, pop := range pops[1 : l-2] {
-               // Valid pubkeys are either 33 or 65 bytes.
-               if len(pop.data) != 33 && len(pop.data) != 65 {
-                       return false
-               }
-       }
-       return true
-}
-
-// isNullData returns true if the passed script is a null data transaction,
-// false otherwise.
-func isNullData(pops []parsedOpcode) bool {
-       // A nulldata transaction is either a single OP_RETURN or an
-       // OP_RETURN SMALLDATA (where SMALLDATA is a data push up to
-       // MaxDataCarrierSize bytes).
-       l := len(pops)
-       if l == 1 && pops[0].opcode.value == OP_RETURN {
-               return true
-       }
-
-       return l == 2 &&
-               pops[0].opcode.value == OP_RETURN &&
-               (isSmallInt(pops[1].opcode) || pops[1].opcode.value <=
-                       OP_PUSHDATA4) &&
-               len(pops[1].data) <= MaxDataCarrierSize
-}
-
-// scriptType returns the type of the script being inspected from the known
-// standard types.
-func typeOfScript(pops []parsedOpcode) ScriptClass {
-       if isPubkey(pops) {
-               return PubKeyTy
-       } else if isPubkeyHash(pops) {
-               return PubKeyHashTy
-       } else if isWitnessPubKeyHash(pops) {
-               return WitnessV0PubKeyHashTy
-       } else if isScriptHash(pops) {
-               return ScriptHashTy
-       } else if isWitnessScriptHash(pops) {
-               return WitnessV0ScriptHashTy
-       } else if isMultiSig(pops) {
-               return MultiSigTy
-       } else if isNullData(pops) {
-               return NullDataTy
-       }
-       return NonStandardTy
-}
-
-// GetScriptClass returns the class of the script passed.
-//
-// NonStandardTy will be returned when the script does not parse.
-func GetScriptClass(script []byte) ScriptClass {
-       pops, err := parseScript(script)
-       if err != nil {
-               return NonStandardTy
-       }
-       return typeOfScript(pops)
-}
-
-// expectedInputs returns the number of arguments required by a script.
-// If the script is of unknown type such that the number can not be determined
-// then -1 is returned. We are an internal function and thus assume that class
-// is the real class of pops (and we can thus assume things that were determined
-// while finding out the type).
-func expectedInputs(pops []parsedOpcode, class ScriptClass) int {
-       switch class {
-       case PubKeyTy:
-               return 1
-
-       case PubKeyHashTy:
-               return 2
-
-       case WitnessV0PubKeyHashTy:
-               return 2
-
-       case ScriptHashTy:
-               // Not including script.  That is handled by the caller.
-               return 1
-
-       case WitnessV0ScriptHashTy:
-               // Not including script.  That is handled by the caller.
-               return 1
-
-       case MultiSigTy:
-               // Standard multisig has a push a small number for the number
-               // of sigs and number of keys.  Check the first push instruction
-               // to see how many arguments are expected. typeOfScript already
-               // checked this so we know it'll be a small int.  Also, due to
-               // the original bitcoind bug where OP_CHECKMULTISIG pops an
-               // additional item from the stack, add an extra expected input
-               // for the extra push that is required to compensate.
-               return asSmallInt(pops[0].opcode) + 1
-
-       case NullDataTy:
-               fallthrough
-       default:
-               return -1
-       }
-}
-
-// ScriptInfo houses information about a script pair that is determined by
-// CalcScriptInfo.
-type ScriptInfo struct {
-       // PkScriptClass is the class of the public key script and is equivalent
-       // to calling GetScriptClass on it.
-       PkScriptClass ScriptClass
-
-       // NumInputs is the number of inputs provided by the public key script.
-       NumInputs int
-
-       // ExpectedInputs is the number of outputs required by the signature
-       // script and any pay-to-script-hash scripts. The number will be -1 if
-       // unknown.
-       ExpectedInputs int
-
-       // SigOps is the number of signature operations in the script pair.
-       SigOps int
-}
-
-// CalcScriptInfo returns a structure providing data about the provided script
-// pair.  It will error if the pair is in someway invalid such that they can not
-// be analysed, i.e. if they do not parse or the pkScript is not a push-only
-// script
-func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness,
-       bip16, segwit bool) (*ScriptInfo, error) {
-
-       sigPops, err := parseScript(sigScript)
-       if err != nil {
-               return nil, err
-       }
-
-       pkPops, err := parseScript(pkScript)
-       if err != nil {
-               return nil, err
-       }
-
-       // Push only sigScript makes little sense.
-       si := new(ScriptInfo)
-       si.PkScriptClass = typeOfScript(pkPops)
-
-       // Can't have a signature script that doesn't just push data.
-       if !isPushOnly(sigPops) {
-               return nil, scriptError(ErrNotPushOnly,
-                       "signature script is not push only")
-       }
-
-       si.ExpectedInputs = expectedInputs(pkPops, si.PkScriptClass)
-
-       switch {
-       // Count sigops taking into account pay-to-script-hash.
-       case si.PkScriptClass == ScriptHashTy && bip16 && !segwit:
-               // The pay-to-hash-script is the final data push of the
-               // signature script.
-               script := sigPops[len(sigPops)-1].data
-               shPops, err := parseScript(script)
-               if err != nil {
-                       return nil, err
-               }
-
-               shInputs := expectedInputs(shPops, typeOfScript(shPops))
-               if shInputs == -1 {
-                       si.ExpectedInputs = -1
-               } else {
-                       si.ExpectedInputs += shInputs
-               }
-               si.SigOps = getSigOpCount(shPops, true)
-
-               // All entries pushed to stack (or are OP_RESERVED and exec
-               // will fail).
-               si.NumInputs = len(sigPops)
-
-       // If segwit is active, and this is a regular p2wkh output, then we'll
-       // treat the script as a p2pkh output in essence.
-       case si.PkScriptClass == WitnessV0PubKeyHashTy && segwit:
-
-               si.SigOps = GetWitnessSigOpCount(sigScript, pkScript, witness)
-               si.NumInputs = len(witness)
-
-       // We'll attempt to detect the nested p2sh case so we can accurately
-       // count the signature operations involved.
-       case si.PkScriptClass == ScriptHashTy &&
-               IsWitnessProgram(sigScript[1:]) && bip16 && segwit:
-
-               // Extract the pushed witness program from the sigScript so we
-               // can determine the number of expected inputs.
-               pkPops, _ := parseScript(sigScript[1:])
-               shInputs := expectedInputs(pkPops, typeOfScript(pkPops))
-               if shInputs == -1 {
-                       si.ExpectedInputs = -1
-               } else {
-                       si.ExpectedInputs += shInputs
-               }
-
-               si.SigOps = GetWitnessSigOpCount(sigScript, pkScript, witness)
-
-               si.NumInputs = len(witness)
-               si.NumInputs += len(sigPops)
-
-       // If segwit is active, and this is a p2wsh output, then we'll need to
-       // examine the witness script to generate accurate script info.
-       case si.PkScriptClass == WitnessV0ScriptHashTy && segwit:
-               // The witness script is the final element of the witness
-               // stack.
-               witnessScript := witness[len(witness)-1]
-               pops, _ := parseScript(witnessScript)
-
-               shInputs := expectedInputs(pops, typeOfScript(pops))
-               if shInputs == -1 {
-                       si.ExpectedInputs = -1
-               } else {
-                       si.ExpectedInputs += shInputs
-               }
-
-               si.SigOps = GetWitnessSigOpCount(sigScript, pkScript, witness)
-               si.NumInputs = len(witness)
-
-       default:
-               si.SigOps = getSigOpCount(pkPops, true)
-
-               // All entries pushed to stack (or are OP_RESERVED and exec
-               // will fail).
-               si.NumInputs = len(sigPops)
-       }
-
-       return si, nil
-}
-
-// CalcMultiSigStats returns the number of public keys and signatures from
-// a multi-signature transaction script.  The passed script MUST already be
-// known to be a multi-signature script.
-func CalcMultiSigStats(script []byte) (int, int, error) {
-       pops, err := parseScript(script)
-       if err != nil {
-               return 0, 0, err
-       }
-
-       // A multi-signature script is of the pattern:
-       //  NUM_SIGS PUBKEY PUBKEY PUBKEY... NUM_PUBKEYS OP_CHECKMULTISIG
-       // Therefore the number of signatures is the oldest item on the stack
-       // and the number of pubkeys is the 2nd to last.  Also, the absolute
-       // minimum for a multi-signature script is 1 pubkey, so at least 4
-       // items must be on the stack per:
-       //  OP_1 PUBKEY OP_1 OP_CHECKMULTISIG
-       if len(pops) < 4 {
-               str := fmt.Sprintf("script %x is not a multisig script", script)
-               return 0, 0, scriptError(ErrNotMultisigScript, str)
-       }
-
-       numSigs := asSmallInt(pops[0].opcode)
-       numPubKeys := asSmallInt(pops[len(pops)-2].opcode)
-       return numPubKeys, numSigs, nil
-}
-
-// payToPubKeyHashScript creates a new script to pay a transaction
-// output to a 20-byte pubkey hash. It is expected that the input is a valid
-// hash.
-func payToPubKeyHashScript(pubKeyHash []byte) ([]byte, error) {
-       return NewScriptBuilder().AddOp(OP_DUP).AddOp(OP_HASH160).
-               AddData(pubKeyHash).AddOp(OP_EQUALVERIFY).AddOp(OP_CHECKSIG).
-               Script()
-}
-
-// payToWitnessPubKeyHashScript creates a new script to pay to a version 0
-// pubkey hash witness program. The passed hash is expected to be valid.
-func payToWitnessPubKeyHashScript(pubKeyHash []byte) ([]byte, error) {
-       return NewScriptBuilder().AddOp(OP_0).AddData(pubKeyHash).Script()
-}
-
-// payToScriptHashScript creates a new script to pay a transaction output to a
-// script hash. It is expected that the input is a valid hash.
-func payToScriptHashScript(scriptHash []byte) ([]byte, error) {
-       return NewScriptBuilder().AddOp(OP_HASH160).AddData(scriptHash).
-               AddOp(OP_EQUAL).Script()
-}
-
-// payToWitnessPubKeyHashScript creates a new script to pay to a version 0
-// script hash witness program. The passed hash is expected to be valid.
-func payToWitnessScriptHashScript(scriptHash []byte) ([]byte, error) {
-       return NewScriptBuilder().AddOp(OP_0).AddData(scriptHash).Script()
-}
-
-// payToPubkeyScript creates a new script to pay a transaction output to a
-// public key. It is expected that the input is a valid pubkey.
-func payToPubKeyScript(serializedPubKey []byte) ([]byte, error) {
-       return NewScriptBuilder().AddData(serializedPubKey).
-               AddOp(OP_CHECKSIG).Script()
-}
-
-// PayToAddrScript creates a new script to pay a transaction output to a the
-// specified address.
-func PayToAddrScript(addr btcutil.Address) ([]byte, error) {
-       const nilAddrErrStr = "unable to generate payment script for nil address"
-
-       switch addr := addr.(type) {
-       case *btcutil.AddressPubKeyHash:
-               if addr == nil {
-                       return nil, scriptError(ErrUnsupportedAddress,
-                               nilAddrErrStr)
-               }
-               return payToPubKeyHashScript(addr.ScriptAddress())
-
-       case *btcutil.AddressScriptHash:
-               if addr == nil {
-                       return nil, scriptError(ErrUnsupportedAddress,
-                               nilAddrErrStr)
-               }
-               return payToScriptHashScript(addr.ScriptAddress())
-
-       case *btcutil.AddressPubKey:
-               if addr == nil {
-                       return nil, scriptError(ErrUnsupportedAddress,
-                               nilAddrErrStr)
-               }
-               return payToPubKeyScript(addr.ScriptAddress())
-
-       case *btcutil.AddressWitnessPubKeyHash:
-               if addr == nil {
-                       return nil, scriptError(ErrUnsupportedAddress,
-                               nilAddrErrStr)
-               }
-               return payToWitnessPubKeyHashScript(addr.ScriptAddress())
-       case *btcutil.AddressWitnessScriptHash:
-               if addr == nil {
-                       return nil, scriptError(ErrUnsupportedAddress,
-                               nilAddrErrStr)
-               }
-               return payToWitnessScriptHashScript(addr.ScriptAddress())
-       }
-
-       str := fmt.Sprintf("unable to generate payment script for unsupported "+
-               "address type %T", addr)
-       return nil, scriptError(ErrUnsupportedAddress, str)
-}
-
-// NullDataScript creates a provably-prunable script containing OP_RETURN
-// followed by the passed data.  An Error with the error code ErrTooMuchNullData
-// will be returned if the length of the passed data exceeds MaxDataCarrierSize.
-func NullDataScript(data []byte) ([]byte, error) {
-       if len(data) > MaxDataCarrierSize {
-               str := fmt.Sprintf("data size %d is larger than max "+
-                       "allowed size %d", len(data), MaxDataCarrierSize)
-               return nil, scriptError(ErrTooMuchNullData, str)
-       }
-
-       return NewScriptBuilder().AddOp(OP_RETURN).AddData(data).Script()
-}
-
-// MultiSigScript returns a valid script for a multisignature redemption where
-// nrequired of the keys in pubkeys are required to have signed the transaction
-// for success.  An Error with the error code ErrTooManyRequiredSigs will be
-// returned if nrequired is larger than the number of keys provided.
-func MultiSigScript(pubkeys []*btcutil.AddressPubKey, nrequired int) ([]byte, error) {
-       if len(pubkeys) < nrequired {
-               str := fmt.Sprintf("unable to generate multisig script with "+
-                       "%d required signatures when there are only %d public "+
-                       "keys available", nrequired, len(pubkeys))
-               return nil, scriptError(ErrTooManyRequiredSigs, str)
-       }
-
-       builder := NewScriptBuilder().AddInt64(int64(nrequired))
-       for _, key := range pubkeys {
-               builder.AddData(key.ScriptAddress())
-       }
-       builder.AddInt64(int64(len(pubkeys)))
-       builder.AddOp(OP_CHECKMULTISIG)
-
-       return builder.Script()
-}
-
-// PushedData returns an array of byte slices containing any pushed data found
-// in the passed script.  This includes OP_0, but not OP_1 - OP_16.
-func PushedData(script []byte) ([][]byte, error) {
-       pops, err := parseScript(script)
-       if err != nil {
-               return nil, err
-       }
-
-       var data [][]byte
-       for _, pop := range pops {
-               if pop.data != nil {
-                       data = append(data, pop.data)
-               } else if pop.opcode.value == OP_0 {
-                       data = append(data, nil)
-               }
-       }
-       return data, nil
-}
-
-// ExtractPkScriptAddrs returns the type of script, addresses and required
-// signatures associated with the passed PkScript.  Note that it only works for
-// 'standard' transaction script types.  Any data such as public keys which are
-// invalid are omitted from the results.
-func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (ScriptClass, []btcutil.Address, int, error) {
-       var addrs []btcutil.Address
-       var requiredSigs int
-
-       // No valid addresses or required signatures if the script doesn't
-       // parse.
-       pops, err := parseScript(pkScript)
-       if err != nil {
-               return NonStandardTy, nil, 0, err
-       }
-
-       scriptClass := typeOfScript(pops)
-       switch scriptClass {
-       case PubKeyHashTy:
-               // A pay-to-pubkey-hash script is of the form:
-               //  OP_DUP OP_HASH160 <hash> OP_EQUALVERIFY OP_CHECKSIG
-               // Therefore the pubkey hash is the 3rd item on the stack.
-               // Skip the pubkey hash if it's invalid for some reason.
-               requiredSigs = 1
-               addr, err := btcutil.NewAddressPubKeyHash(pops[2].data,
-                       chainParams)
-               if err == nil {
-                       addrs = append(addrs, addr)
-               }
-
-       case WitnessV0PubKeyHashTy:
-               // A pay-to-witness-pubkey-hash script is of thw form:
-               //  OP_0 <20-byte hash>
-               // Therefore, the pubkey hash is the second item on the stack.
-               // Skip the pubkey hash if it's invalid for some reason.
-               requiredSigs = 1
-               addr, err := btcutil.NewAddressWitnessPubKeyHash(pops[1].data,
-                       chainParams)
-               if err == nil {
-                       addrs = append(addrs, addr)
-               }
-
-       case PubKeyTy:
-               // A pay-to-pubkey script is of the form:
-               //  <pubkey> OP_CHECKSIG
-               // Therefore the pubkey is the first item on the stack.
-               // Skip the pubkey if it's invalid for some reason.
-               requiredSigs = 1
-               addr, err := btcutil.NewAddressPubKey(pops[0].data, chainParams)
-               if err == nil {
-                       addrs = append(addrs, addr)
-               }
-
-       case ScriptHashTy:
-               // A pay-to-script-hash script is of the form:
-               //  OP_HASH160 <scripthash> OP_EQUAL
-               // Therefore the script hash is the 2nd item on the stack.
-               // Skip the script hash if it's invalid for some reason.
-               requiredSigs = 1
-               addr, err := btcutil.NewAddressScriptHashFromHash(pops[1].data,
-                       chainParams)
-               if err == nil {
-                       addrs = append(addrs, addr)
-               }
-
-       case WitnessV0ScriptHashTy:
-               // A pay-to-witness-script-hash script is of the form:
-               //  OP_0 <32-byte hash>
-               // Therefore, the script hash is the second item on the stack.
-               // Skip the script hash if it's invalid for some reason.
-               requiredSigs = 1
-               addr, err := btcutil.NewAddressWitnessScriptHash(pops[1].data,
-                       chainParams)
-               if err == nil {
-                       addrs = append(addrs, addr)
-               }
-
-       case MultiSigTy:
-               // A multi-signature script is of the form:
-               //  <numsigs> <pubkey> <pubkey> <pubkey>... <numpubkeys> OP_CHECKMULTISIG
-               // Therefore the number of required signatures is the 1st item
-               // on the stack and the number of public keys is the 2nd to last
-               // item on the stack.
-               requiredSigs = asSmallInt(pops[0].opcode)
-               numPubKeys := asSmallInt(pops[len(pops)-2].opcode)
-
-               // Extract the public keys while skipping any that are invalid.
-               addrs = make([]btcutil.Address, 0, numPubKeys)
-               for i := 0; i < numPubKeys; i++ {
-                       addr, err := btcutil.NewAddressPubKey(pops[i+1].data,
-                               chainParams)
-                       if err == nil {
-                               addrs = append(addrs, addr)
-                       }
-               }
-
-       case NullDataTy:
-               // Null data transactions have no addresses or required
-               // signatures.
-
-       case NonStandardTy:
-               // Don't attempt to extract addresses or required signatures for
-               // nonstandard transactions.
-       }
-
-       return scriptClass, addrs, requiredSigs, nil
-}