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