standard_test.go raw

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