1 // Copyright (c) 2013-2017 The btcsuite developers
2 // Use of this source code is governed by an ISC
3 // license that can be found in the LICENSE file.
13 "github.com/btcsuite/btcd/chaincfg"
14 "github.com/btcsuite/btcd/wire"
15 "github.com/btcsuite/btcutil"
18 // mustParseShortForm parses the passed short form script and returns the
19 // resulting bytes. It panics if an error occurs. This is only used in the
20 // tests as a helper since the only way it can fail is if there is an error in
21 // the test source code.
22 func mustParseShortForm(script string) []byte {
23 s, err := parseShortForm(script)
25 panic("invalid short form script in test source: err " +
26 err.Error() + ", script: " + script)
32 // newAddressPubKey returns a new btcutil.AddressPubKey from the provided
33 // serialized public key. It panics if an error occurs. This is only used in
34 // the tests as a helper since the only way it can fail is if there is an error
35 // in the test source code.
36 func newAddressPubKey(serializedPubKey []byte) btcutil.Address {
37 addr, err := btcutil.NewAddressPubKey(serializedPubKey,
38 &chaincfg.MainNetParams)
40 panic("invalid public key in test source")
46 // newAddressPubKeyHash returns a new btcutil.AddressPubKeyHash from the
47 // provided hash. It panics if an error occurs. This is only used in the tests
48 // as a helper since the only way it can fail is if there is an error in the
50 func newAddressPubKeyHash(pkHash []byte) btcutil.Address {
51 addr, err := btcutil.NewAddressPubKeyHash(pkHash, &chaincfg.MainNetParams)
53 panic("invalid public key hash in test source")
59 // newAddressScriptHash returns a new btcutil.AddressScriptHash from the
60 // provided hash. It panics if an error occurs. This is only used in the tests
61 // as a helper since the only way it can fail is if there is an error in the
63 func newAddressScriptHash(scriptHash []byte) btcutil.Address {
64 addr, err := btcutil.NewAddressScriptHashFromHash(scriptHash,
65 &chaincfg.MainNetParams)
67 panic("invalid script hash in test source")
73 // TestExtractPkScriptAddrs ensures that extracting the type, addresses, and
74 // number of required signatures from PkScripts works as intended.
75 func TestExtractPkScriptAddrs(t *testing.T) {
81 addrs []btcutil.Address
86 name: "standard p2pk with compressed pubkey (0x02)",
87 script: hexToBytes("2102192d74d0cb94344c9569c2e779015" +
88 "73d8d7903c3ebec3a957724895dca52c6b4ac"),
89 addrs: []btcutil.Address{
90 newAddressPubKey(hexToBytes("02192d74d0cb9434" +
91 "4c9569c2e77901573d8d7903c3ebec3a9577" +
98 name: "standard p2pk with uncompressed pubkey (0x04)",
99 script: hexToBytes("410411db93e1dcdb8a016b49840f8c53b" +
100 "c1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddf" +
101 "b84ccf9744464f82e160bfa9b8b64f9d4c03f999b864" +
103 addrs: []btcutil.Address{
104 newAddressPubKey(hexToBytes("0411db93e1dcdb8a" +
105 "016b49840f8c53bc1eb68a382e97b1482eca" +
106 "d7b148a6909a5cb2e0eaddfb84ccf9744464" +
107 "f82e160bfa9b8b64f9d4c03f999b8643f656" +
114 name: "standard p2pk with hybrid pubkey (0x06)",
115 script: hexToBytes("4106192d74d0cb94344c9569c2e779015" +
116 "73d8d7903c3ebec3a957724895dca52c6b40d4526483" +
117 "8c0bd96852662ce6a847b197376830160c6d2eb5e6a4" +
119 addrs: []btcutil.Address{
120 newAddressPubKey(hexToBytes("06192d74d0cb9434" +
121 "4c9569c2e77901573d8d7903c3ebec3a9577" +
122 "24895dca52c6b40d45264838c0bd96852662" +
123 "ce6a847b197376830160c6d2eb5e6a4c44d3" +
130 name: "standard p2pk with compressed pubkey (0x03)",
131 script: hexToBytes("2103b0bd634234abbb1ba1e986e884185" +
132 "c61cf43e001f9137f23c2c409273eb16e65ac"),
133 addrs: []btcutil.Address{
134 newAddressPubKey(hexToBytes("03b0bd634234abbb" +
135 "1ba1e986e884185c61cf43e001f9137f23c2" +
142 name: "2nd standard p2pk with uncompressed pubkey (0x04)",
143 script: hexToBytes("4104b0bd634234abbb1ba1e986e884185" +
144 "c61cf43e001f9137f23c2c409273eb16e6537a576782" +
145 "eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3" +
147 addrs: []btcutil.Address{
148 newAddressPubKey(hexToBytes("04b0bd634234abbb" +
149 "1ba1e986e884185c61cf43e001f9137f23c2" +
150 "c409273eb16e6537a576782eba668a7ef8bd" +
151 "3b3cfb1edb7117ab65129b8a2e681f3c1e09" +
158 name: "standard p2pk with hybrid pubkey (0x07)",
159 script: hexToBytes("4107b0bd634234abbb1ba1e986e884185" +
160 "c61cf43e001f9137f23c2c409273eb16e6537a576782" +
161 "eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3" +
163 addrs: []btcutil.Address{
164 newAddressPubKey(hexToBytes("07b0bd634234abbb" +
165 "1ba1e986e884185c61cf43e001f9137f23c2" +
166 "c409273eb16e6537a576782eba668a7ef8bd" +
167 "3b3cfb1edb7117ab65129b8a2e681f3c1e09" +
174 name: "standard p2pkh",
175 script: hexToBytes("76a914ad06dd6ddee55cbca9a9e3713bd" +
176 "7587509a3056488ac"),
177 addrs: []btcutil.Address{
178 newAddressPubKeyHash(hexToBytes("ad06dd6ddee5" +
179 "5cbca9a9e3713bd7587509a30564")),
185 name: "standard p2sh",
186 script: hexToBytes("a91463bcc565f9e68ee0189dd5cc67f1b" +
188 addrs: []btcutil.Address{
189 newAddressScriptHash(hexToBytes("63bcc565f9e6" +
190 "8ee0189dd5cc67f1b0e5f02f45cb")),
195 // from real tx 60a20bd93aa49ab4b28d514ec10b06e1829ce6818ec06cd3aabd013ebcdc4bb1, vout 0
197 name: "standard 1 of 2 multisig",
198 script: hexToBytes("514104cc71eb30d653c0c3163990c47b9" +
199 "76f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a47" +
200 "3e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d1" +
201 "1fcdd0d348ac4410461cbdcc5409fb4b4d42b51d3338" +
202 "1354d80e550078cb532a34bfa2fcfdeb7d76519aecc6" +
203 "2770f5b0e4ef8551946d8a540911abe3e7854a26f39f" +
204 "58b25c15342af52ae"),
205 addrs: []btcutil.Address{
206 newAddressPubKey(hexToBytes("04cc71eb30d653c0" +
207 "c3163990c47b976f3fb3f37cccdcbedb169a" +
208 "1dfef58bbfbfaff7d8a473e7e2e6d317b87b" +
209 "afe8bde97e3cf8f065dec022b51d11fcdd0d" +
211 newAddressPubKey(hexToBytes("0461cbdcc5409fb4" +
212 "b4d42b51d33381354d80e550078cb532a34b" +
213 "fa2fcfdeb7d76519aecc62770f5b0e4ef855" +
214 "1946d8a540911abe3e7854a26f39f58b25c1" +
220 // from real tx d646f82bd5fbdb94a36872ce460f97662b80c3050ad3209bef9d1e398ea277ab, vin 1
222 name: "standard 2 of 3 multisig",
223 script: hexToBytes("524104cb9c3c222c5f7a7d3b9bd152f36" +
224 "3a0b6d54c9eb312c4d4f9af1e8551b6c421a6a4ab0e2" +
225 "9105f24de20ff463c1c91fcf3bf662cdde4783d4799f" +
226 "787cb7c08869b4104ccc588420deeebea22a7e900cc8" +
227 "b68620d2212c374604e3487ca08f1ff3ae12bdc63951" +
228 "4d0ec8612a2d3c519f084d9a00cbbe3b53d071e9b09e" +
229 "71e610b036aa24104ab47ad1939edcb3db65f7fedea6" +
230 "2bbf781c5410d3f22a7a3a56ffefb2238af8627363bd" +
231 "f2ed97c1f89784a1aecdb43384f11d2acc64443c7fc2" +
232 "99cef0400421a53ae"),
233 addrs: []btcutil.Address{
234 newAddressPubKey(hexToBytes("04cb9c3c222c5f7a" +
235 "7d3b9bd152f363a0b6d54c9eb312c4d4f9af" +
236 "1e8551b6c421a6a4ab0e29105f24de20ff46" +
237 "3c1c91fcf3bf662cdde4783d4799f787cb7c" +
239 newAddressPubKey(hexToBytes("04ccc588420deeeb" +
240 "ea22a7e900cc8b68620d2212c374604e3487" +
241 "ca08f1ff3ae12bdc639514d0ec8612a2d3c5" +
242 "19f084d9a00cbbe3b53d071e9b09e71e610b" +
244 newAddressPubKey(hexToBytes("04ab47ad1939edcb" +
245 "3db65f7fedea62bbf781c5410d3f22a7a3a5" +
246 "6ffefb2238af8627363bdf2ed97c1f89784a" +
247 "1aecdb43384f11d2acc64443c7fc299cef04" +
254 // The below are nonstandard script due to things such as
255 // invalid pubkeys, failure to parse, and not being of a
259 name: "p2pk with uncompressed pk missing OP_CHECKSIG",
260 script: hexToBytes("410411db93e1dcdb8a016b49840f8c53b" +
261 "c1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddf" +
262 "b84ccf9744464f82e160bfa9b8b64f9d4c03f999b864" +
266 class: NonStandardTy,
269 name: "valid signature from a sigscript - no addresses",
270 script: hexToBytes("47304402204e45e16932b8af514961a1d" +
271 "3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd41022" +
272 "0181522ec8eca07de4860a4acdd12909d831cc56cbba" +
273 "c4622082221a8768d1d0901"),
276 class: NonStandardTy,
278 // Note the technically the pubkey is the second item on the
279 // stack, but since the address extraction intentionally only
280 // works with standard PkScripts, this should not return any
283 name: "valid sigscript to reedeem p2pk - no addresses",
284 script: hexToBytes("493046022100ddc69738bf2336318e4e0" +
285 "41a5a77f305da87428ab1606f023260017854350ddc0" +
286 "22100817af09d2eec36862d16009852b7e3a0f6dd765" +
287 "98290b7834e1453660367e07a014104cd4240c198e12" +
288 "523b6f9cb9f5bed06de1ba37e96a1bbd13745fcf9d11" +
289 "c25b1dff9a519675d198804ba9962d3eca2d5937d58e" +
290 "5a75a71042d40388a4d307f887d"),
293 class: NonStandardTy,
295 // from real tx 691dd277dc0e90a462a3d652a1171686de49cf19067cd33c7df0392833fb986a, vout 0
296 // invalid public keys
298 name: "1 of 3 multisig with invalid pubkeys",
299 script: hexToBytes("51411c2200007353455857696b696c656" +
300 "16b73204361626c6567617465204261636b75700a0a6" +
301 "361626c65676174652d3230313031323034313831312" +
302 "e377a0a0a446f41776e6c6f61642074686520666f6c6" +
303 "c6f77696e67207472616e73616374696f6e732077697" +
304 "468205361746f736869204e616b616d6f746f2773206" +
305 "46f776e6c6f61416420746f6f6c2077686963680a636" +
306 "16e20626520666f756e6420696e207472616e7361637" +
307 "4696f6e2036633533636439383731313965663739376" +
308 "435616463636453ae"),
309 addrs: []btcutil.Address{},
313 // from real tx: 691dd277dc0e90a462a3d652a1171686de49cf19067cd33c7df0392833fb986a, vout 44
314 // invalid public keys
316 name: "1 of 3 multisig with invalid pubkeys 2",
317 script: hexToBytes("514134633365633235396337346461636" +
318 "536666430383862343463656638630a6336366263313" +
319 "93936633862393461333831316233363536313866653" +
320 "16539623162354136636163636539393361333938386" +
321 "134363966636336643664616266640a3236363363666" +
322 "13963663463303363363039633539336333653931666" +
323 "56465373032392131323364643432643235363339643" +
324 "338613663663530616234636434340a00000053ae"),
325 addrs: []btcutil.Address{},
330 name: "empty script",
334 class: NonStandardTy,
337 name: "script that does not parse",
338 script: []byte{OP_DATA_45},
341 class: NonStandardTy,
345 t.Logf("Running %d tests.", len(tests))
346 for i, test := range tests {
347 class, addrs, reqSigs, err := ExtractPkScriptAddrs(
348 test.script, &chaincfg.MainNetParams)
352 if !reflect.DeepEqual(addrs, test.addrs) {
353 t.Errorf("ExtractPkScriptAddrs #%d (%s) unexpected "+
354 "addresses\ngot %v\nwant %v", i, test.name,
359 if reqSigs != test.reqSigs {
360 t.Errorf("ExtractPkScriptAddrs #%d (%s) unexpected "+
361 "number of required signatures - got %d, "+
362 "want %d", i, test.name, reqSigs, test.reqSigs)
366 if class != test.class {
367 t.Errorf("ExtractPkScriptAddrs #%d (%s) unexpected "+
368 "script type - got %s, want %s", i, test.name,
375 // TestCalcScriptInfo ensures the CalcScriptInfo provides the expected results
376 // for various valid and invalid script pairs.
377 func TestCalcScriptInfo(t *testing.T) {
389 scriptInfo ScriptInfo
393 // Invented scripts, the hashes do not match
394 // Truncated version of test below:
395 name: "pkscript doesn't parse",
396 sigScript: "1 81 DATA_8 2DUP EQUAL NOT VERIFY ABS " +
398 pkScript: "HASH160 DATA_20 0xfe441065b6532231de2fac56" +
401 scriptInfoErr: scriptError(ErrMalformedPush, ""),
404 name: "sigScript doesn't parse",
405 // Truncated version of p2sh script below.
406 sigScript: "1 81 DATA_8 2DUP EQUAL NOT VERIFY ABS " +
408 pkScript: "HASH160 DATA_20 0xfe441065b6532231de2fac56" +
409 "3152205ec4f59c74 EQUAL",
411 scriptInfoErr: scriptError(ErrMalformedPush, ""),
414 // Invented scripts, the hashes do not match
415 name: "p2sh standard script",
416 sigScript: "1 81 DATA_25 DUP HASH160 DATA_20 0x010203" +
417 "0405060708090a0b0c0d0e0f1011121314 EQUALVERIFY " +
419 pkScript: "HASH160 DATA_20 0xfe441065b6532231de2fac56" +
420 "3152205ec4f59c74 EQUAL",
422 scriptInfo: ScriptInfo{
423 PkScriptClass: ScriptHashTy,
425 ExpectedInputs: 3, // nonstandard p2sh.
430 // from 567a53d1ce19ce3d07711885168484439965501536d0d0294c5d46d46c10e53b
431 // from the blockchain.
432 name: "p2sh nonstandard script",
433 sigScript: "1 81 DATA_8 2DUP EQUAL NOT VERIFY ABS " +
435 pkScript: "HASH160 DATA_20 0xfe441065b6532231de2fac56" +
436 "3152205ec4f59c74 EQUAL",
438 scriptInfo: ScriptInfo{
439 PkScriptClass: ScriptHashTy,
441 ExpectedInputs: -1, // nonstandard p2sh.
446 // Script is invented, numbers all fake.
447 name: "multisig script",
448 // Extra 0 arg on the end for OP_CHECKMULTISIG bug.
449 sigScript: "1 1 1 0",
451 "DATA_33 0x0102030405060708090a0b0c0d0e0f1011" +
452 "12131415161718191a1b1c1d1e1f2021 DATA_33 " +
453 "0x0102030405060708090a0b0c0d0e0f101112131415" +
454 "161718191a1b1c1d1e1f2021 DATA_33 0x010203040" +
455 "5060708090a0b0c0d0e0f101112131415161718191a1" +
456 "b1c1d1e1f2021 3 CHECKMULTISIG",
458 scriptInfo: ScriptInfo{
459 PkScriptClass: MultiSigTy,
467 name: "p2wkh script",
468 pkScript: "OP_0 DATA_20 0x365ab47888e150ff46f8d51bce36dcd680f1283f",
470 "3045022100ee9fe8f9487afa977" +
471 "6647ebcf0883ce0cd37454d7ce19889d34ba2c9" +
472 "9ce5a9f402200341cb469d0efd3955acb9e46" +
473 "f568d7e2cc10f9084aaff94ced6dc50a59134ad01",
474 "03f0000d0639a22bfaf217e4c9428" +
475 "9c2b0cc7fa1036f7fd5d9f61a9d6ec153100e",
478 scriptInfo: ScriptInfo{
479 PkScriptClass: WitnessV0PubKeyHashTy,
487 name: "p2wkh nested inside p2sh",
488 pkScript: "HASH160 DATA_20 " +
489 "0xb3a84b564602a9d68b4c9f19c2ea61458ff7826c EQUAL",
490 sigScript: "DATA_22 0x0014ad0ffa2e387f07e7ead14dc56d5a97dbd6ff5a23",
492 "3045022100cb1c2ac1ff1d57d" +
493 "db98f7bdead905f8bf5bcc8641b029ce8eef25" +
494 "c75a9e22a4702203be621b5c86b771288706be5" +
495 "a7eee1db4fceabf9afb7583c1cc6ee3f8297b21201",
496 "03f0000d0639a22bfaf217e4c9" +
497 "4289c2b0cc7fa1036f7fd5d9f61a9d6ec153100e",
501 scriptInfo: ScriptInfo{
502 PkScriptClass: ScriptHashTy,
510 name: "p2wsh spend of a p2wkh witness script",
511 pkScript: "0 DATA_32 0xe112b88a0cd87ba387f44" +
512 "9d443ee2596eb353beb1f0351ab2cba8909d875db23",
514 "3045022100cb1c2ac1ff1d57d" +
515 "db98f7bdead905f8bf5bcc8641b029ce8eef25" +
516 "c75a9e22a4702203be621b5c86b771288706be5" +
517 "a7eee1db4fceabf9afb7583c1cc6ee3f8297b21201",
518 "03f0000d0639a22bfaf217e4c9" +
519 "4289c2b0cc7fa1036f7fd5d9f61a9d6ec153100e",
520 "76a914064977cb7b4a2e0c9680df0ef696e9e0e296b39988ac",
523 scriptInfo: ScriptInfo{
524 PkScriptClass: WitnessV0ScriptHashTy,
532 for _, test := range tests {
533 sigScript := mustParseShortForm(test.sigScript)
534 pkScript := mustParseShortForm(test.pkScript)
536 var witness wire.TxWitness
538 for _, witElement := range test.witness {
539 wit, err := hex.DecodeString(witElement)
541 t.Fatalf("unable to decode witness "+
545 witness = append(witness, wit)
548 si, err := CalcScriptInfo(sigScript, pkScript, witness,
549 test.bip16, test.segwit)
550 if e := tstCheckScriptError(err, test.scriptInfoErr); e != nil {
551 t.Errorf("scriptinfo test %q: %v", test.name, e)
558 if *si != test.scriptInfo {
559 t.Errorf("%s: scriptinfo doesn't match expected. "+
560 "got: %q expected %q", test.name, *si,
567 // bogusAddress implements the btcutil.Address interface so the tests can ensure
568 // unsupported address types are handled properly.
569 type bogusAddress struct{}
571 // EncodeAddress simply returns an empty string. It exists to satsify the
572 // btcutil.Address interface.
573 func (b *bogusAddress) EncodeAddress() string {
577 // ScriptAddress simply returns an empty byte slice. It exists to satsify the
578 // btcutil.Address interface.
579 func (b *bogusAddress) ScriptAddress() []byte {
583 // IsForNet lies blatantly to satisfy the btcutil.Address interface.
584 func (b *bogusAddress) IsForNet(chainParams *chaincfg.Params) bool {
585 return true // why not?
588 // String simply returns an empty string. It exists to satsify the
589 // btcutil.Address interface.
590 func (b *bogusAddress) String() string {
594 // TestPayToAddrScript ensures the PayToAddrScript function generates the
595 // correct scripts for the various types of addresses.
596 func TestPayToAddrScript(t *testing.T) {
599 // 1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gX
600 p2pkhMain, err := btcutil.NewAddressPubKeyHash(hexToBytes("e34cce70c86"+
601 "373273efcc54ce7d2a491bb4a0e84"), &chaincfg.MainNetParams)
603 t.Fatalf("Unable to create public key hash address: %v", err)
606 // Taken from transaction:
607 // b0539a45de13b3e0403909b8bd1a555b8cbe45fd4e3f3fda76f3a5f52835c29d
608 p2shMain, _ := btcutil.NewAddressScriptHashFromHash(hexToBytes("e8c300"+
609 "c87986efa84c37c0519929019ef86eb5b4"), &chaincfg.MainNetParams)
611 t.Fatalf("Unable to create script hash address: %v", err)
614 // mainnet p2pk 13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg
615 p2pkCompressedMain, err := btcutil.NewAddressPubKey(hexToBytes("02192d"+
616 "74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4"),
617 &chaincfg.MainNetParams)
619 t.Fatalf("Unable to create pubkey address (compressed): %v",
622 p2pkCompressed2Main, err := btcutil.NewAddressPubKey(hexToBytes("03b0b"+
623 "d634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65"),
624 &chaincfg.MainNetParams)
626 t.Fatalf("Unable to create pubkey address (compressed 2): %v",
630 p2pkUncompressedMain, err := btcutil.NewAddressPubKey(hexToBytes("0411"+
631 "db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5"+
632 "cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b4"+
633 "12a3"), &chaincfg.MainNetParams)
635 t.Fatalf("Unable to create pubkey address (uncompressed): %v",
639 // Errors used in the tests below defined here for convenience and to
640 // keep the horizontal test size shorter.
641 errUnsupportedAddress := scriptError(ErrUnsupportedAddress, "")
648 // pay-to-pubkey-hash address on mainnet
651 "DUP HASH160 DATA_20 0xe34cce70c86373273efcc54ce7d2a4" +
652 "91bb4a0e8488 CHECKSIG",
655 // pay-to-script-hash address on mainnet
658 "HASH160 DATA_20 0xe8c300c87986efa84c37c0519929019ef8" +
662 // pay-to-pubkey address on mainnet. compressed key.
665 "DATA_33 0x02192d74d0cb94344c9569c2e77901573d8d7903c3" +
666 "ebec3a957724895dca52c6b4 CHECKSIG",
669 // pay-to-pubkey address on mainnet. compressed key (other way).
672 "DATA_33 0x03b0bd634234abbb1ba1e986e884185c61cf43e001" +
673 "f9137f23c2c409273eb16e65 CHECKSIG",
676 // pay-to-pubkey address on mainnet. uncompressed key.
678 p2pkUncompressedMain,
679 "DATA_65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382e" +
680 "97b1482ecad7b148a6909a5cb2e0eaddfb84ccf97444" +
681 "64f82e160bfa9b8b64f9d4c03f999b8643f656b412a3 " +
686 // Supported address types with nil pointers.
687 {(*btcutil.AddressPubKeyHash)(nil), "", errUnsupportedAddress},
688 {(*btcutil.AddressScriptHash)(nil), "", errUnsupportedAddress},
689 {(*btcutil.AddressPubKey)(nil), "", errUnsupportedAddress},
691 // Unsupported address type.
692 {&bogusAddress{}, "", errUnsupportedAddress},
695 t.Logf("Running %d tests", len(tests))
696 for i, test := range tests {
697 pkScript, err := PayToAddrScript(test.in)
698 if e := tstCheckScriptError(err, test.err); e != nil {
699 t.Errorf("PayToAddrScript #%d unexpected error - "+
700 "got %v, want %v", i, err, test.err)
704 expected := mustParseShortForm(test.expected)
705 if !bytes.Equal(pkScript, expected) {
706 t.Errorf("PayToAddrScript #%d got: %x\nwant: %x",
707 i, pkScript, expected)
713 // TestMultiSigScript ensures the MultiSigScript function returns the expected
714 // scripts and errors.
715 func TestMultiSigScript(t *testing.T) {
718 // mainnet p2pk 13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg
719 p2pkCompressedMain, err := btcutil.NewAddressPubKey(hexToBytes("02192d"+
720 "74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4"),
721 &chaincfg.MainNetParams)
723 t.Fatalf("Unable to create pubkey address (compressed): %v",
726 p2pkCompressed2Main, err := btcutil.NewAddressPubKey(hexToBytes("03b0b"+
727 "d634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65"),
728 &chaincfg.MainNetParams)
730 t.Fatalf("Unable to create pubkey address (compressed 2): %v",
734 p2pkUncompressedMain, err := btcutil.NewAddressPubKey(hexToBytes("0411"+
735 "db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5"+
736 "cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b4"+
737 "12a3"), &chaincfg.MainNetParams)
739 t.Fatalf("Unable to create pubkey address (uncompressed): %v",
744 keys []*btcutil.AddressPubKey
750 []*btcutil.AddressPubKey{
755 "1 DATA_33 0x02192d74d0cb94344c9569c2e77901573d8d7903c" +
756 "3ebec3a957724895dca52c6b4 DATA_33 0x03b0bd634" +
757 "234abbb1ba1e986e884185c61cf43e001f9137f23c2c4" +
758 "09273eb16e65 2 CHECKMULTISIG",
762 []*btcutil.AddressPubKey{
767 "2 DATA_33 0x02192d74d0cb94344c9569c2e77901573d8d7903c" +
768 "3ebec3a957724895dca52c6b4 DATA_33 0x03b0bd634" +
769 "234abbb1ba1e986e884185c61cf43e001f9137f23c2c4" +
770 "09273eb16e65 2 CHECKMULTISIG",
774 []*btcutil.AddressPubKey{
780 scriptError(ErrTooManyRequiredSigs, ""),
783 []*btcutil.AddressPubKey{
784 p2pkUncompressedMain,
787 "1 DATA_65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382" +
788 "e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf97444" +
789 "64f82e160bfa9b8b64f9d4c03f999b8643f656b412a3 " +
794 []*btcutil.AddressPubKey{
795 p2pkUncompressedMain,
799 scriptError(ErrTooManyRequiredSigs, ""),
803 t.Logf("Running %d tests", len(tests))
804 for i, test := range tests {
805 script, err := MultiSigScript(test.keys, test.nrequired)
806 if e := tstCheckScriptError(err, test.err); e != nil {
807 t.Errorf("MultiSigScript #%d: %v", i, e)
811 expected := mustParseShortForm(test.expected)
812 if !bytes.Equal(script, expected) {
813 t.Errorf("MultiSigScript #%d got: %x\nwant: %x",
820 // TestCalcMultiSigStats ensures the CalcMutliSigStats function returns the
822 func TestCalcMultiSigStats(t *testing.T) {
831 name: "short script",
832 script: "0x046708afdb0fe5548271967f1a67130b7105cd6a828" +
833 "e03909a67962e0ea1f61d",
834 err: scriptError(ErrMalformedPush, ""),
837 name: "stack underflow",
838 script: "RETURN DATA_41 0x046708afdb0fe5548271967f1a" +
839 "67130b7105cd6a828e03909a67962e0ea1f61deb649f6" +
841 err: scriptError(ErrNotMultisigScript, ""),
844 name: "multisig script",
845 script: "0 DATA_72 0x30450220106a3e4ef0b51b764a2887226" +
846 "2ffef55846514dacbdcbbdd652c849d395b4384022100" +
847 "e03ae554c3cbb40600d31dd46fc33f25e47bf8525b1fe" +
848 "07282e3b6ecb5f3bb2801 CODESEPARATOR 1 DATA_33 " +
849 "0x0232abdc893e7f0631364d7fd01cb33d24da45329a0" +
850 "0357b3a7886211ab414d55a 1 CHECKMULTISIG",
855 for i, test := range tests {
856 script := mustParseShortForm(test.script)
857 _, _, err := CalcMultiSigStats(script)
858 if e := tstCheckScriptError(err, test.err); e != nil {
859 t.Errorf("CalcMultiSigStats #%d (%s): %v", i, test.name,
866 // scriptClassTests houses several test scripts used to ensure various class
867 // determination is working as expected. It's defined as a test global versus
868 // inside a function scope since this spans both the standard tests and the
869 // consensus tests (pay-to-script-hash is part of consensus).
870 var scriptClassTests = []struct {
877 script: "DATA_65 0x0411db93e1dcdb8a016b49840f8c53bc1eb68a382e" +
878 "97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e16" +
879 "0bfa9b8b64f9d4c03f999b8643f656b412a3 CHECKSIG",
882 // tx 599e47a8114fe098103663029548811d2651991b62397e057f0c863c2bc9f9ea
884 name: "Pay PubkeyHash",
885 script: "DUP HASH160 DATA_20 0x660d4ef3a743e3e696ad990364e555" +
886 "c271ad504b EQUALVERIFY CHECKSIG",
889 // part of tx 6d36bc17e947ce00bb6f12f8e7a56a1585c5a36188ffa2b05e10b4743273a74b
890 // codeseparator parts have been elided. (bitcoin core's checks for
891 // multisig type doesn't have codesep either).
894 script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da4" +
895 "5329a00357b3a7886211ab414d55a 1 CHECKMULTISIG",
898 // tx e5779b9e78f9650debc2893fd9636d827b26b4ddfa6a8172fe8708c924f5c39d
901 script: "HASH160 DATA_20 0x433ec2ac1ffa1b7b7d027f564529c57197f" +
907 // Nulldata with no data at all.
908 name: "nulldata no data",
913 // Nulldata with single zero push.
914 name: "nulldata zero",
919 // Nulldata with small integer push.
920 name: "nulldata small int",
925 // Nulldata with max small integer push.
926 name: "nulldata max small int",
931 // Nulldata with small data push.
932 name: "nulldata small data",
933 script: "RETURN DATA_8 0x046708afdb0fe554",
937 // Canonical nulldata with 60-byte data push.
938 name: "canonical nulldata 60-byte push",
939 script: "RETURN 0x3c 0x046708afdb0fe5548271967f1a67130b7105cd" +
940 "6a828e03909a67962e0ea1f61deb649f6bc3f4cef3046708afdb" +
941 "0fe5548271967f1a67130b7105cd6a",
945 // Non-canonical nulldata with 60-byte data push.
946 name: "non-canonical nulldata 60-byte push",
947 script: "RETURN PUSHDATA1 0x3c 0x046708afdb0fe5548271967f1a67" +
948 "130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3" +
949 "046708afdb0fe5548271967f1a67130b7105cd6a",
953 // Nulldata with max allowed data to be considered standard.
954 name: "nulldata max standard push",
955 script: "RETURN PUSHDATA1 0x50 0x046708afdb0fe5548271967f1a67" +
956 "130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3" +
957 "046708afdb0fe5548271967f1a67130b7105cd6a828e03909a67" +
958 "962e0ea1f61deb649f6bc3f4cef3",
962 // Nulldata with more than max allowed data to be considered
963 // standard (so therefore nonstandard)
964 name: "nulldata exceed max standard push",
965 script: "RETURN PUSHDATA1 0x51 0x046708afdb0fe5548271967f1a67" +
966 "130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3" +
967 "046708afdb0fe5548271967f1a67130b7105cd6a828e03909a67" +
968 "962e0ea1f61deb649f6bc3f4cef308",
969 class: NonStandardTy,
972 // Almost nulldata, but add an additional opcode after the data
973 // to make it nonstandard.
974 name: "almost nulldata",
975 script: "RETURN 4 TRUE",
976 class: NonStandardTy,
979 // The next few are almost multisig (it is the more complex script type)
980 // but with various changes to make it fail.
982 // Multisig but invalid nsigs.
984 script: "DUP DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da45" +
985 "329a00357b3a7886211ab414d55a 1 CHECKMULTISIG",
986 class: NonStandardTy,
989 // Multisig but invalid pubkey.
991 script: "1 1 1 CHECKMULTISIG",
992 class: NonStandardTy,
995 // Multisig but no matching npubkeys opcode.
997 script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da4532" +
998 "9a00357b3a7886211ab414d55a DATA_33 0x0232abdc893e7f0" +
999 "631364d7fd01cb33d24da45329a00357b3a7886211ab414d55a " +
1001 class: NonStandardTy,
1004 // Multisig but with multisigverify.
1006 script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da4532" +
1007 "9a00357b3a7886211ab414d55a 1 CHECKMULTISIGVERIFY",
1008 class: NonStandardTy,
1011 // Multisig but wrong length.
1013 script: "1 CHECKMULTISIG",
1014 class: NonStandardTy,
1017 name: "doesn't parse",
1018 script: "DATA_5 0x01020304",
1019 class: NonStandardTy,
1022 name: "multisig script with wrong number of pubkeys",
1025 "0x027adf5df7c965a2d46203c781bd4dd8" +
1026 "21f11844136f6673af7cc5a4a05cd29380 " +
1028 "0x02c08f3de8ee2de9be7bd770f4c10eb0" +
1029 "d6ff1dd81ee96eedd3a9d4aeaf86695e80 " +
1031 class: NonStandardTy,
1034 // New standard segwit script templates.
1036 // A pay to witness pub key hash pk script.
1037 name: "Pay To Witness PubkeyHash",
1038 script: "0 DATA_20 0x1d0f172a0ecb48aee1be1f2687d2963ae33f71a1",
1039 class: WitnessV0PubKeyHashTy,
1042 // A pay to witness scripthash pk script.
1043 name: "Pay To Witness Scripthash",
1044 script: "0 DATA_32 0x9f96ade4b41d5433f4eda31e1738ec2b36f6e7d1420d94a6af99801a88f7f7ff",
1045 class: WitnessV0ScriptHashTy,
1049 // TestScriptClass ensures all the scripts in scriptClassTests have the expected
1051 func TestScriptClass(t *testing.T) {
1054 for _, test := range scriptClassTests {
1055 script := mustParseShortForm(test.script)
1056 class := GetScriptClass(script)
1057 if class != test.class {
1058 t.Errorf("%s: expected %s got %s (script %x)", test.name,
1059 test.class, class, script)
1065 // TestStringifyClass ensures the script class string returns the expected
1066 // string for each script class.
1067 func TestStringifyClass(t *testing.T) {
1076 name: "nonstandardty",
1077 class: NonStandardTy,
1078 stringed: "nonstandard",
1087 class: PubKeyHashTy,
1088 stringed: "pubkeyhash",
1091 name: "witnesspubkeyhash",
1092 class: WitnessV0PubKeyHashTy,
1093 stringed: "witness_v0_keyhash",
1097 class: ScriptHashTy,
1098 stringed: "scripthash",
1101 name: "witnessscripthash",
1102 class: WitnessV0ScriptHashTy,
1103 stringed: "witness_v0_scripthash",
1108 stringed: "multisig",
1113 stringed: "nulldata",
1117 class: ScriptClass(255),
1118 stringed: "Invalid",
1122 for _, test := range tests {
1123 typeString := test.class.String()
1124 if typeString != test.stringed {
1125 t.Errorf("%s: got %#q, want %#q", test.name,
1126 typeString, test.stringed)
1131 // TestNullDataScript tests whether NullDataScript returns a valid script.
1132 func TestNullDataScript(t *testing.T) {
1142 data: hexToBytes("01"),
1143 expected: mustParseShortForm("RETURN 1"),
1148 name: "max small int",
1149 data: hexToBytes("10"),
1150 expected: mustParseShortForm("RETURN 16"),
1155 name: "data of size before OP_PUSHDATA1 is needed",
1156 data: hexToBytes("0102030405060708090a0b0c0d0e0f10111" +
1158 expected: mustParseShortForm("RETURN 0x18 0x01020304" +
1159 "05060708090a0b0c0d0e0f101112131415161718"),
1165 data: hexToBytes("000102030405060708090a0b0c0d0e0f101" +
1166 "112131415161718191a1b1c1d1e1f202122232425262" +
1167 "728292a2b2c2d2e2f303132333435363738393a3b3c3" +
1168 "d3e3f404142434445464748494a4b4c4d4e4f"),
1169 expected: mustParseShortForm("RETURN PUSHDATA1 0x50 " +
1170 "0x000102030405060708090a0b0c0d0e0f101112131" +
1171 "415161718191a1b1c1d1e1f20212223242526272829" +
1172 "2a2b2c2d2e2f303132333435363738393a3b3c3d3e3" +
1173 "f404142434445464748494a4b4c4d4e4f"),
1179 data: hexToBytes("000102030405060708090a0b0c0d0e0f101" +
1180 "112131415161718191a1b1c1d1e1f202122232425262" +
1181 "728292a2b2c2d2e2f303132333435363738393a3b3c3" +
1182 "d3e3f404142434445464748494a4b4c4d4e4f50"),
1184 err: scriptError(ErrTooMuchNullData, ""),
1185 class: NonStandardTy,
1189 for i, test := range tests {
1190 script, err := NullDataScript(test.data)
1191 if e := tstCheckScriptError(err, test.err); e != nil {
1192 t.Errorf("NullDataScript: #%d (%s): %v", i, test.name,
1198 // Check that the expected result was returned.
1199 if !bytes.Equal(script, test.expected) {
1200 t.Errorf("NullDataScript: #%d (%s) wrong result\n"+
1201 "got: %x\nwant: %x", i, test.name, script,
1206 // Check that the script has the correct type.
1207 scriptType := GetScriptClass(script)
1208 if scriptType != test.class {
1209 t.Errorf("GetScriptClass: #%d (%s) wrong result -- "+
1210 "got: %v, want: %v", i, test.name, scriptType,