github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/txscript/standard.go (about)

     1  // Copyright (c) 2013-2015 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package txscript
     7  
     8  import (
     9  	"github.com/BlockABC/godash/chaincfg"
    10  	"github.com/BlockABC/godashutil"
    11  )
    12  
    13  const (
    14  	// MaxDataCarrierSize is the maximum number of bytes allowed in pushed
    15  	// data to be considered a nulldata transaction
    16  	MaxDataCarrierSize = 80
    17  
    18  	// StandardVerifyFlags are the script flags which are used when
    19  	// executing transaction scripts to enforce additional checks which
    20  	// are required for the script to be considered standard.  These checks
    21  	// help reduce issues related to transaction malleability as well as
    22  	// allow pay-to-script hash transactions.  Note these flags are
    23  	// different than what is required for the consensus rules in that they
    24  	// are more strict.
    25  	//
    26  	// TODO: This definition does not belong here.  It belongs in a policy
    27  	// package.
    28  	StandardVerifyFlags = ScriptBip16 |
    29  		ScriptVerifyDERSignatures |
    30  		ScriptVerifyStrictEncoding |
    31  		ScriptVerifyMinimalData |
    32  		ScriptStrictMultiSig |
    33  		ScriptDiscourageUpgradableNops |
    34  		ScriptVerifyCleanStack |
    35  		ScriptVerifyCheckLockTimeVerify |
    36  		ScriptVerifyLowS
    37  )
    38  
    39  // ScriptClass is an enumeration for the list of standard types of script.
    40  type ScriptClass byte
    41  
    42  // Classes of script payment known about in the blockchain.
    43  const (
    44  	NonStandardTy ScriptClass = iota // None of the recognized forms.
    45  	PubKeyTy                         // Pay pubkey.
    46  	PubKeyHashTy                     // Pay pubkey hash.
    47  	ScriptHashTy                     // Pay to script hash.
    48  	MultiSigTy                       // Multi signature.
    49  	NullDataTy                       // Empty data-only (provably prunable).
    50  )
    51  
    52  // scriptClassToName houses the human-readable strings which describe each
    53  // script class.
    54  var scriptClassToName = []string{
    55  	NonStandardTy: "nonstandard",
    56  	PubKeyTy:      "pubkey",
    57  	PubKeyHashTy:  "pubkeyhash",
    58  	ScriptHashTy:  "scripthash",
    59  	MultiSigTy:    "multisig",
    60  	NullDataTy:    "nulldata",
    61  }
    62  
    63  // String implements the Stringer interface by returning the name of
    64  // the enum script class. If the enum is invalid then "Invalid" will be
    65  // returned.
    66  func (t ScriptClass) String() string {
    67  	if int(t) > len(scriptClassToName) || int(t) < 0 {
    68  		return "Invalid"
    69  	}
    70  	return scriptClassToName[t]
    71  }
    72  
    73  // isPubkey returns true if the script passed is a pay-to-pubkey transaction,
    74  // false otherwise.
    75  func isPubkey(pops []parsedOpcode) bool {
    76  	// Valid pubkeys are either 33 or 65 bytes.
    77  	return len(pops) == 2 &&
    78  		(len(pops[0].data) == 33 || len(pops[0].data) == 65) &&
    79  		pops[1].opcode.value == OP_CHECKSIG
    80  }
    81  
    82  // isPubkeyHash returns true if the script passed is a pay-to-pubkey-hash
    83  // transaction, false otherwise.
    84  func isPubkeyHash(pops []parsedOpcode) bool {
    85  	return len(pops) == 5 &&
    86  		pops[0].opcode.value == OP_DUP &&
    87  		pops[1].opcode.value == OP_HASH160 &&
    88  		pops[2].opcode.value == OP_DATA_20 &&
    89  		pops[3].opcode.value == OP_EQUALVERIFY &&
    90  		pops[4].opcode.value == OP_CHECKSIG
    91  
    92  }
    93  
    94  // isMultiSig returns true if the passed script is a multisig transaction, false
    95  // otherwise.
    96  func isMultiSig(pops []parsedOpcode) bool {
    97  	// The absolute minimum is 1 pubkey:
    98  	// OP_0/OP_1-16 <pubkey> OP_1 OP_CHECKMULTISIG
    99  	l := len(pops)
   100  	if l < 4 {
   101  		return false
   102  	}
   103  	if !isSmallInt(pops[0].opcode) {
   104  		return false
   105  	}
   106  	if !isSmallInt(pops[l-2].opcode) {
   107  		return false
   108  	}
   109  	if pops[l-1].opcode.value != OP_CHECKMULTISIG {
   110  		return false
   111  	}
   112  
   113  	// Verify the number of pubkeys specified matches the actual number
   114  	// of pubkeys provided.
   115  	if l-2-1 != asSmallInt(pops[l-2].opcode) {
   116  		return false
   117  	}
   118  
   119  	for _, pop := range pops[1 : l-2] {
   120  		// Valid pubkeys are either 33 or 65 bytes.
   121  		if len(pop.data) != 33 && len(pop.data) != 65 {
   122  			return false
   123  		}
   124  	}
   125  	return true
   126  }
   127  
   128  // isNullData returns true if the passed script is a null data transaction,
   129  // false otherwise.
   130  func isNullData(pops []parsedOpcode) bool {
   131  	// A nulldata transaction is either a single OP_RETURN or an
   132  	// OP_RETURN SMALLDATA (where SMALLDATA is a data push up to
   133  	// MaxDataCarrierSize bytes).
   134  	l := len(pops)
   135  	if l == 1 && pops[0].opcode.value == OP_RETURN {
   136  		return true
   137  	}
   138  
   139  	return l == 2 &&
   140  		pops[0].opcode.value == OP_RETURN &&
   141  		pops[1].opcode.value <= OP_PUSHDATA4 &&
   142  		len(pops[1].data) <= MaxDataCarrierSize
   143  }
   144  
   145  // scriptType returns the type of the script being inspected from the known
   146  // standard types.
   147  func typeOfScript(pops []parsedOpcode) ScriptClass {
   148  	if isPubkey(pops) {
   149  		return PubKeyTy
   150  	} else if isPubkeyHash(pops) {
   151  		return PubKeyHashTy
   152  	} else if isScriptHash(pops) {
   153  		return ScriptHashTy
   154  	} else if isMultiSig(pops) {
   155  		return MultiSigTy
   156  	} else if isNullData(pops) {
   157  		return NullDataTy
   158  	}
   159  	return NonStandardTy
   160  }
   161  
   162  // GetScriptClass returns the class of the script passed.
   163  //
   164  // NonStandardTy will be returned when the script does not parse.
   165  func GetScriptClass(script []byte) ScriptClass {
   166  	pops, err := parseScript(script)
   167  	if err != nil {
   168  		return NonStandardTy
   169  	}
   170  	return typeOfScript(pops)
   171  }
   172  
   173  // expectedInputs returns the number of arguments required by a script.
   174  // If the script is of unknown type such that the number can not be determined
   175  // then -1 is returned. We are an internal function and thus assume that class
   176  // is the real class of pops (and we can thus assume things that were determined
   177  // while finding out the type).
   178  func expectedInputs(pops []parsedOpcode, class ScriptClass) int {
   179  	switch class {
   180  	case PubKeyTy:
   181  		return 1
   182  
   183  	case PubKeyHashTy:
   184  		return 2
   185  
   186  	case ScriptHashTy:
   187  		// Not including script.  That is handled by the caller.
   188  		return 1
   189  
   190  	case MultiSigTy:
   191  		// Standard multisig has a push a small number for the number
   192  		// of sigs and number of keys.  Check the first push instruction
   193  		// to see how many arguments are expected. typeOfScript already
   194  		// checked this so we know it'll be a small int.  Also, due to
   195  		// the original bitcoind bug where OP_CHECKMULTISIG pops an
   196  		// additional item from the stack, add an extra expected input
   197  		// for the extra push that is required to compensate.
   198  		return asSmallInt(pops[0].opcode) + 1
   199  
   200  	case NullDataTy:
   201  		fallthrough
   202  	default:
   203  		return -1
   204  	}
   205  }
   206  
   207  // ScriptInfo houses information about a script pair that is determined by
   208  // CalcScriptInfo.
   209  type ScriptInfo struct {
   210  	// PkScriptClass is the class of the public key script and is equivalent
   211  	// to calling GetScriptClass on it.
   212  	PkScriptClass ScriptClass
   213  
   214  	// NumInputs is the number of inputs provided by the public key script.
   215  	NumInputs int
   216  
   217  	// ExpectedInputs is the number of outputs required by the signature
   218  	// script and any pay-to-script-hash scripts. The number will be -1 if
   219  	// unknown.
   220  	ExpectedInputs int
   221  
   222  	// SigOps is the number of signature operations in the script pair.
   223  	SigOps int
   224  }
   225  
   226  // CalcScriptInfo returns a structure providing data about the provided script
   227  // pair.  It will error if the pair is in someway invalid such that they can not
   228  // be analysed, i.e. if they do not parse or the pkScript is not a push-only
   229  // script
   230  func CalcScriptInfo(sigScript, pkScript []byte, bip16 bool) (*ScriptInfo, error) {
   231  	sigPops, err := parseScript(sigScript)
   232  	if err != nil {
   233  		return nil, err
   234  	}
   235  
   236  	pkPops, err := parseScript(pkScript)
   237  	if err != nil {
   238  		return nil, err
   239  	}
   240  
   241  	// Push only sigScript makes little sense.
   242  	si := new(ScriptInfo)
   243  	si.PkScriptClass = typeOfScript(pkPops)
   244  
   245  	// Can't have a pkScript that doesn't just push data.
   246  	if !isPushOnly(sigPops) {
   247  		return nil, ErrStackNonPushOnly
   248  	}
   249  
   250  	si.ExpectedInputs = expectedInputs(pkPops, si.PkScriptClass)
   251  
   252  	// All entries pushed to stack (or are OP_RESERVED and exec will fail).
   253  	si.NumInputs = len(sigPops)
   254  
   255  	// Count sigops taking into account pay-to-script-hash.
   256  	if si.PkScriptClass == ScriptHashTy && bip16 {
   257  		// The pay-to-hash-script is the final data push of the
   258  		// signature script.
   259  		script := sigPops[len(sigPops)-1].data
   260  		shPops, err := parseScript(script)
   261  		if err != nil {
   262  			return nil, err
   263  		}
   264  
   265  		shInputs := expectedInputs(shPops, typeOfScript(shPops))
   266  		if shInputs == -1 {
   267  			si.ExpectedInputs = -1
   268  		} else {
   269  			si.ExpectedInputs += shInputs
   270  		}
   271  		si.SigOps = getSigOpCount(shPops, true)
   272  	} else {
   273  		si.SigOps = getSigOpCount(pkPops, true)
   274  	}
   275  
   276  	return si, nil
   277  }
   278  
   279  // CalcMultiSigStats returns the number of public keys and signatures from
   280  // a multi-signature transaction script.  The passed script MUST already be
   281  // known to be a multi-signature script.
   282  func CalcMultiSigStats(script []byte) (int, int, error) {
   283  	pops, err := parseScript(script)
   284  	if err != nil {
   285  		return 0, 0, err
   286  	}
   287  
   288  	// A multi-signature script is of the pattern:
   289  	//  NUM_SIGS PUBKEY PUBKEY PUBKEY... NUM_PUBKEYS OP_CHECKMULTISIG
   290  	// Therefore the number of signatures is the oldest item on the stack
   291  	// and the number of pubkeys is the 2nd to last.  Also, the absolute
   292  	// minimum for a multi-signature script is 1 pubkey, so at least 4
   293  	// items must be on the stack per:
   294  	//  OP_1 PUBKEY OP_1 OP_CHECKMULTISIG
   295  	if len(pops) < 4 {
   296  		return 0, 0, ErrStackUnderflow
   297  	}
   298  
   299  	numSigs := asSmallInt(pops[0].opcode)
   300  	numPubKeys := asSmallInt(pops[len(pops)-2].opcode)
   301  	return numPubKeys, numSigs, nil
   302  }
   303  
   304  // payToPubKeyHashScript creates a new script to pay a transaction
   305  // output to a 20-byte pubkey hash. It is expected that the input is a valid
   306  // hash.
   307  func payToPubKeyHashScript(pubKeyHash []byte) ([]byte, error) {
   308  	return NewScriptBuilder().AddOp(OP_DUP).AddOp(OP_HASH160).
   309  		AddData(pubKeyHash).AddOp(OP_EQUALVERIFY).AddOp(OP_CHECKSIG).
   310  		Script()
   311  }
   312  
   313  // payToScriptHashScript creates a new script to pay a transaction output to a
   314  // script hash. It is expected that the input is a valid hash.
   315  func payToScriptHashScript(scriptHash []byte) ([]byte, error) {
   316  	return NewScriptBuilder().AddOp(OP_HASH160).AddData(scriptHash).
   317  		AddOp(OP_EQUAL).Script()
   318  }
   319  
   320  // payToPubkeyScript creates a new script to pay a transaction output to a
   321  // public key. It is expected that the input is a valid pubkey.
   322  func payToPubKeyScript(serializedPubKey []byte) ([]byte, error) {
   323  	return NewScriptBuilder().AddData(serializedPubKey).
   324  		AddOp(OP_CHECKSIG).Script()
   325  }
   326  
   327  // PayToAddrScript creates a new script to pay a transaction output to a the
   328  // specified address.
   329  func PayToAddrScript(addr godashutil.Address) ([]byte, error) {
   330  	switch addr := addr.(type) {
   331  	case *godashutil.AddressPubKeyHash:
   332  		if addr == nil {
   333  			return nil, ErrUnsupportedAddress
   334  		}
   335  		return payToPubKeyHashScript(addr.ScriptAddress())
   336  
   337  	case *godashutil.AddressScriptHash:
   338  		if addr == nil {
   339  			return nil, ErrUnsupportedAddress
   340  		}
   341  		return payToScriptHashScript(addr.ScriptAddress())
   342  
   343  	case *godashutil.AddressPubKey:
   344  		if addr == nil {
   345  			return nil, ErrUnsupportedAddress
   346  		}
   347  		return payToPubKeyScript(addr.ScriptAddress())
   348  	}
   349  
   350  	return nil, ErrUnsupportedAddress
   351  }
   352  
   353  // MultiSigScript returns a valid script for a multisignature redemption where
   354  // nrequired of the keys in pubkeys are required to have signed the transaction
   355  // for success.  An ErrBadNumRequired will be returned if nrequired is larger
   356  // than the number of keys provided.
   357  func MultiSigScript(pubkeys []*godashutil.AddressPubKey, nrequired int) ([]byte, error) {
   358  	if len(pubkeys) < nrequired {
   359  		return nil, ErrBadNumRequired
   360  	}
   361  
   362  	builder := NewScriptBuilder().AddInt64(int64(nrequired))
   363  	for _, key := range pubkeys {
   364  		builder.AddData(key.ScriptAddress())
   365  	}
   366  	builder.AddInt64(int64(len(pubkeys)))
   367  	builder.AddOp(OP_CHECKMULTISIG)
   368  
   369  	return builder.Script()
   370  }
   371  
   372  // PushedData returns an array of byte slices containing any pushed data found
   373  // in the passed script.  This includes OP_0, but not OP_1 - OP_16.
   374  func PushedData(script []byte) ([][]byte, error) {
   375  	pops, err := parseScript(script)
   376  	if err != nil {
   377  		return nil, err
   378  	}
   379  
   380  	var data [][]byte
   381  	for _, pop := range pops {
   382  		if pop.data != nil {
   383  			data = append(data, pop.data)
   384  		} else if pop.opcode.value == OP_0 {
   385  			data = append(data, nil)
   386  		}
   387  	}
   388  	return data, nil
   389  }
   390  
   391  // ExtractPkScriptAddrs returns the type of script, addresses and required
   392  // signatures associated with the passed PkScript.  Note that it only works for
   393  // 'standard' transaction script types.  Any data such as public keys which are
   394  // invalid are omitted from the results.
   395  func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (ScriptClass, []godashutil.Address, int, error) {
   396  	var addrs []godashutil.Address
   397  	var requiredSigs int
   398  
   399  	// No valid addresses or required signatures if the script doesn't
   400  	// parse.
   401  	pops, err := parseScript(pkScript)
   402  	if err != nil {
   403  		return NonStandardTy, nil, 0, err
   404  	}
   405  
   406  	scriptClass := typeOfScript(pops)
   407  	switch scriptClass {
   408  	case PubKeyHashTy:
   409  		// A pay-to-pubkey-hash script is of the form:
   410  		//  OP_DUP OP_HASH160 <hash> OP_EQUALVERIFY OP_CHECKSIG
   411  		// Therefore the pubkey hash is the 3rd item on the stack.
   412  		// Skip the pubkey hash if it's invalid for some reason.
   413  		requiredSigs = 1
   414  		addr, err := godashutil.NewAddressPubKeyHash(pops[2].data,
   415  			chainParams)
   416  		if err == nil {
   417  			addrs = append(addrs, addr)
   418  		}
   419  
   420  	case PubKeyTy:
   421  		// A pay-to-pubkey script is of the form:
   422  		//  <pubkey> OP_CHECKSIG
   423  		// Therefore the pubkey is the first item on the stack.
   424  		// Skip the pubkey if it's invalid for some reason.
   425  		requiredSigs = 1
   426  		addr, err := godashutil.NewAddressPubKey(pops[0].data, chainParams)
   427  		if err == nil {
   428  			addrs = append(addrs, addr)
   429  		}
   430  
   431  	case ScriptHashTy:
   432  		// A pay-to-script-hash script is of the form:
   433  		//  OP_HASH160 <scripthash> OP_EQUAL
   434  		// Therefore the script hash is the 2nd item on the stack.
   435  		// Skip the script hash if it's invalid for some reason.
   436  		requiredSigs = 1
   437  		addr, err := godashutil.NewAddressScriptHashFromHash(pops[1].data,
   438  			chainParams)
   439  		if err == nil {
   440  			addrs = append(addrs, addr)
   441  		}
   442  
   443  	case MultiSigTy:
   444  		// A multi-signature script is of the form:
   445  		//  <numsigs> <pubkey> <pubkey> <pubkey>... <numpubkeys> OP_CHECKMULTISIG
   446  		// Therefore the number of required signatures is the 1st item
   447  		// on the stack and the number of public keys is the 2nd to last
   448  		// item on the stack.
   449  		requiredSigs = asSmallInt(pops[0].opcode)
   450  		numPubKeys := asSmallInt(pops[len(pops)-2].opcode)
   451  
   452  		// Extract the public keys while skipping any that are invalid.
   453  		addrs = make([]godashutil.Address, 0, numPubKeys)
   454  		for i := 0; i < numPubKeys; i++ {
   455  			addr, err := godashutil.NewAddressPubKey(pops[i+1].data,
   456  				chainParams)
   457  			if err == nil {
   458  				addrs = append(addrs, addr)
   459  			}
   460  		}
   461  
   462  	case NullDataTy:
   463  		// Null data transactions have no addresses or required
   464  		// signatures.
   465  
   466  	case NonStandardTy:
   467  		// Don't attempt to extract addresses or required signatures for
   468  		// nonstandard transactions.
   469  	}
   470  
   471  	return scriptClass, addrs, requiredSigs, nil
   472  }