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

     1  // Copyright (c) 2013-2015 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package txscript_test
     7  
     8  import (
     9  	"bytes"
    10  	"encoding/hex"
    11  	"reflect"
    12  	"testing"
    13  
    14  	"github.com/BlockABC/godash/chaincfg"
    15  	"github.com/BlockABC/godash/txscript"
    16  	"github.com/BlockABC/godashutil"
    17  )
    18  
    19  // decodeHex decodes the passed hex string and returns the resulting bytes.  It
    20  // panics if an error occurs.  This is only used in the tests as a helper since
    21  // the only way it can fail is if there is an error in the test source code.
    22  func decodeHex(hexStr string) []byte {
    23  	b, err := hex.DecodeString(hexStr)
    24  	if err != nil {
    25  		panic("invalid hex string in test source: err " + err.Error() +
    26  			", hex: " + hexStr)
    27  	}
    28  
    29  	return b
    30  }
    31  
    32  // mustParseShortForm parses the passed short form script and returns the
    33  // resulting bytes.  It panics if an error occurs.  This is only used in the
    34  // tests as a helper since the only way it can fail is if there is an error in
    35  // the test source code.
    36  func mustParseShortForm(script string) []byte {
    37  	s, err := parseShortForm(script)
    38  	if err != nil {
    39  		panic("invalid short form script in test source: err " +
    40  			err.Error() + ", script: " + script)
    41  	}
    42  
    43  	return s
    44  }
    45  
    46  // newAddressPubKey returns a new godashutil.AddressPubKey from the provided
    47  // serialized public key.  It panics if an error occurs.  This is only used in
    48  // the tests as a helper since the only way it can fail is if there is an error
    49  // in the test source code.
    50  func newAddressPubKey(serializedPubKey []byte) godashutil.Address {
    51  	addr, err := godashutil.NewAddressPubKey(serializedPubKey,
    52  		&chaincfg.MainNetParams)
    53  	if err != nil {
    54  		panic("invalid public key in test source")
    55  	}
    56  
    57  	return addr
    58  }
    59  
    60  // newAddressPubKeyHash returns a new godashutil.AddressPubKeyHash 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 newAddressPubKeyHash(pkHash []byte) godashutil.Address {
    65  	addr, err := godashutil.NewAddressPubKeyHash(pkHash, &chaincfg.MainNetParams)
    66  	if err != nil {
    67  		panic("invalid public key hash in test source")
    68  	}
    69  
    70  	return addr
    71  }
    72  
    73  // newAddressScriptHash returns a new godashutil.AddressScriptHash from the
    74  // provided hash.  It panics if an error occurs.  This is only used in the tests
    75  // as a helper since the only way it can fail is if there is an error in the
    76  // test source code.
    77  func newAddressScriptHash(scriptHash []byte) godashutil.Address {
    78  	addr, err := godashutil.NewAddressScriptHashFromHash(scriptHash,
    79  		&chaincfg.MainNetParams)
    80  	if err != nil {
    81  		panic("invalid script hash in test source")
    82  	}
    83  
    84  	return addr
    85  }
    86  
    87  // TestExtractPkScriptAddrs ensures that extracting the type, addresses, and
    88  // number of required signatures from PkScripts works as intended.
    89  func TestExtractPkScriptAddrs(t *testing.T) {
    90  	t.Parallel()
    91  
    92  	tests := []struct {
    93  		name    string
    94  		script  []byte
    95  		addrs   []godashutil.Address
    96  		reqSigs int
    97  		class   txscript.ScriptClass
    98  	}{
    99  		{
   100  			name: "standard p2pk with compressed pubkey (0x02)",
   101  			script: decodeHex("2102192d74d0cb94344c9569c2e7790157" +
   102  				"3d8d7903c3ebec3a957724895dca52c6b4ac"),
   103  			addrs: []godashutil.Address{
   104  				newAddressPubKey(decodeHex("02192d74d0cb94344" +
   105  					"c9569c2e77901573d8d7903c3ebec3a95772" +
   106  					"4895dca52c6b4")),
   107  			},
   108  			reqSigs: 1,
   109  			class:   txscript.PubKeyTy,
   110  		},
   111  		{
   112  			name: "standard p2pk with uncompressed pubkey (0x04)",
   113  			script: decodeHex("410411db93e1dcdb8a016b49840f8c53bc" +
   114  				"1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb" +
   115  				"84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643" +
   116  				"f656b412a3ac"),
   117  			addrs: []godashutil.Address{
   118  				newAddressPubKey(decodeHex("0411db93e1dcdb8a0" +
   119  					"16b49840f8c53bc1eb68a382e97b1482ecad" +
   120  					"7b148a6909a5cb2e0eaddfb84ccf9744464f" +
   121  					"82e160bfa9b8b64f9d4c03f999b8643f656b" +
   122  					"412a3")),
   123  			},
   124  			reqSigs: 1,
   125  			class:   txscript.PubKeyTy,
   126  		},
   127  		{
   128  			name: "standard p2pk with hybrid pubkey (0x06)",
   129  			script: decodeHex("4106192d74d0cb94344c9569c2e7790157" +
   130  				"3d8d7903c3ebec3a957724895dca52c6b40d45264838" +
   131  				"c0bd96852662ce6a847b197376830160c6d2eb5e6a4c" +
   132  				"44d33f453eac"),
   133  			addrs: []godashutil.Address{
   134  				newAddressPubKey(decodeHex("06192d74d0cb94344" +
   135  					"c9569c2e77901573d8d7903c3ebec3a95772" +
   136  					"4895dca52c6b40d45264838c0bd96852662c" +
   137  					"e6a847b197376830160c6d2eb5e6a4c44d33" +
   138  					"f453e")),
   139  			},
   140  			reqSigs: 1,
   141  			class:   txscript.PubKeyTy,
   142  		},
   143  		{
   144  			name: "standard p2pk with compressed pubkey (0x03)",
   145  			script: decodeHex("2103b0bd634234abbb1ba1e986e884185c" +
   146  				"61cf43e001f9137f23c2c409273eb16e65ac"),
   147  			addrs: []godashutil.Address{
   148  				newAddressPubKey(decodeHex("03b0bd634234abbb1" +
   149  					"ba1e986e884185c61cf43e001f9137f23c2c" +
   150  					"409273eb16e65")),
   151  			},
   152  			reqSigs: 1,
   153  			class:   txscript.PubKeyTy,
   154  		},
   155  		{
   156  			name: "2nd standard p2pk with uncompressed pubkey (0x04)",
   157  			script: decodeHex("4104b0bd634234abbb1ba1e986e884185c" +
   158  				"61cf43e001f9137f23c2c409273eb16e6537a576782e" +
   159  				"ba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c" +
   160  				"1e0908ef7bac"),
   161  			addrs: []godashutil.Address{
   162  				newAddressPubKey(decodeHex("04b0bd634234abbb1" +
   163  					"ba1e986e884185c61cf43e001f9137f23c2c" +
   164  					"409273eb16e6537a576782eba668a7ef8bd3" +
   165  					"b3cfb1edb7117ab65129b8a2e681f3c1e090" +
   166  					"8ef7b")),
   167  			},
   168  			reqSigs: 1,
   169  			class:   txscript.PubKeyTy,
   170  		},
   171  		{
   172  			name: "standard p2pk with hybrid pubkey (0x07)",
   173  			script: decodeHex("4107b0bd634234abbb1ba1e986e884185c" +
   174  				"61cf43e001f9137f23c2c409273eb16e6537a576782e" +
   175  				"ba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c" +
   176  				"1e0908ef7bac"),
   177  			addrs: []godashutil.Address{
   178  				newAddressPubKey(decodeHex("07b0bd634234abbb1" +
   179  					"ba1e986e884185c61cf43e001f9137f23c2c" +
   180  					"409273eb16e6537a576782eba668a7ef8bd3" +
   181  					"b3cfb1edb7117ab65129b8a2e681f3c1e090" +
   182  					"8ef7b")),
   183  			},
   184  			reqSigs: 1,
   185  			class:   txscript.PubKeyTy,
   186  		},
   187  		{
   188  			name: "standard p2pkh",
   189  			script: decodeHex("76a914ad06dd6ddee55cbca9a9e3713bd7" +
   190  				"587509a3056488ac"),
   191  			addrs: []godashutil.Address{
   192  				newAddressPubKeyHash(decodeHex("ad06dd6ddee55" +
   193  					"cbca9a9e3713bd7587509a30564")),
   194  			},
   195  			reqSigs: 1,
   196  			class:   txscript.PubKeyHashTy,
   197  		},
   198  		{
   199  			name: "standard p2sh",
   200  			script: decodeHex("a91463bcc565f9e68ee0189dd5cc67f1b0" +
   201  				"e5f02f45cb87"),
   202  			addrs: []godashutil.Address{
   203  				newAddressScriptHash(decodeHex("63bcc565f9e68" +
   204  					"ee0189dd5cc67f1b0e5f02f45cb")),
   205  			},
   206  			reqSigs: 1,
   207  			class:   txscript.ScriptHashTy,
   208  		},
   209  		// from real tx 60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1, vout 0
   210  		{
   211  			name: "standard 1 of 2 multisig",
   212  			script: decodeHex("514104cc71eb30d653c0c3163990c47b97" +
   213  				"6f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473" +
   214  				"e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11" +
   215  				"fcdd0d348ac4410461cbdcc5409fb4b4d42b51d33381" +
   216  				"354d80e550078cb532a34bfa2fcfdeb7d76519aecc62" +
   217  				"770f5b0e4ef8551946d8a540911abe3e7854a26f39f5" +
   218  				"8b25c15342af52ae"),
   219  			addrs: []godashutil.Address{
   220  				newAddressPubKey(decodeHex("04cc71eb30d653c0c" +
   221  					"3163990c47b976f3fb3f37cccdcbedb169a1" +
   222  					"dfef58bbfbfaff7d8a473e7e2e6d317b87ba" +
   223  					"fe8bde97e3cf8f065dec022b51d11fcdd0d3" +
   224  					"48ac4")),
   225  				newAddressPubKey(decodeHex("0461cbdcc5409fb4b" +
   226  					"4d42b51d33381354d80e550078cb532a34bf" +
   227  					"a2fcfdeb7d76519aecc62770f5b0e4ef8551" +
   228  					"946d8a540911abe3e7854a26f39f58b25c15" +
   229  					"342af")),
   230  			},
   231  			reqSigs: 1,
   232  			class:   txscript.MultiSigTy,
   233  		},
   234  		// from real tx d646f82bd5fbdb94a36872ce460f97662b80c3050ad3209bef9d1e398ea277ab, vin 1
   235  		{
   236  			name: "standard 2 of 3 multisig",
   237  			script: decodeHex("524104cb9c3c222c5f7a7d3b9bd152f363" +
   238  				"a0b6d54c9eb312c4d4f9af1e8551b6c421a6a4ab0e29" +
   239  				"105f24de20ff463c1c91fcf3bf662cdde4783d4799f7" +
   240  				"87cb7c08869b4104ccc588420deeebea22a7e900cc8b" +
   241  				"68620d2212c374604e3487ca08f1ff3ae12bdc639514" +
   242  				"d0ec8612a2d3c519f084d9a00cbbe3b53d071e9b09e7" +
   243  				"1e610b036aa24104ab47ad1939edcb3db65f7fedea62" +
   244  				"bbf781c5410d3f22a7a3a56ffefb2238af8627363bdf" +
   245  				"2ed97c1f89784a1aecdb43384f11d2acc64443c7fc29" +
   246  				"9cef0400421a53ae"),
   247  			addrs: []godashutil.Address{
   248  				newAddressPubKey(decodeHex("04cb9c3c222c5f7a7" +
   249  					"d3b9bd152f363a0b6d54c9eb312c4d4f9af1" +
   250  					"e8551b6c421a6a4ab0e29105f24de20ff463" +
   251  					"c1c91fcf3bf662cdde4783d4799f787cb7c0" +
   252  					"8869b")),
   253  				newAddressPubKey(decodeHex("04ccc588420deeebe" +
   254  					"a22a7e900cc8b68620d2212c374604e3487c" +
   255  					"a08f1ff3ae12bdc639514d0ec8612a2d3c51" +
   256  					"9f084d9a00cbbe3b53d071e9b09e71e610b0" +
   257  					"36aa2")),
   258  				newAddressPubKey(decodeHex("04ab47ad1939edcb3" +
   259  					"db65f7fedea62bbf781c5410d3f22a7a3a56" +
   260  					"ffefb2238af8627363bdf2ed97c1f89784a1" +
   261  					"aecdb43384f11d2acc64443c7fc299cef040" +
   262  					"0421a")),
   263  			},
   264  			reqSigs: 2,
   265  			class:   txscript.MultiSigTy,
   266  		},
   267  
   268  		// The below are nonstandard script due to things such as
   269  		// invalid pubkeys, failure to parse, and not being of a
   270  		// standard form.
   271  
   272  		{
   273  			name: "p2pk with uncompressed pk missing OP_CHECKSIG",
   274  			script: decodeHex("410411db93e1dcdb8a016b49840f8c53bc" +
   275  				"1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb" +
   276  				"84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643" +
   277  				"f656b412a3"),
   278  			addrs:   nil,
   279  			reqSigs: 0,
   280  			class:   txscript.NonStandardTy,
   281  		},
   282  		{
   283  			name: "valid signature from a sigscript - no addresses",
   284  			script: decodeHex("47304402204e45e16932b8af514961a1d3" +
   285  				"a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220" +
   286  				"181522ec8eca07de4860a4acdd12909d831cc56cbbac" +
   287  				"4622082221a8768d1d0901"),
   288  			addrs:   nil,
   289  			reqSigs: 0,
   290  			class:   txscript.NonStandardTy,
   291  		},
   292  		// Note the technically the pubkey is the second item on the
   293  		// stack, but since the address extraction intentionally only
   294  		// works with standard PkScripts, this should not return any
   295  		// addresses.
   296  		{
   297  			name: "valid sigscript to reedeem p2pk - no addresses",
   298  			script: decodeHex("493046022100ddc69738bf2336318e4e04" +
   299  				"1a5a77f305da87428ab1606f023260017854350ddc02" +
   300  				"2100817af09d2eec36862d16009852b7e3a0f6dd7659" +
   301  				"8290b7834e1453660367e07a014104cd4240c198e125" +
   302  				"23b6f9cb9f5bed06de1ba37e96a1bbd13745fcf9d11c" +
   303  				"25b1dff9a519675d198804ba9962d3eca2d5937d58e5" +
   304  				"a75a71042d40388a4d307f887d"),
   305  			addrs:   nil,
   306  			reqSigs: 0,
   307  			class:   txscript.NonStandardTy,
   308  		},
   309  		// from real tx 691dd277dc0e90a462a3d652a1171686de49cf19067cd33c7df0392833fb986a, vout 0
   310  		// invalid public keys
   311  		{
   312  			name: "1 of 3 multisig with invalid pubkeys",
   313  			script: decodeHex("51411c2200007353455857696b696c6561" +
   314  				"6b73204361626c6567617465204261636b75700a0a63" +
   315  				"61626c65676174652d3230313031323034313831312e" +
   316  				"377a0a0a446f41776e6c6f61642074686520666f6c6c" +
   317  				"6f77696e67207472616e73616374696f6e7320776974" +
   318  				"68205361746f736869204e616b616d6f746f27732064" +
   319  				"6f776e6c6f61416420746f6f6c2077686963680a6361" +
   320  				"6e20626520666f756e6420696e207472616e73616374" +
   321  				"696f6e20366335336364393837313139656637393764" +
   322  				"35616463636453ae"),
   323  			addrs:   []godashutil.Address{},
   324  			reqSigs: 1,
   325  			class:   txscript.MultiSigTy,
   326  		},
   327  		// from real tx: 691dd277dc0e90a462a3d652a1171686de49cf19067cd33c7df0392833fb986a, vout 44
   328  		// invalid public keys
   329  		{
   330  			name: "1 of 3 multisig with invalid pubkeys 2",
   331  			script: decodeHex("5141346333656332353963373464616365" +
   332  				"36666430383862343463656638630a63363662633139" +
   333  				"39366338623934613338313162333635363138666531" +
   334  				"65396231623541366361636365393933613339383861" +
   335  				"34363966636336643664616266640a32363633636661" +
   336  				"39636634633033633630396335393363336539316665" +
   337  				"64653730323921313233646434326432353633396433" +
   338  				"38613663663530616234636434340a00000053ae"),
   339  			addrs:   []godashutil.Address{},
   340  			reqSigs: 1,
   341  			class:   txscript.MultiSigTy,
   342  		},
   343  		{
   344  			name:    "empty script",
   345  			script:  []byte{},
   346  			addrs:   nil,
   347  			reqSigs: 0,
   348  			class:   txscript.NonStandardTy,
   349  		},
   350  		{
   351  			name:    "script that does not parse",
   352  			script:  []byte{txscript.OP_DATA_45},
   353  			addrs:   nil,
   354  			reqSigs: 0,
   355  			class:   txscript.NonStandardTy,
   356  		},
   357  	}
   358  
   359  	t.Logf("Running %d tests.", len(tests))
   360  	for i, test := range tests {
   361  		class, addrs, reqSigs, err := txscript.ExtractPkScriptAddrs(
   362  			test.script, &chaincfg.MainNetParams)
   363  		if err != nil {
   364  		}
   365  
   366  		if !reflect.DeepEqual(addrs, test.addrs) {
   367  			t.Errorf("ExtractPkScriptAddrs #%d (%s) unexpected "+
   368  				"addresses\ngot  %v\nwant %v", i, test.name,
   369  				addrs, test.addrs)
   370  			continue
   371  		}
   372  
   373  		if reqSigs != test.reqSigs {
   374  			t.Errorf("ExtractPkScriptAddrs #%d (%s) unexpected "+
   375  				"number of required signatures - got %d, "+
   376  				"want %d", i, test.name, reqSigs, test.reqSigs)
   377  			continue
   378  		}
   379  
   380  		if class != test.class {
   381  			t.Errorf("ExtractPkScriptAddrs #%d (%s) unexpected "+
   382  				"script type - got %s, want %s", i, test.name,
   383  				class, test.class)
   384  			continue
   385  		}
   386  	}
   387  }
   388  
   389  // TestCalcScriptInfo ensures the CalcScriptInfo provides the expected results
   390  // for various valid and invalid script pairs.
   391  func TestCalcScriptInfo(t *testing.T) {
   392  	t.Parallel()
   393  
   394  	tests := []struct {
   395  		name          string
   396  		sigScript     string
   397  		pkScript      string
   398  		bip16         bool
   399  		scriptInfo    txscript.ScriptInfo
   400  		scriptInfoErr error
   401  	}{
   402  		{
   403  			// Invented scripts, the hashes do not match
   404  			// Truncated version of test below:
   405  			name: "pkscript doesn't parse",
   406  			sigScript: "1 81 DATA_8 2DUP EQUAL NOT VERIFY ABS " +
   407  				"SWAP ABS EQUAL",
   408  			pkScript: "HASH160 DATA_20 0xfe441065b6532231de2fac56" +
   409  				"3152205ec4f59c",
   410  			bip16:         true,
   411  			scriptInfoErr: txscript.ErrStackShortScript,
   412  		},
   413  		{
   414  			name: "sigScript doesn't parse",
   415  			// Truncated version of p2sh script below.
   416  			sigScript: "1 81 DATA_8 2DUP EQUAL NOT VERIFY ABS " +
   417  				"SWAP ABS",
   418  			pkScript: "HASH160 DATA_20 0xfe441065b6532231de2fac56" +
   419  				"3152205ec4f59c74 EQUAL",
   420  			bip16:         true,
   421  			scriptInfoErr: txscript.ErrStackShortScript,
   422  		},
   423  		{
   424  			// Invented scripts, the hashes do not match
   425  			name: "p2sh standard script",
   426  			sigScript: "1 81 DATA_25 DUP HASH160 DATA_20 0x010203" +
   427  				"0405060708090a0b0c0d0e0f1011121314 EQUALVERIFY " +
   428  				"CHECKSIG",
   429  			pkScript: "HASH160 DATA_20 0xfe441065b6532231de2fac56" +
   430  				"3152205ec4f59c74 EQUAL",
   431  			bip16: true,
   432  			scriptInfo: txscript.ScriptInfo{
   433  				PkScriptClass:  txscript.ScriptHashTy,
   434  				NumInputs:      3,
   435  				ExpectedInputs: 3, // nonstandard p2sh.
   436  				SigOps:         1,
   437  			},
   438  		},
   439  		{
   440  			// from 567a53d1ce19ce3d07711885168484439965501536d0d0294c5d46d46c10e53b
   441  			// from the blockchain.
   442  			name: "p2sh nonstandard script",
   443  			sigScript: "1 81 DATA_8 2DUP EQUAL NOT VERIFY ABS " +
   444  				"SWAP ABS EQUAL",
   445  			pkScript: "HASH160 DATA_20 0xfe441065b6532231de2fac56" +
   446  				"3152205ec4f59c74 EQUAL",
   447  			bip16: true,
   448  			scriptInfo: txscript.ScriptInfo{
   449  				PkScriptClass:  txscript.ScriptHashTy,
   450  				NumInputs:      3,
   451  				ExpectedInputs: -1, // nonstandard p2sh.
   452  				SigOps:         0,
   453  			},
   454  		},
   455  		{
   456  			// Script is invented, numbers all fake.
   457  			name: "multisig script",
   458  			// Extra 0 arg on the end for OP_CHECKMULTISIG bug.
   459  			sigScript: "1 1 1 0",
   460  			pkScript: "3 " +
   461  				"DATA_33 0x0102030405060708090a0b0c0d0e0f1011" +
   462  				"12131415161718191a1b1c1d1e1f2021 DATA_33 " +
   463  				"0x0102030405060708090a0b0c0d0e0f101112131415" +
   464  				"161718191a1b1c1d1e1f2021 DATA_33 0x010203040" +
   465  				"5060708090a0b0c0d0e0f101112131415161718191a1" +
   466  				"b1c1d1e1f2021 3 CHECKMULTISIG",
   467  			bip16: true,
   468  			scriptInfo: txscript.ScriptInfo{
   469  				PkScriptClass:  txscript.MultiSigTy,
   470  				NumInputs:      4,
   471  				ExpectedInputs: 4,
   472  				SigOps:         3,
   473  			},
   474  		},
   475  	}
   476  
   477  	for _, test := range tests {
   478  		sigScript := mustParseShortForm(test.sigScript)
   479  		pkScript := mustParseShortForm(test.pkScript)
   480  		si, err := txscript.CalcScriptInfo(sigScript, pkScript,
   481  			test.bip16)
   482  		if err != nil {
   483  			if err != test.scriptInfoErr {
   484  				t.Errorf("scriptinfo test \"%s\": got \"%v\""+
   485  					"expected \"%v\"", test.name, err,
   486  					test.scriptInfoErr)
   487  			}
   488  			continue
   489  		}
   490  		if test.scriptInfoErr != nil {
   491  			t.Errorf("%s: succeeded when expecting \"%v\"",
   492  				test.name, test.scriptInfoErr)
   493  			continue
   494  		}
   495  		if *si != test.scriptInfo {
   496  			t.Errorf("%s: scriptinfo doesn't match expected. "+
   497  				"got: \"%v\" expected \"%v\"", test.name,
   498  				*si, test.scriptInfo)
   499  			continue
   500  		}
   501  	}
   502  }
   503  
   504  // bogusAddress implements the godashutil.Address interface so the tests can ensure
   505  // unsupported address types are handled properly.
   506  type bogusAddress struct{}
   507  
   508  // EncodeAddress simply returns an empty string.  It exists to satsify the
   509  // godashutil.Address interface.
   510  func (b *bogusAddress) EncodeAddress() string {
   511  	return ""
   512  }
   513  
   514  // ScriptAddress simply returns an empty byte slice.  It exists to satsify the
   515  // godashutil.Address interface.
   516  func (b *bogusAddress) ScriptAddress() []byte {
   517  	return nil
   518  }
   519  
   520  // IsForNet lies blatantly to satisfy the godashutil.Address interface.
   521  func (b *bogusAddress) IsForNet(chainParams *chaincfg.Params) bool {
   522  	return true // why not?
   523  }
   524  
   525  // String simply returns an empty string.  It exists to satsify the
   526  // godashutil.Address interface.
   527  func (b *bogusAddress) String() string {
   528  	return ""
   529  }
   530  
   531  // TestPayToAddrScript ensures the PayToAddrScript function generates the
   532  // correct scripts for the various types of addresses.
   533  func TestPayToAddrScript(t *testing.T) {
   534  	t.Parallel()
   535  
   536  	// 1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gX
   537  	p2pkhMain, err := godashutil.NewAddressPubKeyHash(decodeHex("e34cce70c863"+
   538  		"73273efcc54ce7d2a491bb4a0e84"), &chaincfg.MainNetParams)
   539  	if err != nil {
   540  		t.Errorf("Unable to create public key hash address: %v", err)
   541  		return
   542  	}
   543  
   544  	// Taken from transaction:
   545  	// b0539a45de13b3e0403909b8bd1a555b8cbe45fd4e3f3fda76f3a5f52835c29d
   546  	p2shMain, _ := godashutil.NewAddressScriptHashFromHash(decodeHex("e8c300"+
   547  		"c87986efa84c37c0519929019ef86eb5b4"), &chaincfg.MainNetParams)
   548  	if err != nil {
   549  		t.Errorf("Unable to create script hash address: %v", err)
   550  		return
   551  	}
   552  
   553  	//  mainnet p2pk 13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg
   554  	p2pkCompressedMain, err := godashutil.NewAddressPubKey(decodeHex("02192d74"+
   555  		"d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4"),
   556  		&chaincfg.MainNetParams)
   557  	if err != nil {
   558  		t.Errorf("Unable to create pubkey address (compressed): %v",
   559  			err)
   560  		return
   561  	}
   562  	p2pkCompressed2Main, err := godashutil.NewAddressPubKey(decodeHex("03b0bd"+
   563  		"634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65"),
   564  		&chaincfg.MainNetParams)
   565  	if err != nil {
   566  		t.Errorf("Unable to create pubkey address (compressed 2): %v",
   567  			err)
   568  		return
   569  	}
   570  
   571  	p2pkUncompressedMain, err := godashutil.NewAddressPubKey(decodeHex("0411db"+
   572  		"93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2"+
   573  		"e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3"),
   574  		&chaincfg.MainNetParams)
   575  	if err != nil {
   576  		t.Errorf("Unable to create pubkey address (uncompressed): %v",
   577  			err)
   578  		return
   579  	}
   580  
   581  	tests := []struct {
   582  		in       godashutil.Address
   583  		expected string
   584  		err      error
   585  	}{
   586  		// pay-to-pubkey-hash address on mainnet
   587  		{
   588  			p2pkhMain,
   589  			"DUP HASH160 DATA_20 0xe34cce70c86373273efcc54ce7d2a4" +
   590  				"91bb4a0e8488 CHECKSIG",
   591  			nil,
   592  		},
   593  		// pay-to-script-hash address on mainnet
   594  		{
   595  			p2shMain,
   596  			"HASH160 DATA_20 0xe8c300c87986efa84c37c0519929019ef8" +
   597  				"6eb5b4 EQUAL",
   598  			nil,
   599  		},
   600  		// pay-to-pubkey address on mainnet. compressed key.
   601  		{
   602  			p2pkCompressedMain,
   603  			"DATA_33 0x02192d74d0cb94344c9569c2e77901573d8d7903c3" +
   604  				"ebec3a957724895dca52c6b4 CHECKSIG",
   605  			nil,
   606  		},
   607  		// pay-to-pubkey address on mainnet. compressed key (other way).
   608  		{
   609  			p2pkCompressed2Main,
   610  			"DATA_33 0x03b0bd634234abbb1ba1e986e884185c61cf43e001" +
   611  				"f9137f23c2c409273eb16e65 CHECKSIG",
   612  			nil,
   613  		},
   614  		// pay-to-pubkey address on mainnet. uncompressed key.
   615  		{
   616  			p2pkUncompressedMain,
   617  			"DATA_65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382e" +
   618  				"97b1482ecad7b148a6909a5cb2e0eaddfb84ccf97444" +
   619  				"64f82e160bfa9b8b64f9d4c03f999b8643f656b412a3 " +
   620  				"CHECKSIG",
   621  			nil,
   622  		},
   623  
   624  		// Supported address types with nil pointers.
   625  		{(*godashutil.AddressPubKeyHash)(nil), "", txscript.ErrUnsupportedAddress},
   626  		{(*godashutil.AddressScriptHash)(nil), "", txscript.ErrUnsupportedAddress},
   627  		{(*godashutil.AddressPubKey)(nil), "", txscript.ErrUnsupportedAddress},
   628  
   629  		// Unsupported address type.
   630  		{&bogusAddress{}, "", txscript.ErrUnsupportedAddress},
   631  	}
   632  
   633  	t.Logf("Running %d tests", len(tests))
   634  	for i, test := range tests {
   635  		pkScript, err := txscript.PayToAddrScript(test.in)
   636  		if err != test.err {
   637  			t.Errorf("PayToAddrScript #%d unexpected error - "+
   638  				"got %v, want %v", i, err, test.err)
   639  			continue
   640  		}
   641  
   642  		expected := mustParseShortForm(test.expected)
   643  		if !bytes.Equal(pkScript, expected) {
   644  			t.Errorf("PayToAddrScript #%d got: %x\nwant: %x",
   645  				i, pkScript, expected)
   646  			continue
   647  		}
   648  	}
   649  }
   650  
   651  // TestMultiSigScript ensures the MultiSigScript function returns the expected
   652  // scripts and errors.
   653  func TestMultiSigScript(t *testing.T) {
   654  	t.Parallel()
   655  
   656  	//  mainnet p2pk 13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg
   657  	p2pkCompressedMain, err := godashutil.NewAddressPubKey(decodeHex("02192d7"+
   658  		"4d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4"),
   659  		&chaincfg.MainNetParams)
   660  	if err != nil {
   661  		t.Errorf("Unable to create pubkey address (compressed): %v",
   662  			err)
   663  		return
   664  	}
   665  	p2pkCompressed2Main, err := godashutil.NewAddressPubKey(decodeHex("03b0bd"+
   666  		"634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65"),
   667  		&chaincfg.MainNetParams)
   668  	if err != nil {
   669  		t.Errorf("Unable to create pubkey address (compressed 2): %v",
   670  			err)
   671  		return
   672  	}
   673  
   674  	p2pkUncompressedMain, err := godashutil.NewAddressPubKey(decodeHex("0411d"+
   675  		"b93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c"+
   676  		"b2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b41"+
   677  		"2a3"), &chaincfg.MainNetParams)
   678  	if err != nil {
   679  		t.Errorf("Unable to create pubkey address (uncompressed): %v",
   680  			err)
   681  		return
   682  	}
   683  
   684  	tests := []struct {
   685  		keys      []*godashutil.AddressPubKey
   686  		nrequired int
   687  		expected  string
   688  		err       error
   689  	}{
   690  		{
   691  			[]*godashutil.AddressPubKey{
   692  				p2pkCompressedMain,
   693  				p2pkCompressed2Main,
   694  			},
   695  			1,
   696  			"1 DATA_33 0x02192d74d0cb94344c9569c2e77901573d8d7903c" +
   697  				"3ebec3a957724895dca52c6b4 DATA_33 0x03b0bd634" +
   698  				"234abbb1ba1e986e884185c61cf43e001f9137f23c2c4" +
   699  				"09273eb16e65 2 CHECKMULTISIG",
   700  			nil,
   701  		},
   702  		{
   703  			[]*godashutil.AddressPubKey{
   704  				p2pkCompressedMain,
   705  				p2pkCompressed2Main,
   706  			},
   707  			2,
   708  			"2 DATA_33 0x02192d74d0cb94344c9569c2e77901573d8d7903c" +
   709  				"3ebec3a957724895dca52c6b4 DATA_33 0x03b0bd634" +
   710  				"234abbb1ba1e986e884185c61cf43e001f9137f23c2c4" +
   711  				"09273eb16e65 2 CHECKMULTISIG",
   712  			nil,
   713  		},
   714  		{
   715  			[]*godashutil.AddressPubKey{
   716  				p2pkCompressedMain,
   717  				p2pkCompressed2Main,
   718  			},
   719  			3,
   720  			"",
   721  			txscript.ErrBadNumRequired,
   722  		},
   723  		{
   724  			[]*godashutil.AddressPubKey{
   725  				p2pkUncompressedMain,
   726  			},
   727  			1,
   728  			"1 DATA_65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382" +
   729  				"e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf97444" +
   730  				"64f82e160bfa9b8b64f9d4c03f999b8643f656b412a3 " +
   731  				"1 CHECKMULTISIG",
   732  			nil,
   733  		},
   734  		{
   735  			[]*godashutil.AddressPubKey{
   736  				p2pkUncompressedMain,
   737  			},
   738  			2,
   739  			"",
   740  			txscript.ErrBadNumRequired,
   741  		},
   742  	}
   743  
   744  	t.Logf("Running %d tests", len(tests))
   745  	for i, test := range tests {
   746  		script, err := txscript.MultiSigScript(test.keys,
   747  			test.nrequired)
   748  		if err != test.err {
   749  			t.Errorf("MultiSigScript #%d unexpected error - "+
   750  				"got %v, want %v", i, err, test.err)
   751  			continue
   752  		}
   753  
   754  		expected := mustParseShortForm(test.expected)
   755  		if !bytes.Equal(script, expected) {
   756  			t.Errorf("MultiSigScript #%d got: %x\nwant: %x",
   757  				i, script, expected)
   758  			continue
   759  		}
   760  	}
   761  }
   762  
   763  // TestCalcMultiSigStats ensures the CalcMutliSigStats function returns the
   764  // expected errors.
   765  func TestCalcMultiSigStats(t *testing.T) {
   766  	t.Parallel()
   767  
   768  	tests := []struct {
   769  		name   string
   770  		script string
   771  		err    error
   772  	}{
   773  		{
   774  			name: "short script",
   775  			script: "0x046708afdb0fe5548271967f1a67130b7105cd6a828" +
   776  				"e03909a67962e0ea1f61d",
   777  			err: txscript.ErrStackShortScript,
   778  		},
   779  		{
   780  			name: "stack underflow",
   781  			script: "RETURN DATA_41 0x046708afdb0fe5548271967f1a" +
   782  				"67130b7105cd6a828e03909a67962e0ea1f61deb649f6" +
   783  				"bc3f4cef308",
   784  			err: txscript.ErrStackUnderflow,
   785  		},
   786  		{
   787  			name: "multisig script",
   788  			script: "0 DATA_72 0x30450220106a3e4ef0b51b764a2887226" +
   789  				"2ffef55846514dacbdcbbdd652c849d395b4384022100" +
   790  				"e03ae554c3cbb40600d31dd46fc33f25e47bf8525b1fe" +
   791  				"07282e3b6ecb5f3bb2801 CODESEPARATOR 1 DATA_33 " +
   792  				"0x0232abdc893e7f0631364d7fd01cb33d24da45329a0" +
   793  				"0357b3a7886211ab414d55a 1 CHECKMULTISIG",
   794  			err: nil,
   795  		},
   796  	}
   797  
   798  	for i, test := range tests {
   799  		script := mustParseShortForm(test.script)
   800  		if _, _, err := txscript.CalcMultiSigStats(script); err != test.err {
   801  			t.Errorf("CalcMultiSigStats #%d (%s) unexpected "+
   802  				"error\ngot: %v\nwant: %v", i, test.name, err,
   803  				test.err)
   804  		}
   805  	}
   806  }
   807  
   808  // scriptClassTest houses a test used to ensure various scripts have the
   809  // expected class.
   810  type scriptClassTest struct {
   811  	name   string
   812  	script string
   813  	class  txscript.ScriptClass
   814  }
   815  
   816  // scriptClassTests houses several test scripts used to ensure various class
   817  // determination is working as expected.  It's defined as a test global versus
   818  // inside a function scope since this spans both the standard tests and the
   819  // consensus tests (pay-to-script-hash is part of consensus).
   820  var scriptClassTests = []scriptClassTest{
   821  	{
   822  		name: "Pay Pubkey",
   823  		script: "DATA_65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382e" +
   824  			"97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e16" +
   825  			"0bfa9b8b64f9d4c03f999b8643f656b412a3 CHECKSIG",
   826  		class: txscript.PubKeyTy,
   827  	},
   828  	// tx 599e47a8114fe098103663029548811d2651991b62397e057f0c863c2bc9f9ea
   829  	{
   830  		name: "Pay PubkeyHash",
   831  		script: "DUP HASH160 DATA_20 0x660d4ef3a743e3e696ad990364e555" +
   832  			"c271ad504b EQUALVERIFY CHECKSIG",
   833  		class: txscript.PubKeyHashTy,
   834  	},
   835  	// part of tx 6d36bc17e947ce00bb6f12f8e7a56a1585c5a36188ffa2b05e10b4743273a74b
   836  	// codeseparator parts have been elided. (bitcoin core's checks for
   837  	// multisig type doesn't have codesep either).
   838  	{
   839  		name: "multisig",
   840  		script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da4" +
   841  			"5329a00357b3a7886211ab414d55a 1 CHECKMULTISIG",
   842  		class: txscript.MultiSigTy,
   843  	},
   844  	// tx e5779b9e78f9650debc2893fd9636d827b26b4ddfa6a8172fe8708c924f5c39d
   845  	{
   846  		name: "P2SH",
   847  		script: "HASH160 DATA_20 0x433ec2ac1ffa1b7b7d027f564529c57197f" +
   848  			"9ae88 EQUAL",
   849  		class: txscript.ScriptHashTy,
   850  	},
   851  	{
   852  		// Nulldata with no data at all.
   853  		name:   "nulldata",
   854  		script: "RETURN",
   855  		class:  txscript.NullDataTy,
   856  	},
   857  	{
   858  		// Nulldata with small data.
   859  		name:   "nulldata2",
   860  		script: "RETURN DATA_8 0x046708afdb0fe554",
   861  		class:  txscript.NullDataTy,
   862  	},
   863  	{
   864  		// Nulldata with max allowed data.
   865  		name: "nulldata3",
   866  		script: "RETURN PUSHDATA1 0x50 0x046708afdb0fe5548271967f1a67" +
   867  			"130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3" +
   868  			"046708afdb0fe5548271967f1a67130b7105cd6a828e03909a67" +
   869  			"962e0ea1f61deb649f6bc3f4cef3",
   870  		class: txscript.NullDataTy,
   871  	},
   872  	{
   873  		// Nulldata with more than max allowed data (so therefore
   874  		// nonstandard)
   875  		name: "nulldata4",
   876  		script: "RETURN PUSHDATA1 0x51 0x046708afdb0fe5548271967f1a67" +
   877  			"130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3" +
   878  			"046708afdb0fe5548271967f1a67130b7105cd6a828e03909a67" +
   879  			"962e0ea1f61deb649f6bc3f4cef308",
   880  		class: txscript.NonStandardTy,
   881  	},
   882  	{
   883  		// Almost nulldata, but add an additional opcode after the data
   884  		// to make it nonstandard.
   885  		name:   "nulldata5",
   886  		script: "RETURN 4 TRUE",
   887  		class:  txscript.NonStandardTy,
   888  	},
   889  
   890  	// The next few are almost multisig (it is the more complex script type)
   891  	// but with various changes to make it fail.
   892  	{
   893  		// Multisig but invalid nsigs.
   894  		name: "strange 1",
   895  		script: "DUP DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da45" +
   896  			"329a00357b3a7886211ab414d55a 1 CHECKMULTISIG",
   897  		class: txscript.NonStandardTy,
   898  	},
   899  	{
   900  		// Multisig but invalid pubkey.
   901  		name:   "strange 2",
   902  		script: "1 1 1 CHECKMULTISIG",
   903  		class:  txscript.NonStandardTy,
   904  	},
   905  	{
   906  		// Multisig but no matching npubkeys opcode.
   907  		name: "strange 3",
   908  		script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da4532" +
   909  			"9a00357b3a7886211ab414d55a DATA_33 0x0232abdc893e7f0" +
   910  			"631364d7fd01cb33d24da45329a00357b3a7886211ab414d55a " +
   911  			"CHECKMULTISIG",
   912  		class: txscript.NonStandardTy,
   913  	},
   914  	{
   915  		// Multisig but with multisigverify.
   916  		name: "strange 4",
   917  		script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da4532" +
   918  			"9a00357b3a7886211ab414d55a 1 CHECKMULTISIGVERIFY",
   919  		class: txscript.NonStandardTy,
   920  	},
   921  	{
   922  		// Multisig but wrong length.
   923  		name:   "strange 5",
   924  		script: "1 CHECKMULTISIG",
   925  		class:  txscript.NonStandardTy,
   926  	},
   927  	{
   928  		name:   "doesn't parse",
   929  		script: "DATA_5 0x01020304",
   930  		class:  txscript.NonStandardTy,
   931  	},
   932  	{
   933  		name: "multisig script with wrong number of pubkeys",
   934  		script: "2 " +
   935  			"DATA_33 " +
   936  			"0x027adf5df7c965a2d46203c781bd4dd8" +
   937  			"21f11844136f6673af7cc5a4a05cd29380 " +
   938  			"DATA_33 " +
   939  			"0x02c08f3de8ee2de9be7bd770f4c10eb0" +
   940  			"d6ff1dd81ee96eedd3a9d4aeaf86695e80 " +
   941  			"3 CHECKMULTISIG",
   942  		class: txscript.NonStandardTy,
   943  	},
   944  }
   945  
   946  // TestScriptClass ensures all the scripts in scriptClassTests have the expected
   947  // class.
   948  func TestScriptClass(t *testing.T) {
   949  	t.Parallel()
   950  
   951  	for _, test := range scriptClassTests {
   952  		script := mustParseShortForm(test.script)
   953  		class := txscript.GetScriptClass(script)
   954  		if class != test.class {
   955  			t.Errorf("%s: expected %s got %s", test.name,
   956  				test.class, class)
   957  			return
   958  		}
   959  	}
   960  }
   961  
   962  // TestStringifyClass ensures the script class string returns the expected
   963  // string for each script class.
   964  func TestStringifyClass(t *testing.T) {
   965  	t.Parallel()
   966  
   967  	tests := []struct {
   968  		name     string
   969  		class    txscript.ScriptClass
   970  		stringed string
   971  	}{
   972  		{
   973  			name:     "nonstandardty",
   974  			class:    txscript.NonStandardTy,
   975  			stringed: "nonstandard",
   976  		},
   977  		{
   978  			name:     "pubkey",
   979  			class:    txscript.PubKeyTy,
   980  			stringed: "pubkey",
   981  		},
   982  		{
   983  			name:     "pubkeyhash",
   984  			class:    txscript.PubKeyHashTy,
   985  			stringed: "pubkeyhash",
   986  		},
   987  		{
   988  			name:     "scripthash",
   989  			class:    txscript.ScriptHashTy,
   990  			stringed: "scripthash",
   991  		},
   992  		{
   993  			name:     "multisigty",
   994  			class:    txscript.MultiSigTy,
   995  			stringed: "multisig",
   996  		},
   997  		{
   998  			name:     "nulldataty",
   999  			class:    txscript.NullDataTy,
  1000  			stringed: "nulldata",
  1001  		},
  1002  		{
  1003  			name:     "broken",
  1004  			class:    txscript.ScriptClass(255),
  1005  			stringed: "Invalid",
  1006  		},
  1007  	}
  1008  
  1009  	for _, test := range tests {
  1010  		typeString := test.class.String()
  1011  		if typeString != test.stringed {
  1012  			t.Errorf("%s: got %#q, want %#q", test.name,
  1013  				typeString, test.stringed)
  1014  		}
  1015  	}
  1016  }