github.com/btcsuite/btcd@v0.24.0/txscript/standard_test.go (about)

     1  // Copyright (c) 2013-2020 The btcsuite developers
     2  // Use of this source code is governed by an ISC
     3  // license that can be found in the LICENSE file.
     4  
     5  package txscript
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/hex"
    10  	"errors"
    11  	"reflect"
    12  	"testing"
    13  
    14  	"github.com/btcsuite/btcd/btcutil"
    15  	"github.com/btcsuite/btcd/chaincfg"
    16  	"github.com/btcsuite/btcd/wire"
    17  )
    18  
    19  // mustParseShortForm parses the passed short form script and returns the
    20  // resulting bytes.  It panics if an error occurs.  This is only used in the
    21  // tests as a helper since the only way it can fail is if there is an error in
    22  // the test source code.
    23  func mustParseShortForm(script string) []byte {
    24  	s, err := parseShortForm(script)
    25  	if err != nil {
    26  		panic("invalid short form script in test source: err " +
    27  			err.Error() + ", script: " + script)
    28  	}
    29  
    30  	return s
    31  }
    32  
    33  // newAddressPubKey returns a new btcutil.AddressPubKey from the provided
    34  // serialized public key.  It panics if an error occurs.  This is only used in
    35  // the tests as a helper since the only way it can fail is if there is an error
    36  // in the test source code.
    37  func newAddressPubKey(serializedPubKey []byte) btcutil.Address {
    38  	addr, err := btcutil.NewAddressPubKey(serializedPubKey,
    39  		&chaincfg.MainNetParams)
    40  	if err != nil {
    41  		panic("invalid public key in test source")
    42  	}
    43  
    44  	return addr
    45  }
    46  
    47  // newAddressPubKeyHash returns a new btcutil.AddressPubKeyHash from the
    48  // provided hash.  It panics if an error occurs.  This is only used in the tests
    49  // as a helper since the only way it can fail is if there is an error in the
    50  // test source code.
    51  func newAddressPubKeyHash(pkHash []byte) btcutil.Address {
    52  	addr, err := btcutil.NewAddressPubKeyHash(pkHash, &chaincfg.MainNetParams)
    53  	if err != nil {
    54  		panic("invalid public key hash in test source")
    55  	}
    56  
    57  	return addr
    58  }
    59  
    60  // newAddressScriptHash returns a new btcutil.AddressScriptHash from the
    61  // provided hash.  It panics if an error occurs.  This is only used in the tests
    62  // as a helper since the only way it can fail is if there is an error in the
    63  // test source code.
    64  func newAddressScriptHash(scriptHash []byte) btcutil.Address {
    65  	addr, err := btcutil.NewAddressScriptHashFromHash(scriptHash,
    66  		&chaincfg.MainNetParams)
    67  	if err != nil {
    68  		panic("invalid script hash in test source")
    69  	}
    70  
    71  	return addr
    72  }
    73  
    74  // newAddressTaproot returns a new btcutil.AddressTaproot from the
    75  // provided hash.  It panics if an error occurs.  This is only used in the tests
    76  // as a helper since the only way it can fail is if there is an error in the
    77  // test source code.
    78  func newAddressTaproot(scriptHash []byte) btcutil.Address {
    79  	addr, err := btcutil.NewAddressTaproot(scriptHash,
    80  		&chaincfg.MainNetParams)
    81  	if err != nil {
    82  		panic("invalid script hash in test source")
    83  	}
    84  
    85  	return addr
    86  }
    87  
    88  // TestExtractPkScriptAddrs ensures that extracting the type, addresses, and
    89  // number of required signatures from PkScripts works as intended.
    90  func TestExtractPkScriptAddrs(t *testing.T) {
    91  	t.Parallel()
    92  
    93  	tests := []struct {
    94  		name    string
    95  		script  []byte
    96  		addrs   []btcutil.Address
    97  		reqSigs int
    98  		class   ScriptClass
    99  	}{
   100  		{
   101  			name: "standard p2pk with compressed pubkey (0x02)",
   102  			script: hexToBytes("2102192d74d0cb94344c9569c2e779015" +
   103  				"73d8d7903c3ebec3a957724895dca52c6b4ac"),
   104  			addrs: []btcutil.Address{
   105  				newAddressPubKey(hexToBytes("02192d74d0cb9434" +
   106  					"4c9569c2e77901573d8d7903c3ebec3a9577" +
   107  					"24895dca52c6b4")),
   108  			},
   109  			reqSigs: 1,
   110  			class:   PubKeyTy,
   111  		},
   112  		{
   113  			name: "standard p2pk with uncompressed pubkey (0x04)",
   114  			script: hexToBytes("410411db93e1dcdb8a016b49840f8c53b" +
   115  				"c1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddf" +
   116  				"b84ccf9744464f82e160bfa9b8b64f9d4c03f999b864" +
   117  				"3f656b412a3ac"),
   118  			addrs: []btcutil.Address{
   119  				newAddressPubKey(hexToBytes("0411db93e1dcdb8a" +
   120  					"016b49840f8c53bc1eb68a382e97b1482eca" +
   121  					"d7b148a6909a5cb2e0eaddfb84ccf9744464" +
   122  					"f82e160bfa9b8b64f9d4c03f999b8643f656" +
   123  					"b412a3")),
   124  			},
   125  			reqSigs: 1,
   126  			class:   PubKeyTy,
   127  		},
   128  		{
   129  			name: "standard p2pk with hybrid pubkey (0x06)",
   130  			script: hexToBytes("4106192d74d0cb94344c9569c2e779015" +
   131  				"73d8d7903c3ebec3a957724895dca52c6b40d4526483" +
   132  				"8c0bd96852662ce6a847b197376830160c6d2eb5e6a4" +
   133  				"c44d33f453eac"),
   134  			addrs: []btcutil.Address{
   135  				newAddressPubKey(hexToBytes("06192d74d0cb9434" +
   136  					"4c9569c2e77901573d8d7903c3ebec3a9577" +
   137  					"24895dca52c6b40d45264838c0bd96852662" +
   138  					"ce6a847b197376830160c6d2eb5e6a4c44d3" +
   139  					"3f453e")),
   140  			},
   141  			reqSigs: 1,
   142  			class:   PubKeyTy,
   143  		},
   144  		{
   145  			name: "standard p2pk with compressed pubkey (0x03)",
   146  			script: hexToBytes("2103b0bd634234abbb1ba1e986e884185" +
   147  				"c61cf43e001f9137f23c2c409273eb16e65ac"),
   148  			addrs: []btcutil.Address{
   149  				newAddressPubKey(hexToBytes("03b0bd634234abbb" +
   150  					"1ba1e986e884185c61cf43e001f9137f23c2" +
   151  					"c409273eb16e65")),
   152  			},
   153  			reqSigs: 1,
   154  			class:   PubKeyTy,
   155  		},
   156  		{
   157  			name: "2nd standard p2pk with uncompressed pubkey (0x04)",
   158  			script: hexToBytes("4104b0bd634234abbb1ba1e986e884185" +
   159  				"c61cf43e001f9137f23c2c409273eb16e6537a576782" +
   160  				"eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3" +
   161  				"c1e0908ef7bac"),
   162  			addrs: []btcutil.Address{
   163  				newAddressPubKey(hexToBytes("04b0bd634234abbb" +
   164  					"1ba1e986e884185c61cf43e001f9137f23c2" +
   165  					"c409273eb16e6537a576782eba668a7ef8bd" +
   166  					"3b3cfb1edb7117ab65129b8a2e681f3c1e09" +
   167  					"08ef7b")),
   168  			},
   169  			reqSigs: 1,
   170  			class:   PubKeyTy,
   171  		},
   172  		{
   173  			name: "standard p2pk with hybrid pubkey (0x07)",
   174  			script: hexToBytes("4107b0bd634234abbb1ba1e986e884185" +
   175  				"c61cf43e001f9137f23c2c409273eb16e6537a576782" +
   176  				"eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3" +
   177  				"c1e0908ef7bac"),
   178  			addrs: []btcutil.Address{
   179  				newAddressPubKey(hexToBytes("07b0bd634234abbb" +
   180  					"1ba1e986e884185c61cf43e001f9137f23c2" +
   181  					"c409273eb16e6537a576782eba668a7ef8bd" +
   182  					"3b3cfb1edb7117ab65129b8a2e681f3c1e09" +
   183  					"08ef7b")),
   184  			},
   185  			reqSigs: 1,
   186  			class:   PubKeyTy,
   187  		},
   188  		{
   189  			name: "standard p2pkh",
   190  			script: hexToBytes("76a914ad06dd6ddee55cbca9a9e3713bd" +
   191  				"7587509a3056488ac"),
   192  			addrs: []btcutil.Address{
   193  				newAddressPubKeyHash(hexToBytes("ad06dd6ddee5" +
   194  					"5cbca9a9e3713bd7587509a30564")),
   195  			},
   196  			reqSigs: 1,
   197  			class:   PubKeyHashTy,
   198  		},
   199  		{
   200  			name: "standard p2sh",
   201  			script: hexToBytes("a91463bcc565f9e68ee0189dd5cc67f1b" +
   202  				"0e5f02f45cb87"),
   203  			addrs: []btcutil.Address{
   204  				newAddressScriptHash(hexToBytes("63bcc565f9e6" +
   205  					"8ee0189dd5cc67f1b0e5f02f45cb")),
   206  			},
   207  			reqSigs: 1,
   208  			class:   ScriptHashTy,
   209  		},
   210  		// from real tx 60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1, vout 0
   211  		{
   212  			name: "standard 1 of 2 multisig",
   213  			script: hexToBytes("514104cc71eb30d653c0c3163990c47b9" +
   214  				"76f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a47" +
   215  				"3e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d1" +
   216  				"1fcdd0d348ac4410461cbdcc5409fb4b4d42b51d3338" +
   217  				"1354d80e550078cb532a34bfa2fcfdeb7d76519aecc6" +
   218  				"2770f5b0e4ef8551946d8a540911abe3e7854a26f39f" +
   219  				"58b25c15342af52ae"),
   220  			addrs: []btcutil.Address{
   221  				newAddressPubKey(hexToBytes("04cc71eb30d653c0" +
   222  					"c3163990c47b976f3fb3f37cccdcbedb169a" +
   223  					"1dfef58bbfbfaff7d8a473e7e2e6d317b87b" +
   224  					"afe8bde97e3cf8f065dec022b51d11fcdd0d" +
   225  					"348ac4")),
   226  				newAddressPubKey(hexToBytes("0461cbdcc5409fb4" +
   227  					"b4d42b51d33381354d80e550078cb532a34b" +
   228  					"fa2fcfdeb7d76519aecc62770f5b0e4ef855" +
   229  					"1946d8a540911abe3e7854a26f39f58b25c1" +
   230  					"5342af")),
   231  			},
   232  			reqSigs: 1,
   233  			class:   MultiSigTy,
   234  		},
   235  		// from real tx d646f82bd5fbdb94a36872ce460f97662b80c3050ad3209bef9d1e398ea277ab, vin 1
   236  		{
   237  			name: "standard 2 of 3 multisig",
   238  			script: hexToBytes("524104cb9c3c222c5f7a7d3b9bd152f36" +
   239  				"3a0b6d54c9eb312c4d4f9af1e8551b6c421a6a4ab0e2" +
   240  				"9105f24de20ff463c1c91fcf3bf662cdde4783d4799f" +
   241  				"787cb7c08869b4104ccc588420deeebea22a7e900cc8" +
   242  				"b68620d2212c374604e3487ca08f1ff3ae12bdc63951" +
   243  				"4d0ec8612a2d3c519f084d9a00cbbe3b53d071e9b09e" +
   244  				"71e610b036aa24104ab47ad1939edcb3db65f7fedea6" +
   245  				"2bbf781c5410d3f22a7a3a56ffefb2238af8627363bd" +
   246  				"f2ed97c1f89784a1aecdb43384f11d2acc64443c7fc2" +
   247  				"99cef0400421a53ae"),
   248  			addrs: []btcutil.Address{
   249  				newAddressPubKey(hexToBytes("04cb9c3c222c5f7a" +
   250  					"7d3b9bd152f363a0b6d54c9eb312c4d4f9af" +
   251  					"1e8551b6c421a6a4ab0e29105f24de20ff46" +
   252  					"3c1c91fcf3bf662cdde4783d4799f787cb7c" +
   253  					"08869b")),
   254  				newAddressPubKey(hexToBytes("04ccc588420deeeb" +
   255  					"ea22a7e900cc8b68620d2212c374604e3487" +
   256  					"ca08f1ff3ae12bdc639514d0ec8612a2d3c5" +
   257  					"19f084d9a00cbbe3b53d071e9b09e71e610b" +
   258  					"036aa2")),
   259  				newAddressPubKey(hexToBytes("04ab47ad1939edcb" +
   260  					"3db65f7fedea62bbf781c5410d3f22a7a3a5" +
   261  					"6ffefb2238af8627363bdf2ed97c1f89784a" +
   262  					"1aecdb43384f11d2acc64443c7fc299cef04" +
   263  					"00421a")),
   264  			},
   265  			reqSigs: 2,
   266  			class:   MultiSigTy,
   267  		},
   268  
   269  		// The below are nonstandard script due to things such as
   270  		// invalid pubkeys, failure to parse, and not being of a
   271  		// standard form.
   272  
   273  		{
   274  			name: "p2pk with uncompressed pk missing OP_CHECKSIG",
   275  			script: hexToBytes("410411db93e1dcdb8a016b49840f8c53b" +
   276  				"c1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddf" +
   277  				"b84ccf9744464f82e160bfa9b8b64f9d4c03f999b864" +
   278  				"3f656b412a3"),
   279  			addrs:   nil,
   280  			reqSigs: 0,
   281  			class:   NonStandardTy,
   282  		},
   283  		{
   284  			name: "valid signature from a sigscript - no addresses",
   285  			script: hexToBytes("47304402204e45e16932b8af514961a1d" +
   286  				"3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd41022" +
   287  				"0181522ec8eca07de4860a4acdd12909d831cc56cbba" +
   288  				"c4622082221a8768d1d0901"),
   289  			addrs:   nil,
   290  			reqSigs: 0,
   291  			class:   NonStandardTy,
   292  		},
   293  		// Note the technically the pubkey is the second item on the
   294  		// stack, but since the address extraction intentionally only
   295  		// works with standard PkScripts, this should not return any
   296  		// addresses.
   297  		{
   298  			name: "valid sigscript to reedeem p2pk - no addresses",
   299  			script: hexToBytes("493046022100ddc69738bf2336318e4e0" +
   300  				"41a5a77f305da87428ab1606f023260017854350ddc0" +
   301  				"22100817af09d2eec36862d16009852b7e3a0f6dd765" +
   302  				"98290b7834e1453660367e07a014104cd4240c198e12" +
   303  				"523b6f9cb9f5bed06de1ba37e96a1bbd13745fcf9d11" +
   304  				"c25b1dff9a519675d198804ba9962d3eca2d5937d58e" +
   305  				"5a75a71042d40388a4d307f887d"),
   306  			addrs:   nil,
   307  			reqSigs: 0,
   308  			class:   NonStandardTy,
   309  		},
   310  		// from real tx 691dd277dc0e90a462a3d652a1171686de49cf19067cd33c7df0392833fb986a, vout 0
   311  		// invalid public keys
   312  		{
   313  			name: "1 of 3 multisig with invalid pubkeys",
   314  			script: hexToBytes("51411c2200007353455857696b696c656" +
   315  				"16b73204361626c6567617465204261636b75700a0a6" +
   316  				"361626c65676174652d3230313031323034313831312" +
   317  				"e377a0a0a446f41776e6c6f61642074686520666f6c6" +
   318  				"c6f77696e67207472616e73616374696f6e732077697" +
   319  				"468205361746f736869204e616b616d6f746f2773206" +
   320  				"46f776e6c6f61416420746f6f6c2077686963680a636" +
   321  				"16e20626520666f756e6420696e207472616e7361637" +
   322  				"4696f6e2036633533636439383731313965663739376" +
   323  				"435616463636453ae"),
   324  			addrs:   []btcutil.Address{},
   325  			reqSigs: 1,
   326  			class:   MultiSigTy,
   327  		},
   328  		{
   329  			name: "v1 p2tr witness-script-hash",
   330  			script: hexToBytes("51201a82f7457a9ba6ab1074e9f50" +
   331  				"053eefc637f8b046e389b636766bdc7d1f676f8"),
   332  			addrs: []btcutil.Address{newAddressTaproot(
   333  				hexToBytes("1a82f7457a9ba6ab1074e9f50053eefc6" +
   334  					"37f8b046e389b636766bdc7d1f676f8"))},
   335  			reqSigs: 1,
   336  			class:   WitnessV1TaprootTy,
   337  		},
   338  		{
   339  			name: "1 of 3 multisig with invalid pubkeys 2",
   340  			script: hexToBytes("514134633365633235396337346461636" +
   341  				"536666430383862343463656638630a6336366263313" +
   342  				"93936633862393461333831316233363536313866653" +
   343  				"16539623162354136636163636539393361333938386" +
   344  				"134363966636336643664616266640a3236363363666" +
   345  				"13963663463303363363039633539336333653931666" +
   346  				"56465373032392131323364643432643235363339643" +
   347  				"338613663663530616234636434340a00000053ae"),
   348  			addrs:   []btcutil.Address{},
   349  			reqSigs: 1,
   350  			class:   MultiSigTy,
   351  		},
   352  		{
   353  			name:    "empty script",
   354  			script:  []byte{},
   355  			addrs:   nil,
   356  			reqSigs: 0,
   357  			class:   NonStandardTy,
   358  		},
   359  		{
   360  			name:    "script that does not parse",
   361  			script:  []byte{OP_DATA_45},
   362  			addrs:   nil,
   363  			reqSigs: 0,
   364  			class:   NonStandardTy,
   365  		},
   366  	}
   367  
   368  	t.Logf("Running %d tests.", len(tests))
   369  	for i, test := range tests {
   370  		class, addrs, reqSigs, err := ExtractPkScriptAddrs(
   371  			test.script, &chaincfg.MainNetParams)
   372  		if err != nil {
   373  		}
   374  
   375  		if !reflect.DeepEqual(addrs, test.addrs) {
   376  			t.Errorf("ExtractPkScriptAddrs #%d (%s) unexpected "+
   377  				"addresses\ngot  %v\nwant %v", i, test.name,
   378  				addrs, test.addrs)
   379  			continue
   380  		}
   381  
   382  		if reqSigs != test.reqSigs {
   383  			t.Errorf("ExtractPkScriptAddrs #%d (%s) unexpected "+
   384  				"number of required signatures - got %d, "+
   385  				"want %d", i, test.name, reqSigs, test.reqSigs)
   386  			continue
   387  		}
   388  
   389  		if class != test.class {
   390  			t.Errorf("ExtractPkScriptAddrs #%d (%s) unexpected "+
   391  				"script type - got %s, want %s", i, test.name,
   392  				class, test.class)
   393  			continue
   394  		}
   395  	}
   396  }
   397  
   398  // TestCalcScriptInfo ensures the CalcScriptInfo provides the expected results
   399  // for various valid and invalid script pairs.
   400  func TestCalcScriptInfo(t *testing.T) {
   401  	t.Parallel()
   402  
   403  	tests := []struct {
   404  		name      string
   405  		sigScript string
   406  		pkScript  string
   407  		witness   []string
   408  
   409  		bip16  bool
   410  		segwit bool
   411  
   412  		scriptInfo    ScriptInfo
   413  		scriptInfoErr error
   414  	}{
   415  		{
   416  			// Invented scripts, the hashes do not match
   417  			// Truncated version of test below:
   418  			name: "pkscript doesn't parse",
   419  			sigScript: "1 81 DATA_8 2DUP EQUAL NOT VERIFY ABS " +
   420  				"SWAP ABS EQUAL",
   421  			pkScript: "HASH160 DATA_20 0xfe441065b6532231de2fac56" +
   422  				"3152205ec4f59c",
   423  			bip16:         true,
   424  			scriptInfoErr: scriptError(ErrMalformedPush, ""),
   425  		},
   426  		{
   427  			name: "sigScript doesn't parse",
   428  			// Truncated version of p2sh script below.
   429  			sigScript: "1 81 DATA_8 2DUP EQUAL NOT VERIFY ABS " +
   430  				"SWAP ABS",
   431  			pkScript: "HASH160 DATA_20 0xfe441065b6532231de2fac56" +
   432  				"3152205ec4f59c74 EQUAL",
   433  			bip16:         true,
   434  			scriptInfoErr: scriptError(ErrMalformedPush, ""),
   435  		},
   436  		{
   437  			// Invented scripts, the hashes do not match
   438  			name: "p2sh standard script",
   439  			sigScript: "1 81 DATA_25 DUP HASH160 DATA_20 0x010203" +
   440  				"0405060708090a0b0c0d0e0f1011121314 EQUALVERIFY " +
   441  				"CHECKSIG",
   442  			pkScript: "HASH160 DATA_20 0xfe441065b6532231de2fac56" +
   443  				"3152205ec4f59c74 EQUAL",
   444  			bip16: true,
   445  			scriptInfo: ScriptInfo{
   446  				PkScriptClass:  ScriptHashTy,
   447  				NumInputs:      3,
   448  				ExpectedInputs: 3, // nonstandard p2sh.
   449  				SigOps:         1,
   450  			},
   451  		},
   452  		{
   453  			// from 567a53d1ce19ce3d07711885168484439965501536d0d0294c5d46d46c10e53b
   454  			// from the blockchain.
   455  			name: "p2sh nonstandard script",
   456  			sigScript: "1 81 DATA_8 2DUP EQUAL NOT VERIFY ABS " +
   457  				"SWAP ABS EQUAL",
   458  			pkScript: "HASH160 DATA_20 0xfe441065b6532231de2fac56" +
   459  				"3152205ec4f59c74 EQUAL",
   460  			bip16: true,
   461  			scriptInfo: ScriptInfo{
   462  				PkScriptClass:  ScriptHashTy,
   463  				NumInputs:      3,
   464  				ExpectedInputs: -1, // nonstandard p2sh.
   465  				SigOps:         0,
   466  			},
   467  		},
   468  		{
   469  			// Script is invented, numbers all fake.
   470  			name: "multisig script",
   471  			// Extra 0 arg on the end for OP_CHECKMULTISIG bug.
   472  			sigScript: "1 1 1 0",
   473  			pkScript: "3 " +
   474  				"DATA_33 0x0102030405060708090a0b0c0d0e0f1011" +
   475  				"12131415161718191a1b1c1d1e1f2021 DATA_33 " +
   476  				"0x0102030405060708090a0b0c0d0e0f101112131415" +
   477  				"161718191a1b1c1d1e1f2021 DATA_33 0x010203040" +
   478  				"5060708090a0b0c0d0e0f101112131415161718191a1" +
   479  				"b1c1d1e1f2021 3 CHECKMULTISIG",
   480  			bip16: true,
   481  			scriptInfo: ScriptInfo{
   482  				PkScriptClass:  MultiSigTy,
   483  				NumInputs:      4,
   484  				ExpectedInputs: 4,
   485  				SigOps:         3,
   486  			},
   487  		},
   488  		{
   489  			// A v0 p2wkh spend.
   490  			name:     "p2wkh script",
   491  			pkScript: "OP_0 DATA_20 0x365ab47888e150ff46f8d51bce36dcd680f1283f",
   492  			witness: []string{
   493  				"3045022100ee9fe8f9487afa977" +
   494  					"6647ebcf0883ce0cd37454d7ce19889d34ba2c9" +
   495  					"9ce5a9f402200341cb469d0efd3955acb9e46" +
   496  					"f568d7e2cc10f9084aaff94ced6dc50a59134ad01",
   497  				"03f0000d0639a22bfaf217e4c9428" +
   498  					"9c2b0cc7fa1036f7fd5d9f61a9d6ec153100e",
   499  			},
   500  			segwit: true,
   501  			scriptInfo: ScriptInfo{
   502  				PkScriptClass:  WitnessV0PubKeyHashTy,
   503  				NumInputs:      2,
   504  				ExpectedInputs: 2,
   505  				SigOps:         1,
   506  			},
   507  		},
   508  		{
   509  			// Nested p2sh v0
   510  			name: "p2wkh nested inside p2sh",
   511  			pkScript: "HASH160 DATA_20 " +
   512  				"0xb3a84b564602a9d68b4c9f19c2ea61458ff7826c EQUAL",
   513  			sigScript: "DATA_22 0x0014ad0ffa2e387f07e7ead14dc56d5a97dbd6ff5a23",
   514  			witness: []string{
   515  				"3045022100cb1c2ac1ff1d57d" +
   516  					"db98f7bdead905f8bf5bcc8641b029ce8eef25" +
   517  					"c75a9e22a4702203be621b5c86b771288706be5" +
   518  					"a7eee1db4fceabf9afb7583c1cc6ee3f8297b21201",
   519  				"03f0000d0639a22bfaf217e4c9" +
   520  					"4289c2b0cc7fa1036f7fd5d9f61a9d6ec153100e",
   521  			},
   522  			segwit: true,
   523  			bip16:  true,
   524  			scriptInfo: ScriptInfo{
   525  				PkScriptClass:  ScriptHashTy,
   526  				NumInputs:      3,
   527  				ExpectedInputs: 3,
   528  				SigOps:         1,
   529  			},
   530  		},
   531  		{
   532  			// A v0 p2wsh spend.
   533  			name: "p2wsh spend of a p2wkh witness script",
   534  			pkScript: "0 DATA_32 0xe112b88a0cd87ba387f44" +
   535  				"9d443ee2596eb353beb1f0351ab2cba8909d875db23",
   536  			witness: []string{
   537  				"3045022100cb1c2ac1ff1d57d" +
   538  					"db98f7bdead905f8bf5bcc8641b029ce8eef25" +
   539  					"c75a9e22a4702203be621b5c86b771288706be5" +
   540  					"a7eee1db4fceabf9afb7583c1cc6ee3f8297b21201",
   541  				"03f0000d0639a22bfaf217e4c9" +
   542  					"4289c2b0cc7fa1036f7fd5d9f61a9d6ec153100e",
   543  				"76a914064977cb7b4a2e0c9680df0ef696e9e0e296b39988ac",
   544  			},
   545  			segwit: true,
   546  			scriptInfo: ScriptInfo{
   547  				PkScriptClass:  WitnessV0ScriptHashTy,
   548  				NumInputs:      3,
   549  				ExpectedInputs: 3,
   550  				SigOps:         1,
   551  			},
   552  		},
   553  	}
   554  
   555  	for _, test := range tests {
   556  		sigScript := mustParseShortForm(test.sigScript)
   557  		pkScript := mustParseShortForm(test.pkScript)
   558  
   559  		var witness wire.TxWitness
   560  
   561  		for _, witElement := range test.witness {
   562  			wit, err := hex.DecodeString(witElement)
   563  			if err != nil {
   564  				t.Fatalf("unable to decode witness "+
   565  					"element: %v", err)
   566  			}
   567  
   568  			witness = append(witness, wit)
   569  		}
   570  
   571  		si, err := CalcScriptInfo(sigScript, pkScript, witness,
   572  			test.bip16, test.segwit)
   573  		if e := tstCheckScriptError(err, test.scriptInfoErr); e != nil {
   574  			t.Errorf("scriptinfo test %q: %v", test.name, e)
   575  			continue
   576  		}
   577  		if err != nil {
   578  			continue
   579  		}
   580  
   581  		if *si != test.scriptInfo {
   582  			t.Errorf("%s: scriptinfo doesn't match expected. "+
   583  				"got: %q expected %q", test.name, *si,
   584  				test.scriptInfo)
   585  			continue
   586  		}
   587  	}
   588  }
   589  
   590  // bogusAddress implements the btcutil.Address interface so the tests can ensure
   591  // unsupported address types are handled properly.
   592  type bogusAddress struct{}
   593  
   594  // EncodeAddress simply returns an empty string.  It exists to satisfy the
   595  // btcutil.Address interface.
   596  func (b *bogusAddress) EncodeAddress() string {
   597  	return ""
   598  }
   599  
   600  // ScriptAddress simply returns an empty byte slice.  It exists to satisfy the
   601  // btcutil.Address interface.
   602  func (b *bogusAddress) ScriptAddress() []byte {
   603  	return nil
   604  }
   605  
   606  // IsForNet lies blatantly to satisfy the btcutil.Address interface.
   607  func (b *bogusAddress) IsForNet(chainParams *chaincfg.Params) bool {
   608  	return true // why not?
   609  }
   610  
   611  // String simply returns an empty string.  It exists to satisfy the
   612  // btcutil.Address interface.
   613  func (b *bogusAddress) String() string {
   614  	return ""
   615  }
   616  
   617  // TestPayToAddrScript ensures the PayToAddrScript function generates the
   618  // correct scripts for the various types of addresses.
   619  func TestPayToAddrScript(t *testing.T) {
   620  	t.Parallel()
   621  
   622  	// 1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gX
   623  	p2pkhMain, err := btcutil.NewAddressPubKeyHash(hexToBytes("e34cce70c86"+
   624  		"373273efcc54ce7d2a491bb4a0e84"), &chaincfg.MainNetParams)
   625  	if err != nil {
   626  		t.Fatalf("Unable to create public key hash address: %v", err)
   627  	}
   628  
   629  	// Taken from transaction:
   630  	// b0539a45de13b3e0403909b8bd1a555b8cbe45fd4e3f3fda76f3a5f52835c29d
   631  	p2shMain, _ := btcutil.NewAddressScriptHashFromHash(hexToBytes("e8c300"+
   632  		"c87986efa84c37c0519929019ef86eb5b4"), &chaincfg.MainNetParams)
   633  	if err != nil {
   634  		t.Fatalf("Unable to create script hash address: %v", err)
   635  	}
   636  
   637  	//  mainnet p2pk 13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg
   638  	p2pkCompressedMain, err := btcutil.NewAddressPubKey(hexToBytes("02192d"+
   639  		"74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4"),
   640  		&chaincfg.MainNetParams)
   641  	if err != nil {
   642  		t.Fatalf("Unable to create pubkey address (compressed): %v",
   643  			err)
   644  	}
   645  	p2pkCompressed2Main, err := btcutil.NewAddressPubKey(hexToBytes("03b0b"+
   646  		"d634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65"),
   647  		&chaincfg.MainNetParams)
   648  	if err != nil {
   649  		t.Fatalf("Unable to create pubkey address (compressed 2): %v",
   650  			err)
   651  	}
   652  
   653  	p2pkUncompressedMain, err := btcutil.NewAddressPubKey(hexToBytes("0411"+
   654  		"db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5"+
   655  		"cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b4"+
   656  		"12a3"), &chaincfg.MainNetParams)
   657  	if err != nil {
   658  		t.Fatalf("Unable to create pubkey address (uncompressed): %v",
   659  			err)
   660  	}
   661  
   662  	p2wsh, err := btcutil.NewAddressWitnessScriptHash(hexToBytes("e981bd992a43650657"+
   663  		"d705ef7a30b2adc75a927ed42a4cf6b3da0f865a475fb4"), &chaincfg.MainNetParams)
   664  	if err != nil {
   665  		t.Fatalf("Unable to create p2wsh address: %v",
   666  			err)
   667  	}
   668  
   669  	p2tr, err := btcutil.NewAddressTaproot(hexToBytes("3a8e170b546c3b122ab9c175e"+
   670  		"ff36fb344db2684fe96497eb51b440e75232709"), &chaincfg.MainNetParams)
   671  	if err != nil {
   672  		t.Fatalf("Unable to create p2tr address: %v",
   673  			err)
   674  	}
   675  
   676  	p2wpkh, err := btcutil.NewAddressWitnessPubKeyHash(hexToBytes("748e50366adb8"+
   677  		"ae4b0255e406a28f99d24b73cbc"), &chaincfg.MainNetParams)
   678  	if err != nil {
   679  		t.Fatalf("Unable to create p2wpkh address: %v",
   680  			err)
   681  	}
   682  
   683  	// Errors used in the tests below defined here for convenience and to
   684  	// keep the horizontal test size shorter.
   685  	errUnsupportedAddress := scriptError(ErrUnsupportedAddress, "")
   686  
   687  	tests := []struct {
   688  		in       btcutil.Address
   689  		expected string
   690  		err      error
   691  	}{
   692  		// pay-to-pubkey-hash address on mainnet
   693  		{
   694  			p2pkhMain,
   695  			"DUP HASH160 DATA_20 0xe34cce70c86373273efcc54ce7d2a4" +
   696  				"91bb4a0e8488 CHECKSIG",
   697  			nil,
   698  		},
   699  		// pay-to-script-hash address on mainnet
   700  		{
   701  			p2shMain,
   702  			"HASH160 DATA_20 0xe8c300c87986efa84c37c0519929019ef8" +
   703  				"6eb5b4 EQUAL",
   704  			nil,
   705  		},
   706  		// pay-to-pubkey address on mainnet. compressed key.
   707  		{
   708  			p2pkCompressedMain,
   709  			"DATA_33 0x02192d74d0cb94344c9569c2e77901573d8d7903c3" +
   710  				"ebec3a957724895dca52c6b4 CHECKSIG",
   711  			nil,
   712  		},
   713  		// pay-to-pubkey address on mainnet. compressed key (other way).
   714  		{
   715  			p2pkCompressed2Main,
   716  			"DATA_33 0x03b0bd634234abbb1ba1e986e884185c61cf43e001" +
   717  				"f9137f23c2c409273eb16e65 CHECKSIG",
   718  			nil,
   719  		},
   720  		// pay-to-pubkey address on mainnet. uncompressed key.
   721  		{
   722  			p2pkUncompressedMain,
   723  			"DATA_65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382e" +
   724  				"97b1482ecad7b148a6909a5cb2e0eaddfb84ccf97444" +
   725  				"64f82e160bfa9b8b64f9d4c03f999b8643f656b412a3 " +
   726  				"CHECKSIG",
   727  			nil,
   728  		},
   729  		// pay-to-witness-script-hash address on mainnet.
   730  		{
   731  			p2wsh,
   732  			"OP_0 DATA_32 0xe981bd992a43650657d705ef7a30b2adc75a927ed" +
   733  				"42a4cf6b3da0f865a475fb4",
   734  			nil,
   735  		},
   736  		// pay-to-taproot address on mainnet.
   737  		{
   738  			p2tr,
   739  			"OP_1 DATA_32 0x3a8e170b546c3b122ab9c175eff36fb344db2684" +
   740  				"fe96497eb51b440e75232709",
   741  			nil,
   742  		},
   743  		// pay-to-witness-pubkey-hash address on mainnet.
   744  		{
   745  			p2wpkh,
   746  			"OP_0 DATA_20 0x748e50366adb8ae4b0255e406a28f99d24b73cbc",
   747  			nil,
   748  		},
   749  
   750  		// Supported address types with nil pointers.
   751  		{(*btcutil.AddressPubKeyHash)(nil), "", errUnsupportedAddress},
   752  		{(*btcutil.AddressScriptHash)(nil), "", errUnsupportedAddress},
   753  		{(*btcutil.AddressPubKey)(nil), "", errUnsupportedAddress},
   754  		{(*btcutil.AddressWitnessPubKeyHash)(nil), "", errUnsupportedAddress},
   755  		{(*btcutil.AddressWitnessScriptHash)(nil), "", errUnsupportedAddress},
   756  		{(*btcutil.AddressTaproot)(nil), "", errUnsupportedAddress},
   757  
   758  		// Unsupported address type.
   759  		{&bogusAddress{}, "", errUnsupportedAddress},
   760  	}
   761  
   762  	t.Logf("Running %d tests", len(tests))
   763  	for i, test := range tests {
   764  		pkScript, err := PayToAddrScript(test.in)
   765  		if e := tstCheckScriptError(err, test.err); e != nil {
   766  			t.Errorf("PayToAddrScript #%d unexpected error - "+
   767  				"got %v, want %v", i, err, test.err)
   768  			continue
   769  		}
   770  
   771  		expected := mustParseShortForm(test.expected)
   772  		if !bytes.Equal(pkScript, expected) {
   773  			t.Errorf("PayToAddrScript #%d got: %x\nwant: %x",
   774  				i, pkScript, expected)
   775  			continue
   776  		}
   777  	}
   778  }
   779  
   780  // TestMultiSigScript ensures the MultiSigScript function returns the expected
   781  // scripts and errors.
   782  func TestMultiSigScript(t *testing.T) {
   783  	t.Parallel()
   784  
   785  	//  mainnet p2pk 13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg
   786  	p2pkCompressedMain, err := btcutil.NewAddressPubKey(hexToBytes("02192d"+
   787  		"74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4"),
   788  		&chaincfg.MainNetParams)
   789  	if err != nil {
   790  		t.Fatalf("Unable to create pubkey address (compressed): %v",
   791  			err)
   792  	}
   793  	p2pkCompressed2Main, err := btcutil.NewAddressPubKey(hexToBytes("03b0b"+
   794  		"d634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65"),
   795  		&chaincfg.MainNetParams)
   796  	if err != nil {
   797  		t.Fatalf("Unable to create pubkey address (compressed 2): %v",
   798  			err)
   799  	}
   800  
   801  	p2pkUncompressedMain, err := btcutil.NewAddressPubKey(hexToBytes("0411"+
   802  		"db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5"+
   803  		"cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b4"+
   804  		"12a3"), &chaincfg.MainNetParams)
   805  	if err != nil {
   806  		t.Fatalf("Unable to create pubkey address (uncompressed): %v",
   807  			err)
   808  	}
   809  
   810  	tests := []struct {
   811  		keys      []*btcutil.AddressPubKey
   812  		nrequired int
   813  		expected  string
   814  		err       error
   815  	}{
   816  		{
   817  			[]*btcutil.AddressPubKey{
   818  				p2pkCompressedMain,
   819  				p2pkCompressed2Main,
   820  			},
   821  			1,
   822  			"1 DATA_33 0x02192d74d0cb94344c9569c2e77901573d8d7903c" +
   823  				"3ebec3a957724895dca52c6b4 DATA_33 0x03b0bd634" +
   824  				"234abbb1ba1e986e884185c61cf43e001f9137f23c2c4" +
   825  				"09273eb16e65 2 CHECKMULTISIG",
   826  			nil,
   827  		},
   828  		{
   829  			[]*btcutil.AddressPubKey{
   830  				p2pkCompressedMain,
   831  				p2pkCompressed2Main,
   832  			},
   833  			2,
   834  			"2 DATA_33 0x02192d74d0cb94344c9569c2e77901573d8d7903c" +
   835  				"3ebec3a957724895dca52c6b4 DATA_33 0x03b0bd634" +
   836  				"234abbb1ba1e986e884185c61cf43e001f9137f23c2c4" +
   837  				"09273eb16e65 2 CHECKMULTISIG",
   838  			nil,
   839  		},
   840  		{
   841  			[]*btcutil.AddressPubKey{
   842  				p2pkCompressedMain,
   843  				p2pkCompressed2Main,
   844  			},
   845  			3,
   846  			"",
   847  			scriptError(ErrTooManyRequiredSigs, ""),
   848  		},
   849  		{
   850  			[]*btcutil.AddressPubKey{
   851  				p2pkUncompressedMain,
   852  			},
   853  			1,
   854  			"1 DATA_65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382" +
   855  				"e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf97444" +
   856  				"64f82e160bfa9b8b64f9d4c03f999b8643f656b412a3 " +
   857  				"1 CHECKMULTISIG",
   858  			nil,
   859  		},
   860  		{
   861  			[]*btcutil.AddressPubKey{
   862  				p2pkUncompressedMain,
   863  			},
   864  			2,
   865  			"",
   866  			scriptError(ErrTooManyRequiredSigs, ""),
   867  		},
   868  	}
   869  
   870  	t.Logf("Running %d tests", len(tests))
   871  	for i, test := range tests {
   872  		script, err := MultiSigScript(test.keys, test.nrequired)
   873  		if e := tstCheckScriptError(err, test.err); e != nil {
   874  			t.Errorf("MultiSigScript #%d: %v", i, e)
   875  			continue
   876  		}
   877  
   878  		expected := mustParseShortForm(test.expected)
   879  		if !bytes.Equal(script, expected) {
   880  			t.Errorf("MultiSigScript #%d got: %x\nwant: %x",
   881  				i, script, expected)
   882  			continue
   883  		}
   884  	}
   885  }
   886  
   887  // TestCalcMultiSigStats ensures the CalcMutliSigStats function returns the
   888  // expected errors.
   889  func TestCalcMultiSigStats(t *testing.T) {
   890  	t.Parallel()
   891  
   892  	tests := []struct {
   893  		name   string
   894  		script string
   895  		err    error
   896  	}{
   897  		{
   898  			name: "short script",
   899  			script: "0x046708afdb0fe5548271967f1a67130b7105cd6a828" +
   900  				"e03909a67962e0ea1f61d",
   901  			err: scriptError(ErrNotMultisigScript, ""),
   902  		},
   903  		{
   904  			name: "stack underflow",
   905  			script: "RETURN DATA_41 0x046708afdb0fe5548271967f1a" +
   906  				"67130b7105cd6a828e03909a67962e0ea1f61deb649f6" +
   907  				"bc3f4cef308",
   908  			err: scriptError(ErrNotMultisigScript, ""),
   909  		},
   910  		{
   911  			name: "multisig script",
   912  			script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da45329a0" +
   913  				"0357b3a7886211ab414d55a 1 CHECKMULTISIG",
   914  			err: nil,
   915  		},
   916  	}
   917  
   918  	for i, test := range tests {
   919  		script := mustParseShortForm(test.script)
   920  		_, _, err := CalcMultiSigStats(script)
   921  		if e := tstCheckScriptError(err, test.err); e != nil {
   922  			t.Errorf("CalcMultiSigStats #%d (%s): %v", i, test.name,
   923  				e)
   924  			continue
   925  		}
   926  	}
   927  }
   928  
   929  // scriptClassTests houses several test scripts used to ensure various class
   930  // determination is working as expected.  It's defined as a test global versus
   931  // inside a function scope since this spans both the standard tests and the
   932  // consensus tests (pay-to-script-hash is part of consensus).
   933  var scriptClassTests = []struct {
   934  	name   string
   935  	script string
   936  	class  ScriptClass
   937  }{
   938  	{
   939  		name: "Pay Pubkey",
   940  		script: "DATA_65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382e" +
   941  			"97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e16" +
   942  			"0bfa9b8b64f9d4c03f999b8643f656b412a3 CHECKSIG",
   943  		class: PubKeyTy,
   944  	},
   945  	// tx 599e47a8114fe098103663029548811d2651991b62397e057f0c863c2bc9f9ea
   946  	{
   947  		name: "Pay PubkeyHash",
   948  		script: "DUP HASH160 DATA_20 0x660d4ef3a743e3e696ad990364e555" +
   949  			"c271ad504b EQUALVERIFY CHECKSIG",
   950  		class: PubKeyHashTy,
   951  	},
   952  	// part of tx 6d36bc17e947ce00bb6f12f8e7a56a1585c5a36188ffa2b05e10b4743273a74b
   953  	// codeseparator parts have been elided. (bitcoin core's checks for
   954  	// multisig type doesn't have codesep either).
   955  	{
   956  		name: "multisig",
   957  		script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da4" +
   958  			"5329a00357b3a7886211ab414d55a 1 CHECKMULTISIG",
   959  		class: MultiSigTy,
   960  	},
   961  	// tx e5779b9e78f9650debc2893fd9636d827b26b4ddfa6a8172fe8708c924f5c39d
   962  	{
   963  		name: "P2SH",
   964  		script: "HASH160 DATA_20 0x433ec2ac1ffa1b7b7d027f564529c57197f" +
   965  			"9ae88 EQUAL",
   966  		class: ScriptHashTy,
   967  	},
   968  
   969  	{
   970  		// Nulldata with no data at all.
   971  		name:   "nulldata no data",
   972  		script: "RETURN",
   973  		class:  NullDataTy,
   974  	},
   975  	{
   976  		// Nulldata with single zero push.
   977  		name:   "nulldata zero",
   978  		script: "RETURN 0",
   979  		class:  NullDataTy,
   980  	},
   981  	{
   982  		// Nulldata with small integer push.
   983  		name:   "nulldata small int",
   984  		script: "RETURN 1",
   985  		class:  NullDataTy,
   986  	},
   987  	{
   988  		// Nulldata with max small integer push.
   989  		name:   "nulldata max small int",
   990  		script: "RETURN 16",
   991  		class:  NullDataTy,
   992  	},
   993  	{
   994  		// Nulldata with small data push.
   995  		name:   "nulldata small data",
   996  		script: "RETURN DATA_8 0x046708afdb0fe554",
   997  		class:  NullDataTy,
   998  	},
   999  	{
  1000  		// Canonical nulldata with 60-byte data push.
  1001  		name: "canonical nulldata 60-byte push",
  1002  		script: "RETURN 0x3c 0x046708afdb0fe5548271967f1a67130b7105cd" +
  1003  			"6a828e03909a67962e0ea1f61deb649f6bc3f4cef3046708afdb" +
  1004  			"0fe5548271967f1a67130b7105cd6a",
  1005  		class: NullDataTy,
  1006  	},
  1007  	{
  1008  		// Non-canonical nulldata with 60-byte data push.
  1009  		name: "non-canonical nulldata 60-byte push",
  1010  		script: "RETURN PUSHDATA1 0x3c 0x046708afdb0fe5548271967f1a67" +
  1011  			"130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3" +
  1012  			"046708afdb0fe5548271967f1a67130b7105cd6a",
  1013  		class: NullDataTy,
  1014  	},
  1015  	{
  1016  		// Nulldata with max allowed data to be considered standard.
  1017  		name: "nulldata max standard push",
  1018  		script: "RETURN PUSHDATA1 0x50 0x046708afdb0fe5548271967f1a67" +
  1019  			"130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3" +
  1020  			"046708afdb0fe5548271967f1a67130b7105cd6a828e03909a67" +
  1021  			"962e0ea1f61deb649f6bc3f4cef3",
  1022  		class: NullDataTy,
  1023  	},
  1024  	{
  1025  		// Nulldata with more than max allowed data to be considered
  1026  		// standard (so therefore nonstandard)
  1027  		name: "nulldata exceed max standard push",
  1028  		script: "RETURN PUSHDATA1 0x51 0x046708afdb0fe5548271967f1a67" +
  1029  			"130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3" +
  1030  			"046708afdb0fe5548271967f1a67130b7105cd6a828e03909a67" +
  1031  			"962e0ea1f61deb649f6bc3f4cef308",
  1032  		class: NonStandardTy,
  1033  	},
  1034  	{
  1035  		// Almost nulldata, but add an additional opcode after the data
  1036  		// to make it nonstandard.
  1037  		name:   "almost nulldata",
  1038  		script: "RETURN 4 TRUE",
  1039  		class:  NonStandardTy,
  1040  	},
  1041  
  1042  	// The next few are almost multisig (it is the more complex script type)
  1043  	// but with various changes to make it fail.
  1044  	{
  1045  		// Multisig but invalid nsigs.
  1046  		name: "strange 1",
  1047  		script: "DUP DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da45" +
  1048  			"329a00357b3a7886211ab414d55a 1 CHECKMULTISIG",
  1049  		class: NonStandardTy,
  1050  	},
  1051  	{
  1052  		// Multisig but invalid pubkey.
  1053  		name:   "strange 2",
  1054  		script: "1 1 1 CHECKMULTISIG",
  1055  		class:  NonStandardTy,
  1056  	},
  1057  	{
  1058  		// Multisig but no matching npubkeys opcode.
  1059  		name: "strange 3",
  1060  		script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da4532" +
  1061  			"9a00357b3a7886211ab414d55a DATA_33 0x0232abdc893e7f0" +
  1062  			"631364d7fd01cb33d24da45329a00357b3a7886211ab414d55a " +
  1063  			"CHECKMULTISIG",
  1064  		class: NonStandardTy,
  1065  	},
  1066  	{
  1067  		// Multisig but with multisigverify.
  1068  		name: "strange 4",
  1069  		script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da4532" +
  1070  			"9a00357b3a7886211ab414d55a 1 CHECKMULTISIGVERIFY",
  1071  		class: NonStandardTy,
  1072  	},
  1073  	{
  1074  		// Multisig but wrong length.
  1075  		name:   "strange 5",
  1076  		script: "1 CHECKMULTISIG",
  1077  		class:  NonStandardTy,
  1078  	},
  1079  	{
  1080  		name:   "doesn't parse",
  1081  		script: "DATA_5 0x01020304",
  1082  		class:  NonStandardTy,
  1083  	},
  1084  	{
  1085  		name: "multisig script with wrong number of pubkeys",
  1086  		script: "2 " +
  1087  			"DATA_33 " +
  1088  			"0x027adf5df7c965a2d46203c781bd4dd8" +
  1089  			"21f11844136f6673af7cc5a4a05cd29380 " +
  1090  			"DATA_33 " +
  1091  			"0x02c08f3de8ee2de9be7bd770f4c10eb0" +
  1092  			"d6ff1dd81ee96eedd3a9d4aeaf86695e80 " +
  1093  			"3 CHECKMULTISIG",
  1094  		class: NonStandardTy,
  1095  	},
  1096  
  1097  	// New standard segwit script templates.
  1098  	{
  1099  		// A pay to witness pub key hash pk script.
  1100  		name:   "Pay To Witness PubkeyHash",
  1101  		script: "0 DATA_20 0x1d0f172a0ecb48aee1be1f2687d2963ae33f71a1",
  1102  		class:  WitnessV0PubKeyHashTy,
  1103  	},
  1104  	{
  1105  		// A pay to witness scripthash pk script.
  1106  		name:   "Pay To Witness Scripthash",
  1107  		script: "0 DATA_32 0x9f96ade4b41d5433f4eda31e1738ec2b36f6e7d1420d94a6af99801a88f7f7ff",
  1108  		class:  WitnessV0ScriptHashTy,
  1109  	},
  1110  }
  1111  
  1112  // TestScriptClass ensures all the scripts in scriptClassTests have the expected
  1113  // class.
  1114  func TestScriptClass(t *testing.T) {
  1115  	t.Parallel()
  1116  
  1117  	for _, test := range scriptClassTests {
  1118  		script := mustParseShortForm(test.script)
  1119  		class := GetScriptClass(script)
  1120  		if class != test.class {
  1121  			t.Errorf("%s: expected %s got %s (script %x)", test.name,
  1122  				test.class, class, script)
  1123  			continue
  1124  		}
  1125  	}
  1126  }
  1127  
  1128  // TestStringifyClass ensures the script class string returns the expected
  1129  // string for each script class.
  1130  func TestStringifyClass(t *testing.T) {
  1131  	t.Parallel()
  1132  
  1133  	tests := []struct {
  1134  		name     string
  1135  		class    ScriptClass
  1136  		stringed string
  1137  	}{
  1138  		{
  1139  			name:     "nonstandardty",
  1140  			class:    NonStandardTy,
  1141  			stringed: "nonstandard",
  1142  		},
  1143  		{
  1144  			name:     "pubkey",
  1145  			class:    PubKeyTy,
  1146  			stringed: "pubkey",
  1147  		},
  1148  		{
  1149  			name:     "pubkeyhash",
  1150  			class:    PubKeyHashTy,
  1151  			stringed: "pubkeyhash",
  1152  		},
  1153  		{
  1154  			name:     "witnesspubkeyhash",
  1155  			class:    WitnessV0PubKeyHashTy,
  1156  			stringed: "witness_v0_keyhash",
  1157  		},
  1158  		{
  1159  			name:     "scripthash",
  1160  			class:    ScriptHashTy,
  1161  			stringed: "scripthash",
  1162  		},
  1163  		{
  1164  			name:     "witnessscripthash",
  1165  			class:    WitnessV0ScriptHashTy,
  1166  			stringed: "witness_v0_scripthash",
  1167  		},
  1168  		{
  1169  			name:     "multisigty",
  1170  			class:    MultiSigTy,
  1171  			stringed: "multisig",
  1172  		},
  1173  		{
  1174  			name:     "nulldataty",
  1175  			class:    NullDataTy,
  1176  			stringed: "nulldata",
  1177  		},
  1178  		{
  1179  			name:     "broken",
  1180  			class:    ScriptClass(255),
  1181  			stringed: "Invalid",
  1182  		},
  1183  	}
  1184  
  1185  	for _, test := range tests {
  1186  		typeString := test.class.String()
  1187  		if typeString != test.stringed {
  1188  			t.Errorf("%s: got %#q, want %#q", test.name,
  1189  				typeString, test.stringed)
  1190  		}
  1191  	}
  1192  }
  1193  
  1194  // TestNullDataScript tests whether NullDataScript returns a valid script.
  1195  func TestNullDataScript(t *testing.T) {
  1196  	tests := []struct {
  1197  		name     string
  1198  		data     []byte
  1199  		expected []byte
  1200  		err      error
  1201  		class    ScriptClass
  1202  	}{
  1203  		{
  1204  			name:     "small int",
  1205  			data:     hexToBytes("01"),
  1206  			expected: mustParseShortForm("RETURN 1"),
  1207  			err:      nil,
  1208  			class:    NullDataTy,
  1209  		},
  1210  		{
  1211  			name:     "max small int",
  1212  			data:     hexToBytes("10"),
  1213  			expected: mustParseShortForm("RETURN 16"),
  1214  			err:      nil,
  1215  			class:    NullDataTy,
  1216  		},
  1217  		{
  1218  			name: "data of size before OP_PUSHDATA1 is needed",
  1219  			data: hexToBytes("0102030405060708090a0b0c0d0e0f10111" +
  1220  				"2131415161718"),
  1221  			expected: mustParseShortForm("RETURN 0x18 0x01020304" +
  1222  				"05060708090a0b0c0d0e0f101112131415161718"),
  1223  			err:   nil,
  1224  			class: NullDataTy,
  1225  		},
  1226  		{
  1227  			name: "just right",
  1228  			data: hexToBytes("000102030405060708090a0b0c0d0e0f101" +
  1229  				"112131415161718191a1b1c1d1e1f202122232425262" +
  1230  				"728292a2b2c2d2e2f303132333435363738393a3b3c3" +
  1231  				"d3e3f404142434445464748494a4b4c4d4e4f"),
  1232  			expected: mustParseShortForm("RETURN PUSHDATA1 0x50 " +
  1233  				"0x000102030405060708090a0b0c0d0e0f101112131" +
  1234  				"415161718191a1b1c1d1e1f20212223242526272829" +
  1235  				"2a2b2c2d2e2f303132333435363738393a3b3c3d3e3" +
  1236  				"f404142434445464748494a4b4c4d4e4f"),
  1237  			err:   nil,
  1238  			class: NullDataTy,
  1239  		},
  1240  		{
  1241  			name: "too big",
  1242  			data: hexToBytes("000102030405060708090a0b0c0d0e0f101" +
  1243  				"112131415161718191a1b1c1d1e1f202122232425262" +
  1244  				"728292a2b2c2d2e2f303132333435363738393a3b3c3" +
  1245  				"d3e3f404142434445464748494a4b4c4d4e4f50"),
  1246  			expected: nil,
  1247  			err:      scriptError(ErrTooMuchNullData, ""),
  1248  			class:    NonStandardTy,
  1249  		},
  1250  	}
  1251  
  1252  	for i, test := range tests {
  1253  		script, err := NullDataScript(test.data)
  1254  		if e := tstCheckScriptError(err, test.err); e != nil {
  1255  			t.Errorf("NullDataScript: #%d (%s): %v", i, test.name,
  1256  				e)
  1257  			continue
  1258  
  1259  		}
  1260  
  1261  		// Check that the expected result was returned.
  1262  		if !bytes.Equal(script, test.expected) {
  1263  			t.Errorf("NullDataScript: #%d (%s) wrong result\n"+
  1264  				"got: %x\nwant: %x", i, test.name, script,
  1265  				test.expected)
  1266  			continue
  1267  		}
  1268  
  1269  		// Check that the script has the correct type.
  1270  		scriptType := GetScriptClass(script)
  1271  		if scriptType != test.class {
  1272  			t.Errorf("GetScriptClass: #%d (%s) wrong result -- "+
  1273  				"got: %v, want: %v", i, test.name, scriptType,
  1274  				test.class)
  1275  			continue
  1276  		}
  1277  	}
  1278  }
  1279  
  1280  // TestNewScriptClass tests whether NewScriptClass returns a valid ScriptClass.
  1281  func TestNewScriptClass(t *testing.T) {
  1282  	tests := []struct {
  1283  		name       string
  1284  		scriptName string
  1285  		want       *ScriptClass
  1286  		wantErr    error
  1287  	}{
  1288  		{
  1289  			name:       "NewScriptClass - ok",
  1290  			scriptName: NullDataTy.String(),
  1291  			want: func() *ScriptClass {
  1292  				s := NullDataTy
  1293  				return &s
  1294  			}(),
  1295  		},
  1296  		{
  1297  			name:       "NewScriptClass - invalid",
  1298  			scriptName: "foo",
  1299  			wantErr:    ErrUnsupportedScriptType,
  1300  		},
  1301  	}
  1302  	for _, tt := range tests {
  1303  		t.Run(tt.name, func(t *testing.T) {
  1304  			got, err := NewScriptClass(tt.scriptName)
  1305  			if err != nil && !errors.Is(err, tt.wantErr) {
  1306  				t.Errorf("NewScriptClass() error = %v, wantErr %v", err, tt.wantErr)
  1307  				return
  1308  			}
  1309  
  1310  			if !reflect.DeepEqual(got, tt.want) {
  1311  				t.Errorf("NewScriptClass() got = %v, want %v", got, tt.want)
  1312  			}
  1313  		})
  1314  	}
  1315  }