github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/txscript/script.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  	"bytes"
    10  	"encoding/binary"
    11  	"fmt"
    12  	"time"
    13  
    14  	"github.com/BlockABC/godash/wire"
    15  )
    16  
    17  // Bip16Activation is the timestamp where BIP0016 is valid to use in the
    18  // blockchain.  To be used to determine if BIP0016 should be called for or not.
    19  // This timestamp corresponds to Sun Apr 1 00:00:00 UTC 2012.
    20  var Bip16Activation = time.Unix(1333238400, 0)
    21  
    22  // SigHashType represents hash type bits at the end of a signature.
    23  type SigHashType uint32
    24  
    25  // Hash type bits from the end of a signature.
    26  const (
    27  	SigHashOld          SigHashType = 0x0
    28  	SigHashAll          SigHashType = 0x1
    29  	SigHashNone         SigHashType = 0x2
    30  	SigHashSingle       SigHashType = 0x3
    31  	SigHashAnyOneCanPay SigHashType = 0x80
    32  
    33  	// sigHashMask defines the number of bits of the hash type which is used
    34  	// to identify which outputs are signed.
    35  	sigHashMask = 0x1f
    36  )
    37  
    38  // These are the constants specified for maximums in individual scripts.
    39  const (
    40  	MaxOpsPerScript       = 201 // Max number of non-push operations.
    41  	MaxPubKeysPerMultiSig = 20  // Multisig can't have more sigs than this.
    42  	MaxScriptElementSize  = 520 // Max bytes pushable to the stack.
    43  )
    44  
    45  // isSmallInt returns whether or not the opcode is considered a small integer,
    46  // which is an OP_0, or OP_1 through OP_16.
    47  func isSmallInt(op *opcode) bool {
    48  	if op.value == OP_0 || (op.value >= OP_1 && op.value <= OP_16) {
    49  		return true
    50  	}
    51  	return false
    52  }
    53  
    54  // isScriptHash returns true if the script passed is a pay-to-script-hash
    55  // transaction, false otherwise.
    56  func isScriptHash(pops []parsedOpcode) bool {
    57  	return len(pops) == 3 &&
    58  		pops[0].opcode.value == OP_HASH160 &&
    59  		pops[1].opcode.value == OP_DATA_20 &&
    60  		pops[2].opcode.value == OP_EQUAL
    61  }
    62  
    63  // IsPayToScriptHash returns true if the script is in the standard
    64  // pay-to-script-hash (P2SH) format, false otherwise.
    65  func IsPayToScriptHash(script []byte) bool {
    66  	pops, err := parseScript(script)
    67  	if err != nil {
    68  		return false
    69  	}
    70  	return isScriptHash(pops)
    71  }
    72  
    73  // isPushOnly returns true if the script only pushes data, false otherwise.
    74  func isPushOnly(pops []parsedOpcode) bool {
    75  	// NOTE: This function does NOT verify opcodes directly since it is
    76  	// internal and is only called with parsed opcodes for scripts that did
    77  	// not have any parse errors.  Thus, consensus is properly maintained.
    78  
    79  	for _, pop := range pops {
    80  		// All opcodes up to OP_16 are data push instructions.
    81  		// NOTE: This does consider OP_RESERVED to be a data push
    82  		// instruction, but execution of OP_RESERVED will fail anyways
    83  		// and matches the behavior required by consensus.
    84  		if pop.opcode.value > OP_16 {
    85  			return false
    86  		}
    87  	}
    88  	return true
    89  }
    90  
    91  // IsPushOnlyScript returns whether or not the passed script only pushes data.
    92  //
    93  // False will be returned when the script does not parse.
    94  func IsPushOnlyScript(script []byte) bool {
    95  	pops, err := parseScript(script)
    96  	if err != nil {
    97  		return false
    98  	}
    99  	return isPushOnly(pops)
   100  }
   101  
   102  // parseScriptTemplate is the same as parseScript but allows the passing of the
   103  // template list for testing purposes.  When there are parse errors, it returns
   104  // the list of parsed opcodes up to the point of failure along with the error.
   105  func parseScriptTemplate(script []byte, opcodes *[256]opcode) ([]parsedOpcode, error) {
   106  	retScript := make([]parsedOpcode, 0, len(script))
   107  	for i := 0; i < len(script); {
   108  		instr := script[i]
   109  		op := &opcodes[instr]
   110  		pop := parsedOpcode{opcode: op}
   111  
   112  		// Parse data out of instruction.
   113  		switch {
   114  		// No additional data.  Note that some of the opcodes, notably
   115  		// OP_1NEGATE, OP_0, and OP_[1-16] represent the data
   116  		// themselves.
   117  		case op.length == 1:
   118  			i++
   119  
   120  		// Data pushes of specific lengths -- OP_DATA_[1-75].
   121  		case op.length > 1:
   122  			if len(script[i:]) < op.length {
   123  				return retScript, ErrStackShortScript
   124  			}
   125  
   126  			// Slice out the data.
   127  			pop.data = script[i+1 : i+op.length]
   128  			i += op.length
   129  
   130  		// Data pushes with parsed lengths -- OP_PUSHDATAP{1,2,4}.
   131  		case op.length < 0:
   132  			var l uint
   133  			off := i + 1
   134  
   135  			if len(script[off:]) < -op.length {
   136  				return retScript, ErrStackShortScript
   137  			}
   138  
   139  			// Next -length bytes are little endian length of data.
   140  			switch op.length {
   141  			case -1:
   142  				l = uint(script[off])
   143  			case -2:
   144  				l = ((uint(script[off+1]) << 8) |
   145  					uint(script[off]))
   146  			case -4:
   147  				l = ((uint(script[off+3]) << 24) |
   148  					(uint(script[off+2]) << 16) |
   149  					(uint(script[off+1]) << 8) |
   150  					uint(script[off]))
   151  			default:
   152  				return retScript,
   153  					fmt.Errorf("invalid opcode length %d",
   154  						op.length)
   155  			}
   156  
   157  			// Move offset to beginning of the data.
   158  			off += -op.length
   159  
   160  			// Disallow entries that do not fit script or were
   161  			// sign extended.
   162  			if int(l) > len(script[off:]) || int(l) < 0 {
   163  				return retScript, ErrStackShortScript
   164  			}
   165  
   166  			pop.data = script[off : off+int(l)]
   167  			i += 1 - op.length + int(l)
   168  		}
   169  
   170  		retScript = append(retScript, pop)
   171  	}
   172  
   173  	return retScript, nil
   174  }
   175  
   176  // parseScript preparses the script in bytes into a list of parsedOpcodes while
   177  // applying a number of sanity checks.
   178  func parseScript(script []byte) ([]parsedOpcode, error) {
   179  	return parseScriptTemplate(script, &opcodeArray)
   180  }
   181  
   182  // unparseScript reversed the action of parseScript and returns the
   183  // parsedOpcodes as a list of bytes
   184  func unparseScript(pops []parsedOpcode) ([]byte, error) {
   185  	script := make([]byte, 0, len(pops))
   186  	for _, pop := range pops {
   187  		b, err := pop.bytes()
   188  		if err != nil {
   189  			return nil, err
   190  		}
   191  		script = append(script, b...)
   192  	}
   193  	return script, nil
   194  }
   195  
   196  // DisasmString formats a disassembled script for one line printing.  When the
   197  // script fails to parse, the returned string will contain the disassembled
   198  // script up to the point the failure occurred along with the string '[error]'
   199  // appended.  In addition, the reason the script failed to parse is returned
   200  // if the caller wants more information about the failure.
   201  func DisasmString(buf []byte) (string, error) {
   202  	var disbuf bytes.Buffer
   203  	opcodes, err := parseScript(buf)
   204  	for _, pop := range opcodes {
   205  		disbuf.WriteString(pop.print(true))
   206  		disbuf.WriteByte(' ')
   207  	}
   208  	if disbuf.Len() > 0 {
   209  		disbuf.Truncate(disbuf.Len() - 1)
   210  	}
   211  	if err != nil {
   212  		disbuf.WriteString("[error]")
   213  	}
   214  	return disbuf.String(), err
   215  }
   216  
   217  // removeOpcode will remove any opcode matching ``opcode'' from the opcode
   218  // stream in pkscript
   219  func removeOpcode(pkscript []parsedOpcode, opcode byte) []parsedOpcode {
   220  	retScript := make([]parsedOpcode, 0, len(pkscript))
   221  	for _, pop := range pkscript {
   222  		if pop.opcode.value != opcode {
   223  			retScript = append(retScript, pop)
   224  		}
   225  	}
   226  	return retScript
   227  }
   228  
   229  // canonicalPush returns true if the object is either not a push instruction
   230  // or the push instruction contained wherein is matches the canonical form
   231  // or using the smallest instruction to do the job. False otherwise.
   232  func canonicalPush(pop parsedOpcode) bool {
   233  	opcode := pop.opcode.value
   234  	data := pop.data
   235  	dataLen := len(pop.data)
   236  	if opcode > OP_16 {
   237  		return true
   238  	}
   239  
   240  	if opcode < OP_PUSHDATA1 && opcode > OP_0 && (dataLen == 1 && data[0] <= 16) {
   241  		return false
   242  	}
   243  	if opcode == OP_PUSHDATA1 && dataLen < OP_PUSHDATA1 {
   244  		return false
   245  	}
   246  	if opcode == OP_PUSHDATA2 && dataLen <= 0xff {
   247  		return false
   248  	}
   249  	if opcode == OP_PUSHDATA4 && dataLen <= 0xffff {
   250  		return false
   251  	}
   252  	return true
   253  }
   254  
   255  // removeOpcodeByData will return the script minus any opcodes that would push
   256  // the passed data to the stack.
   257  func removeOpcodeByData(pkscript []parsedOpcode, data []byte) []parsedOpcode {
   258  	retScript := make([]parsedOpcode, 0, len(pkscript))
   259  	for _, pop := range pkscript {
   260  		if !canonicalPush(pop) || !bytes.Contains(pop.data, data) {
   261  			retScript = append(retScript, pop)
   262  		}
   263  	}
   264  	return retScript
   265  
   266  }
   267  
   268  // calcSignatureHash will, given a script and hash type for the current script
   269  // engine instance, calculate the signature hash to be used for signing and
   270  // verification.
   271  func calcSignatureHash(script []parsedOpcode, hashType SigHashType, tx *wire.MsgTx, idx int) []byte {
   272  	// The SigHashSingle signature type signs only the corresponding input
   273  	// and output (the output with the same index number as the input).
   274  	//
   275  	// Since transactions can have more inputs than outputs, this means it
   276  	// is improper to use SigHashSingle on input indices that don't have a
   277  	// corresponding output.
   278  	//
   279  	// A bug in the original Satoshi client implementation means specifying
   280  	// an index that is out of range results in a signature hash of 1 (as a
   281  	// uint256 little endian).  The original intent appeared to be to
   282  	// indicate failure, but unfortunately, it was never checked and thus is
   283  	// treated as the actual signature hash.  This buggy behavior is now
   284  	// part of the consensus and a hard fork would be required to fix it.
   285  	//
   286  	// Due to this, care must be taken by software that creates transactions
   287  	// which make use of SigHashSingle because it can lead to an extremely
   288  	// dangerous situation where the invalid inputs will end up signing a
   289  	// hash of 1.  This in turn presents an opportunity for attackers to
   290  	// cleverly construct transactions which can steal those coins provided
   291  	// they can reuse signatures.
   292  	if hashType&sigHashMask == SigHashSingle && idx >= len(tx.TxOut) {
   293  		var hash wire.ShaHash
   294  		hash[0] = 0x01
   295  		return hash[:]
   296  	}
   297  
   298  	// Remove all instances of OP_CODESEPARATOR from the script.
   299  	script = removeOpcode(script, OP_CODESEPARATOR)
   300  
   301  	// Make a deep copy of the transaction, zeroing out the script for all
   302  	// inputs that are not currently being processed.
   303  	txCopy := tx.Copy()
   304  	for i := range txCopy.TxIn {
   305  		if i == idx {
   306  			// UnparseScript cannot fail here because removeOpcode
   307  			// above only returns a valid script.
   308  			sigScript, _ := unparseScript(script)
   309  			txCopy.TxIn[idx].SignatureScript = sigScript
   310  		} else {
   311  			txCopy.TxIn[i].SignatureScript = nil
   312  		}
   313  	}
   314  
   315  	switch hashType & sigHashMask {
   316  	case SigHashNone:
   317  		txCopy.TxOut = txCopy.TxOut[0:0] // Empty slice.
   318  		for i := range txCopy.TxIn {
   319  			if i != idx {
   320  				txCopy.TxIn[i].Sequence = 0
   321  			}
   322  		}
   323  
   324  	case SigHashSingle:
   325  		// Resize output array to up to and including requested index.
   326  		txCopy.TxOut = txCopy.TxOut[:idx+1]
   327  
   328  		// All but current output get zeroed out.
   329  		for i := 0; i < idx; i++ {
   330  			txCopy.TxOut[i].Value = -1
   331  			txCopy.TxOut[i].PkScript = nil
   332  		}
   333  
   334  		// Sequence on all other inputs is 0, too.
   335  		for i := range txCopy.TxIn {
   336  			if i != idx {
   337  				txCopy.TxIn[i].Sequence = 0
   338  			}
   339  		}
   340  
   341  	default:
   342  		// Consensus treats undefined hashtypes like normal SigHashAll
   343  		// for purposes of hash generation.
   344  		fallthrough
   345  	case SigHashOld:
   346  		fallthrough
   347  	case SigHashAll:
   348  		// Nothing special here.
   349  	}
   350  	if hashType&SigHashAnyOneCanPay != 0 {
   351  		txCopy.TxIn = txCopy.TxIn[idx : idx+1]
   352  		idx = 0
   353  	}
   354  
   355  	// The final hash is the double sha256 of both the serialized modified
   356  	// transaction and the hash type (encoded as a 4-byte little-endian
   357  	// value) appended.
   358  	var wbuf bytes.Buffer
   359  	txCopy.Serialize(&wbuf)
   360  	binary.Write(&wbuf, binary.LittleEndian, hashType)
   361  	return wire.DoubleSha256(wbuf.Bytes())
   362  }
   363  
   364  // asSmallInt returns the passed opcode, which must be true according to
   365  // isSmallInt(), as an integer.
   366  func asSmallInt(op *opcode) int {
   367  	if op.value == OP_0 {
   368  		return 0
   369  	}
   370  
   371  	return int(op.value - (OP_1 - 1))
   372  }
   373  
   374  // getSigOpCount is the implementation function for counting the number of
   375  // signature operations in the script provided by pops. If precise mode is
   376  // requested then we attempt to count the number of operations for a multisig
   377  // op. Otherwise we use the maximum.
   378  func getSigOpCount(pops []parsedOpcode, precise bool) int {
   379  	nSigs := 0
   380  	for i, pop := range pops {
   381  		switch pop.opcode.value {
   382  		case OP_CHECKSIG:
   383  			fallthrough
   384  		case OP_CHECKSIGVERIFY:
   385  			nSigs++
   386  		case OP_CHECKMULTISIG:
   387  			fallthrough
   388  		case OP_CHECKMULTISIGVERIFY:
   389  			// If we are being precise then look for familiar
   390  			// patterns for multisig, for now all we recognize is
   391  			// OP_1 - OP_16 to signify the number of pubkeys.
   392  			// Otherwise, we use the max of 20.
   393  			if precise && i > 0 &&
   394  				pops[i-1].opcode.value >= OP_1 &&
   395  				pops[i-1].opcode.value <= OP_16 {
   396  				nSigs += asSmallInt(pops[i-1].opcode)
   397  			} else {
   398  				nSigs += MaxPubKeysPerMultiSig
   399  			}
   400  		default:
   401  			// Not a sigop.
   402  		}
   403  	}
   404  
   405  	return nSigs
   406  }
   407  
   408  // GetSigOpCount provides a quick count of the number of signature operations
   409  // in a script. a CHECKSIG operations counts for 1, and a CHECK_MULTISIG for 20.
   410  // If the script fails to parse, then the count up to the point of failure is
   411  // returned.
   412  func GetSigOpCount(script []byte) int {
   413  	// Don't check error since parseScript returns the parsed-up-to-error
   414  	// list of pops.
   415  	pops, _ := parseScript(script)
   416  	return getSigOpCount(pops, false)
   417  }
   418  
   419  // GetPreciseSigOpCount returns the number of signature operations in
   420  // scriptPubKey.  If bip16 is true then scriptSig may be searched for the
   421  // Pay-To-Script-Hash script in order to find the precise number of signature
   422  // operations in the transaction.  If the script fails to parse, then the count
   423  // up to the point of failure is returned.
   424  func GetPreciseSigOpCount(scriptSig, scriptPubKey []byte, bip16 bool) int {
   425  	// Don't check error since parseScript returns the parsed-up-to-error
   426  	// list of pops.
   427  	pops, _ := parseScript(scriptPubKey)
   428  
   429  	// Treat non P2SH transactions as normal.
   430  	if !(bip16 && isScriptHash(pops)) {
   431  		return getSigOpCount(pops, true)
   432  	}
   433  
   434  	// The public key script is a pay-to-script-hash, so parse the signature
   435  	// script to get the final item.  Scripts that fail to fully parse count
   436  	// as 0 signature operations.
   437  	sigPops, err := parseScript(scriptSig)
   438  	if err != nil {
   439  		return 0
   440  	}
   441  
   442  	// The signature script must only push data to the stack for P2SH to be
   443  	// a valid pair, so the signature operation count is 0 when that is not
   444  	// the case.
   445  	if !isPushOnly(sigPops) || len(sigPops) == 0 {
   446  		return 0
   447  	}
   448  
   449  	// The P2SH script is the last item the signature script pushes to the
   450  	// stack.  When the script is empty, there are no signature operations.
   451  	shScript := sigPops[len(sigPops)-1].data
   452  	if len(shScript) == 0 {
   453  		return 0
   454  	}
   455  
   456  	// Parse the P2SH script and don't check the error since parseScript
   457  	// returns the parsed-up-to-error list of pops and the consensus rules
   458  	// dictate signature operations are counted up to the first parse
   459  	// failure.
   460  	shPops, _ := parseScript(shScript)
   461  	return getSigOpCount(shPops, true)
   462  }
   463  
   464  // IsUnspendable returns whether the passed public key script is unspendable, or
   465  // guaranteed to fail at execution.  This allows inputs to be pruned instantly
   466  // when entering the UTXO set.
   467  func IsUnspendable(pkScript []byte) bool {
   468  	pops, err := parseScript(pkScript)
   469  	if err != nil {
   470  		return true
   471  	}
   472  
   473  	return len(pops) > 0 && pops[0].opcode.value == OP_RETURN
   474  }