github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/txscript/sign_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 "errors" 10 "fmt" 11 "testing" 12 13 "github.com/dashpay/godash/btcec" 14 "github.com/dashpay/godash/chaincfg" 15 "github.com/dashpay/godash/txscript" 16 "github.com/dashpay/godash/wire" 17 "github.com/dashpay/godashutil" 18 ) 19 20 type addressToKey struct { 21 key *btcec.PrivateKey 22 compressed bool 23 } 24 25 func mkGetKey(keys map[string]addressToKey) txscript.KeyDB { 26 if keys == nil { 27 return txscript.KeyClosure(func(addr godashutil.Address) (*btcec.PrivateKey, 28 bool, error) { 29 return nil, false, errors.New("nope") 30 }) 31 } 32 return txscript.KeyClosure(func(addr godashutil.Address) (*btcec.PrivateKey, 33 bool, error) { 34 a2k, ok := keys[addr.EncodeAddress()] 35 if !ok { 36 return nil, false, errors.New("nope") 37 } 38 return a2k.key, a2k.compressed, nil 39 }) 40 } 41 42 func mkGetScript(scripts map[string][]byte) txscript.ScriptDB { 43 if scripts == nil { 44 return txscript.ScriptClosure(func(addr godashutil.Address) ( 45 []byte, error) { 46 return nil, errors.New("nope") 47 }) 48 } 49 return txscript.ScriptClosure(func(addr godashutil.Address) ([]byte, 50 error) { 51 script, ok := scripts[addr.EncodeAddress()] 52 if !ok { 53 return nil, errors.New("nope") 54 } 55 return script, nil 56 }) 57 } 58 59 func checkScripts(msg string, tx *wire.MsgTx, idx int, sigScript, pkScript []byte) error { 60 tx.TxIn[idx].SignatureScript = sigScript 61 vm, err := txscript.NewEngine(pkScript, tx, idx, 62 txscript.ScriptBip16|txscript.ScriptVerifyDERSignatures, nil) 63 if err != nil { 64 return fmt.Errorf("failed to make script engine for %s: %v", 65 msg, err) 66 } 67 68 err = vm.Execute() 69 if err != nil { 70 return fmt.Errorf("invalid script signature for %s: %v", msg, 71 err) 72 } 73 74 return nil 75 } 76 77 func signAndCheck(msg string, tx *wire.MsgTx, idx int, pkScript []byte, 78 hashType txscript.SigHashType, kdb txscript.KeyDB, sdb txscript.ScriptDB, 79 previousScript []byte) error { 80 81 sigScript, err := txscript.SignTxOutput(&chaincfg.TestNet3Params, tx, 82 idx, pkScript, hashType, kdb, sdb, nil) 83 if err != nil { 84 return fmt.Errorf("failed to sign output %s: %v", msg, err) 85 } 86 87 return checkScripts(msg, tx, idx, sigScript, pkScript) 88 } 89 90 func TestSignTxOutput(t *testing.T) { 91 t.Parallel() 92 93 // make key 94 // make script based on key. 95 // sign with magic pixie dust. 96 hashTypes := []txscript.SigHashType{ 97 txscript.SigHashOld, // no longer used but should act like all 98 txscript.SigHashAll, 99 txscript.SigHashNone, 100 txscript.SigHashSingle, 101 txscript.SigHashAll | txscript.SigHashAnyOneCanPay, 102 txscript.SigHashNone | txscript.SigHashAnyOneCanPay, 103 txscript.SigHashSingle | txscript.SigHashAnyOneCanPay, 104 } 105 tx := &wire.MsgTx{ 106 Version: 1, 107 TxIn: []*wire.TxIn{ 108 { 109 PreviousOutPoint: wire.OutPoint{ 110 Hash: wire.ShaHash{}, 111 Index: 0, 112 }, 113 Sequence: 4294967295, 114 }, 115 { 116 PreviousOutPoint: wire.OutPoint{ 117 Hash: wire.ShaHash{}, 118 Index: 1, 119 }, 120 Sequence: 4294967295, 121 }, 122 { 123 PreviousOutPoint: wire.OutPoint{ 124 Hash: wire.ShaHash{}, 125 Index: 2, 126 }, 127 Sequence: 4294967295, 128 }, 129 }, 130 TxOut: []*wire.TxOut{ 131 { 132 Value: 1, 133 }, 134 { 135 Value: 2, 136 }, 137 { 138 Value: 3, 139 }, 140 }, 141 LockTime: 0, 142 } 143 144 // Pay to Pubkey Hash (uncompressed) 145 for _, hashType := range hashTypes { 146 for i := range tx.TxIn { 147 msg := fmt.Sprintf("%d:%d", hashType, i) 148 key, err := btcec.NewPrivateKey(btcec.S256()) 149 if err != nil { 150 t.Errorf("failed to make privKey for %s: %v", 151 msg, err) 152 break 153 } 154 155 pk := (*btcec.PublicKey)(&key.PublicKey). 156 SerializeUncompressed() 157 address, err := godashutil.NewAddressPubKeyHash( 158 godashutil.Hash160(pk), &chaincfg.TestNet3Params) 159 if err != nil { 160 t.Errorf("failed to make address for %s: %v", 161 msg, err) 162 break 163 } 164 165 pkScript, err := txscript.PayToAddrScript(address) 166 if err != nil { 167 t.Errorf("failed to make pkscript "+ 168 "for %s: %v", msg, err) 169 } 170 171 if err := signAndCheck(msg, tx, i, pkScript, hashType, 172 mkGetKey(map[string]addressToKey{ 173 address.EncodeAddress(): {key, false}, 174 }), mkGetScript(nil), nil); err != nil { 175 t.Error(err) 176 break 177 } 178 } 179 } 180 181 // Pay to Pubkey Hash (uncompressed) (merging with correct) 182 for _, hashType := range hashTypes { 183 for i := range tx.TxIn { 184 msg := fmt.Sprintf("%d:%d", hashType, i) 185 key, err := btcec.NewPrivateKey(btcec.S256()) 186 if err != nil { 187 t.Errorf("failed to make privKey for %s: %v", 188 msg, err) 189 break 190 } 191 192 pk := (*btcec.PublicKey)(&key.PublicKey). 193 SerializeUncompressed() 194 address, err := godashutil.NewAddressPubKeyHash( 195 godashutil.Hash160(pk), &chaincfg.TestNet3Params) 196 if err != nil { 197 t.Errorf("failed to make address for %s: %v", 198 msg, err) 199 break 200 } 201 202 pkScript, err := txscript.PayToAddrScript(address) 203 if err != nil { 204 t.Errorf("failed to make pkscript "+ 205 "for %s: %v", msg, err) 206 } 207 208 sigScript, err := txscript.SignTxOutput( 209 &chaincfg.TestNet3Params, tx, i, pkScript, 210 hashType, mkGetKey(map[string]addressToKey{ 211 address.EncodeAddress(): {key, false}, 212 }), mkGetScript(nil), nil) 213 if err != nil { 214 t.Errorf("failed to sign output %s: %v", msg, 215 err) 216 break 217 } 218 219 // by the above loop, this should be valid, now sign 220 // again and merge. 221 sigScript, err = txscript.SignTxOutput( 222 &chaincfg.TestNet3Params, tx, i, pkScript, 223 hashType, mkGetKey(map[string]addressToKey{ 224 address.EncodeAddress(): {key, false}, 225 }), mkGetScript(nil), sigScript) 226 if err != nil { 227 t.Errorf("failed to sign output %s a "+ 228 "second time: %v", msg, err) 229 break 230 } 231 232 err = checkScripts(msg, tx, i, sigScript, pkScript) 233 if err != nil { 234 t.Errorf("twice signed script invalid for "+ 235 "%s: %v", msg, err) 236 break 237 } 238 } 239 } 240 241 // Pay to Pubkey Hash (compressed) 242 for _, hashType := range hashTypes { 243 for i := range tx.TxIn { 244 msg := fmt.Sprintf("%d:%d", hashType, i) 245 246 key, err := btcec.NewPrivateKey(btcec.S256()) 247 if err != nil { 248 t.Errorf("failed to make privKey for %s: %v", 249 msg, err) 250 break 251 } 252 253 pk := (*btcec.PublicKey)(&key.PublicKey). 254 SerializeCompressed() 255 address, err := godashutil.NewAddressPubKeyHash( 256 godashutil.Hash160(pk), &chaincfg.TestNet3Params) 257 if err != nil { 258 t.Errorf("failed to make address for %s: %v", 259 msg, err) 260 break 261 } 262 263 pkScript, err := txscript.PayToAddrScript(address) 264 if err != nil { 265 t.Errorf("failed to make pkscript "+ 266 "for %s: %v", msg, err) 267 } 268 269 if err := signAndCheck(msg, tx, i, pkScript, hashType, 270 mkGetKey(map[string]addressToKey{ 271 address.EncodeAddress(): {key, true}, 272 }), mkGetScript(nil), nil); err != nil { 273 t.Error(err) 274 break 275 } 276 } 277 } 278 279 // Pay to Pubkey Hash (compressed) with duplicate merge 280 for _, hashType := range hashTypes { 281 for i := range tx.TxIn { 282 msg := fmt.Sprintf("%d:%d", hashType, i) 283 284 key, err := btcec.NewPrivateKey(btcec.S256()) 285 if err != nil { 286 t.Errorf("failed to make privKey for %s: %v", 287 msg, err) 288 break 289 } 290 291 pk := (*btcec.PublicKey)(&key.PublicKey). 292 SerializeCompressed() 293 address, err := godashutil.NewAddressPubKeyHash( 294 godashutil.Hash160(pk), &chaincfg.TestNet3Params) 295 if err != nil { 296 t.Errorf("failed to make address for %s: %v", 297 msg, err) 298 break 299 } 300 301 pkScript, err := txscript.PayToAddrScript(address) 302 if err != nil { 303 t.Errorf("failed to make pkscript "+ 304 "for %s: %v", msg, err) 305 } 306 307 sigScript, err := txscript.SignTxOutput( 308 &chaincfg.TestNet3Params, tx, i, pkScript, 309 hashType, mkGetKey(map[string]addressToKey{ 310 address.EncodeAddress(): {key, true}, 311 }), mkGetScript(nil), nil) 312 if err != nil { 313 t.Errorf("failed to sign output %s: %v", msg, 314 err) 315 break 316 } 317 318 // by the above loop, this should be valid, now sign 319 // again and merge. 320 sigScript, err = txscript.SignTxOutput( 321 &chaincfg.TestNet3Params, tx, i, pkScript, 322 hashType, mkGetKey(map[string]addressToKey{ 323 address.EncodeAddress(): {key, true}, 324 }), mkGetScript(nil), sigScript) 325 if err != nil { 326 t.Errorf("failed to sign output %s a "+ 327 "second time: %v", msg, err) 328 break 329 } 330 331 err = checkScripts(msg, tx, i, sigScript, pkScript) 332 if err != nil { 333 t.Errorf("twice signed script invalid for "+ 334 "%s: %v", msg, err) 335 break 336 } 337 } 338 } 339 340 // Pay to PubKey (uncompressed) 341 for _, hashType := range hashTypes { 342 for i := range tx.TxIn { 343 msg := fmt.Sprintf("%d:%d", hashType, i) 344 345 key, err := btcec.NewPrivateKey(btcec.S256()) 346 if err != nil { 347 t.Errorf("failed to make privKey for %s: %v", 348 msg, err) 349 break 350 } 351 352 pk := (*btcec.PublicKey)(&key.PublicKey). 353 SerializeUncompressed() 354 address, err := godashutil.NewAddressPubKey(pk, 355 &chaincfg.TestNet3Params) 356 if err != nil { 357 t.Errorf("failed to make address for %s: %v", 358 msg, err) 359 break 360 } 361 362 pkScript, err := txscript.PayToAddrScript(address) 363 if err != nil { 364 t.Errorf("failed to make pkscript "+ 365 "for %s: %v", msg, err) 366 } 367 368 if err := signAndCheck(msg, tx, i, pkScript, hashType, 369 mkGetKey(map[string]addressToKey{ 370 address.EncodeAddress(): {key, false}, 371 }), mkGetScript(nil), nil); err != nil { 372 t.Error(err) 373 break 374 } 375 } 376 } 377 378 // Pay to PubKey (uncompressed) 379 for _, hashType := range hashTypes { 380 for i := range tx.TxIn { 381 msg := fmt.Sprintf("%d:%d", hashType, i) 382 383 key, err := btcec.NewPrivateKey(btcec.S256()) 384 if err != nil { 385 t.Errorf("failed to make privKey for %s: %v", 386 msg, err) 387 break 388 } 389 390 pk := (*btcec.PublicKey)(&key.PublicKey). 391 SerializeUncompressed() 392 address, err := godashutil.NewAddressPubKey(pk, 393 &chaincfg.TestNet3Params) 394 if err != nil { 395 t.Errorf("failed to make address for %s: %v", 396 msg, err) 397 break 398 } 399 400 pkScript, err := txscript.PayToAddrScript(address) 401 if err != nil { 402 t.Errorf("failed to make pkscript "+ 403 "for %s: %v", msg, err) 404 } 405 406 sigScript, err := txscript.SignTxOutput( 407 &chaincfg.TestNet3Params, tx, i, pkScript, 408 hashType, mkGetKey(map[string]addressToKey{ 409 address.EncodeAddress(): {key, false}, 410 }), mkGetScript(nil), nil) 411 if err != nil { 412 t.Errorf("failed to sign output %s: %v", msg, 413 err) 414 break 415 } 416 417 // by the above loop, this should be valid, now sign 418 // again and merge. 419 sigScript, err = txscript.SignTxOutput( 420 &chaincfg.TestNet3Params, tx, i, pkScript, 421 hashType, mkGetKey(map[string]addressToKey{ 422 address.EncodeAddress(): {key, false}, 423 }), mkGetScript(nil), sigScript) 424 if err != nil { 425 t.Errorf("failed to sign output %s a "+ 426 "second time: %v", msg, err) 427 break 428 } 429 430 err = checkScripts(msg, tx, i, sigScript, pkScript) 431 if err != nil { 432 t.Errorf("twice signed script invalid for "+ 433 "%s: %v", msg, err) 434 break 435 } 436 } 437 } 438 439 // Pay to PubKey (compressed) 440 for _, hashType := range hashTypes { 441 for i := range tx.TxIn { 442 msg := fmt.Sprintf("%d:%d", hashType, i) 443 444 key, err := btcec.NewPrivateKey(btcec.S256()) 445 if err != nil { 446 t.Errorf("failed to make privKey for %s: %v", 447 msg, err) 448 break 449 } 450 451 pk := (*btcec.PublicKey)(&key.PublicKey). 452 SerializeCompressed() 453 address, err := godashutil.NewAddressPubKey(pk, 454 &chaincfg.TestNet3Params) 455 if err != nil { 456 t.Errorf("failed to make address for %s: %v", 457 msg, err) 458 break 459 } 460 461 pkScript, err := txscript.PayToAddrScript(address) 462 if err != nil { 463 t.Errorf("failed to make pkscript "+ 464 "for %s: %v", msg, err) 465 } 466 467 if err := signAndCheck(msg, tx, i, pkScript, hashType, 468 mkGetKey(map[string]addressToKey{ 469 address.EncodeAddress(): {key, true}, 470 }), mkGetScript(nil), nil); err != nil { 471 t.Error(err) 472 break 473 } 474 } 475 } 476 477 // Pay to PubKey (compressed) with duplicate merge 478 for _, hashType := range hashTypes { 479 for i := range tx.TxIn { 480 msg := fmt.Sprintf("%d:%d", hashType, i) 481 482 key, err := btcec.NewPrivateKey(btcec.S256()) 483 if err != nil { 484 t.Errorf("failed to make privKey for %s: %v", 485 msg, err) 486 break 487 } 488 489 pk := (*btcec.PublicKey)(&key.PublicKey). 490 SerializeCompressed() 491 address, err := godashutil.NewAddressPubKey(pk, 492 &chaincfg.TestNet3Params) 493 if err != nil { 494 t.Errorf("failed to make address for %s: %v", 495 msg, err) 496 break 497 } 498 499 pkScript, err := txscript.PayToAddrScript(address) 500 if err != nil { 501 t.Errorf("failed to make pkscript "+ 502 "for %s: %v", msg, err) 503 } 504 505 sigScript, err := txscript.SignTxOutput( 506 &chaincfg.TestNet3Params, tx, i, pkScript, 507 hashType, mkGetKey(map[string]addressToKey{ 508 address.EncodeAddress(): {key, true}, 509 }), mkGetScript(nil), nil) 510 if err != nil { 511 t.Errorf("failed to sign output %s: %v", msg, 512 err) 513 break 514 } 515 516 // by the above loop, this should be valid, now sign 517 // again and merge. 518 sigScript, err = txscript.SignTxOutput( 519 &chaincfg.TestNet3Params, tx, i, pkScript, 520 hashType, mkGetKey(map[string]addressToKey{ 521 address.EncodeAddress(): {key, true}, 522 }), mkGetScript(nil), sigScript) 523 if err != nil { 524 t.Errorf("failed to sign output %s a "+ 525 "second time: %v", msg, err) 526 break 527 } 528 529 err = checkScripts(msg, tx, i, sigScript, pkScript) 530 if err != nil { 531 t.Errorf("twice signed script invalid for "+ 532 "%s: %v", msg, err) 533 break 534 } 535 } 536 } 537 538 // As before, but with p2sh now. 539 // Pay to Pubkey Hash (uncompressed) 540 for _, hashType := range hashTypes { 541 for i := range tx.TxIn { 542 msg := fmt.Sprintf("%d:%d", hashType, i) 543 key, err := btcec.NewPrivateKey(btcec.S256()) 544 if err != nil { 545 t.Errorf("failed to make privKey for %s: %v", 546 msg, err) 547 break 548 } 549 550 pk := (*btcec.PublicKey)(&key.PublicKey). 551 SerializeUncompressed() 552 address, err := godashutil.NewAddressPubKeyHash( 553 godashutil.Hash160(pk), &chaincfg.TestNet3Params) 554 if err != nil { 555 t.Errorf("failed to make address for %s: %v", 556 msg, err) 557 break 558 } 559 560 pkScript, err := txscript.PayToAddrScript(address) 561 if err != nil { 562 t.Errorf("failed to make pkscript "+ 563 "for %s: %v", msg, err) 564 break 565 } 566 567 scriptAddr, err := godashutil.NewAddressScriptHash( 568 pkScript, &chaincfg.TestNet3Params) 569 if err != nil { 570 t.Errorf("failed to make p2sh addr for %s: %v", 571 msg, err) 572 break 573 } 574 575 scriptPkScript, err := txscript.PayToAddrScript( 576 scriptAddr) 577 if err != nil { 578 t.Errorf("failed to make script pkscript for "+ 579 "%s: %v", msg, err) 580 break 581 } 582 583 if err := signAndCheck(msg, tx, i, scriptPkScript, 584 hashType, 585 mkGetKey(map[string]addressToKey{ 586 address.EncodeAddress(): {key, false}, 587 }), mkGetScript(map[string][]byte{ 588 scriptAddr.EncodeAddress(): pkScript, 589 }), nil); err != nil { 590 t.Error(err) 591 break 592 } 593 } 594 } 595 596 // Pay to Pubkey Hash (uncompressed) with duplicate merge 597 for _, hashType := range hashTypes { 598 for i := range tx.TxIn { 599 msg := fmt.Sprintf("%d:%d", hashType, i) 600 key, err := btcec.NewPrivateKey(btcec.S256()) 601 if err != nil { 602 t.Errorf("failed to make privKey for %s: %v", 603 msg, err) 604 break 605 } 606 607 pk := (*btcec.PublicKey)(&key.PublicKey). 608 SerializeUncompressed() 609 address, err := godashutil.NewAddressPubKeyHash( 610 godashutil.Hash160(pk), &chaincfg.TestNet3Params) 611 if err != nil { 612 t.Errorf("failed to make address for %s: %v", 613 msg, err) 614 break 615 } 616 617 pkScript, err := txscript.PayToAddrScript(address) 618 if err != nil { 619 t.Errorf("failed to make pkscript "+ 620 "for %s: %v", msg, err) 621 break 622 } 623 624 scriptAddr, err := godashutil.NewAddressScriptHash( 625 pkScript, &chaincfg.TestNet3Params) 626 if err != nil { 627 t.Errorf("failed to make p2sh addr for %s: %v", 628 msg, err) 629 break 630 } 631 632 scriptPkScript, err := txscript.PayToAddrScript( 633 scriptAddr) 634 if err != nil { 635 t.Errorf("failed to make script pkscript for "+ 636 "%s: %v", msg, err) 637 break 638 } 639 640 sigScript, err := txscript.SignTxOutput( 641 &chaincfg.TestNet3Params, tx, i, scriptPkScript, 642 hashType, mkGetKey(map[string]addressToKey{ 643 address.EncodeAddress(): {key, false}, 644 }), mkGetScript(map[string][]byte{ 645 scriptAddr.EncodeAddress(): pkScript, 646 }), nil) 647 if err != nil { 648 t.Errorf("failed to sign output %s: %v", msg, 649 err) 650 break 651 } 652 653 // by the above loop, this should be valid, now sign 654 // again and merge. 655 sigScript, err = txscript.SignTxOutput( 656 &chaincfg.TestNet3Params, tx, i, scriptPkScript, 657 hashType, mkGetKey(map[string]addressToKey{ 658 address.EncodeAddress(): {key, false}, 659 }), mkGetScript(map[string][]byte{ 660 scriptAddr.EncodeAddress(): pkScript, 661 }), nil) 662 if err != nil { 663 t.Errorf("failed to sign output %s a "+ 664 "second time: %v", msg, err) 665 break 666 } 667 668 err = checkScripts(msg, tx, i, sigScript, scriptPkScript) 669 if err != nil { 670 t.Errorf("twice signed script invalid for "+ 671 "%s: %v", msg, err) 672 break 673 } 674 } 675 } 676 677 // Pay to Pubkey Hash (compressed) 678 for _, hashType := range hashTypes { 679 for i := range tx.TxIn { 680 msg := fmt.Sprintf("%d:%d", hashType, i) 681 682 key, err := btcec.NewPrivateKey(btcec.S256()) 683 if err != nil { 684 t.Errorf("failed to make privKey for %s: %v", 685 msg, err) 686 break 687 } 688 689 pk := (*btcec.PublicKey)(&key.PublicKey). 690 SerializeCompressed() 691 address, err := godashutil.NewAddressPubKeyHash( 692 godashutil.Hash160(pk), &chaincfg.TestNet3Params) 693 if err != nil { 694 t.Errorf("failed to make address for %s: %v", 695 msg, err) 696 break 697 } 698 699 pkScript, err := txscript.PayToAddrScript(address) 700 if err != nil { 701 t.Errorf("failed to make pkscript "+ 702 "for %s: %v", msg, err) 703 } 704 705 scriptAddr, err := godashutil.NewAddressScriptHash( 706 pkScript, &chaincfg.TestNet3Params) 707 if err != nil { 708 t.Errorf("failed to make p2sh addr for %s: %v", 709 msg, err) 710 break 711 } 712 713 scriptPkScript, err := txscript.PayToAddrScript( 714 scriptAddr) 715 if err != nil { 716 t.Errorf("failed to make script pkscript for "+ 717 "%s: %v", msg, err) 718 break 719 } 720 721 if err := signAndCheck(msg, tx, i, scriptPkScript, 722 hashType, 723 mkGetKey(map[string]addressToKey{ 724 address.EncodeAddress(): {key, true}, 725 }), mkGetScript(map[string][]byte{ 726 scriptAddr.EncodeAddress(): pkScript, 727 }), nil); err != nil { 728 t.Error(err) 729 break 730 } 731 } 732 } 733 734 // Pay to Pubkey Hash (compressed) with duplicate merge 735 for _, hashType := range hashTypes { 736 for i := range tx.TxIn { 737 msg := fmt.Sprintf("%d:%d", hashType, i) 738 739 key, err := btcec.NewPrivateKey(btcec.S256()) 740 if err != nil { 741 t.Errorf("failed to make privKey for %s: %v", 742 msg, err) 743 break 744 } 745 746 pk := (*btcec.PublicKey)(&key.PublicKey). 747 SerializeCompressed() 748 address, err := godashutil.NewAddressPubKeyHash( 749 godashutil.Hash160(pk), &chaincfg.TestNet3Params) 750 if err != nil { 751 t.Errorf("failed to make address for %s: %v", 752 msg, err) 753 break 754 } 755 756 pkScript, err := txscript.PayToAddrScript(address) 757 if err != nil { 758 t.Errorf("failed to make pkscript "+ 759 "for %s: %v", msg, err) 760 } 761 762 scriptAddr, err := godashutil.NewAddressScriptHash( 763 pkScript, &chaincfg.TestNet3Params) 764 if err != nil { 765 t.Errorf("failed to make p2sh addr for %s: %v", 766 msg, err) 767 break 768 } 769 770 scriptPkScript, err := txscript.PayToAddrScript( 771 scriptAddr) 772 if err != nil { 773 t.Errorf("failed to make script pkscript for "+ 774 "%s: %v", msg, err) 775 break 776 } 777 778 sigScript, err := txscript.SignTxOutput( 779 &chaincfg.TestNet3Params, tx, i, scriptPkScript, 780 hashType, mkGetKey(map[string]addressToKey{ 781 address.EncodeAddress(): {key, true}, 782 }), mkGetScript(map[string][]byte{ 783 scriptAddr.EncodeAddress(): pkScript, 784 }), nil) 785 if err != nil { 786 t.Errorf("failed to sign output %s: %v", msg, 787 err) 788 break 789 } 790 791 // by the above loop, this should be valid, now sign 792 // again and merge. 793 sigScript, err = txscript.SignTxOutput( 794 &chaincfg.TestNet3Params, tx, i, scriptPkScript, 795 hashType, mkGetKey(map[string]addressToKey{ 796 address.EncodeAddress(): {key, true}, 797 }), mkGetScript(map[string][]byte{ 798 scriptAddr.EncodeAddress(): pkScript, 799 }), nil) 800 if err != nil { 801 t.Errorf("failed to sign output %s a "+ 802 "second time: %v", msg, err) 803 break 804 } 805 806 err = checkScripts(msg, tx, i, sigScript, scriptPkScript) 807 if err != nil { 808 t.Errorf("twice signed script invalid for "+ 809 "%s: %v", msg, err) 810 break 811 } 812 } 813 } 814 815 // Pay to PubKey (uncompressed) 816 for _, hashType := range hashTypes { 817 for i := range tx.TxIn { 818 msg := fmt.Sprintf("%d:%d", hashType, i) 819 820 key, err := btcec.NewPrivateKey(btcec.S256()) 821 if err != nil { 822 t.Errorf("failed to make privKey for %s: %v", 823 msg, err) 824 break 825 } 826 827 pk := (*btcec.PublicKey)(&key.PublicKey). 828 SerializeUncompressed() 829 address, err := godashutil.NewAddressPubKey(pk, 830 &chaincfg.TestNet3Params) 831 if err != nil { 832 t.Errorf("failed to make address for %s: %v", 833 msg, err) 834 break 835 } 836 837 pkScript, err := txscript.PayToAddrScript(address) 838 if err != nil { 839 t.Errorf("failed to make pkscript "+ 840 "for %s: %v", msg, err) 841 } 842 843 scriptAddr, err := godashutil.NewAddressScriptHash( 844 pkScript, &chaincfg.TestNet3Params) 845 if err != nil { 846 t.Errorf("failed to make p2sh addr for %s: %v", 847 msg, err) 848 break 849 } 850 851 scriptPkScript, err := txscript.PayToAddrScript( 852 scriptAddr) 853 if err != nil { 854 t.Errorf("failed to make script pkscript for "+ 855 "%s: %v", msg, err) 856 break 857 } 858 859 if err := signAndCheck(msg, tx, i, scriptPkScript, 860 hashType, 861 mkGetKey(map[string]addressToKey{ 862 address.EncodeAddress(): {key, false}, 863 }), mkGetScript(map[string][]byte{ 864 scriptAddr.EncodeAddress(): pkScript, 865 }), nil); err != nil { 866 t.Error(err) 867 break 868 } 869 } 870 } 871 872 // Pay to PubKey (uncompressed) with duplicate merge 873 for _, hashType := range hashTypes { 874 for i := range tx.TxIn { 875 msg := fmt.Sprintf("%d:%d", hashType, i) 876 877 key, err := btcec.NewPrivateKey(btcec.S256()) 878 if err != nil { 879 t.Errorf("failed to make privKey for %s: %v", 880 msg, err) 881 break 882 } 883 884 pk := (*btcec.PublicKey)(&key.PublicKey). 885 SerializeUncompressed() 886 address, err := godashutil.NewAddressPubKey(pk, 887 &chaincfg.TestNet3Params) 888 if err != nil { 889 t.Errorf("failed to make address for %s: %v", 890 msg, err) 891 break 892 } 893 894 pkScript, err := txscript.PayToAddrScript(address) 895 if err != nil { 896 t.Errorf("failed to make pkscript "+ 897 "for %s: %v", msg, err) 898 } 899 900 scriptAddr, err := godashutil.NewAddressScriptHash( 901 pkScript, &chaincfg.TestNet3Params) 902 if err != nil { 903 t.Errorf("failed to make p2sh addr for %s: %v", 904 msg, err) 905 break 906 } 907 908 scriptPkScript, err := txscript.PayToAddrScript( 909 scriptAddr) 910 if err != nil { 911 t.Errorf("failed to make script pkscript for "+ 912 "%s: %v", msg, err) 913 break 914 } 915 916 sigScript, err := txscript.SignTxOutput( 917 &chaincfg.TestNet3Params, tx, i, scriptPkScript, 918 hashType, mkGetKey(map[string]addressToKey{ 919 address.EncodeAddress(): {key, false}, 920 }), mkGetScript(map[string][]byte{ 921 scriptAddr.EncodeAddress(): pkScript, 922 }), nil) 923 if err != nil { 924 t.Errorf("failed to sign output %s: %v", msg, 925 err) 926 break 927 } 928 929 // by the above loop, this should be valid, now sign 930 // again and merge. 931 sigScript, err = txscript.SignTxOutput( 932 &chaincfg.TestNet3Params, tx, i, scriptPkScript, 933 hashType, mkGetKey(map[string]addressToKey{ 934 address.EncodeAddress(): {key, false}, 935 }), mkGetScript(map[string][]byte{ 936 scriptAddr.EncodeAddress(): pkScript, 937 }), nil) 938 if err != nil { 939 t.Errorf("failed to sign output %s a "+ 940 "second time: %v", msg, err) 941 break 942 } 943 944 err = checkScripts(msg, tx, i, sigScript, scriptPkScript) 945 if err != nil { 946 t.Errorf("twice signed script invalid for "+ 947 "%s: %v", msg, err) 948 break 949 } 950 } 951 } 952 953 // Pay to PubKey (compressed) 954 for _, hashType := range hashTypes { 955 for i := range tx.TxIn { 956 msg := fmt.Sprintf("%d:%d", hashType, i) 957 958 key, err := btcec.NewPrivateKey(btcec.S256()) 959 if err != nil { 960 t.Errorf("failed to make privKey for %s: %v", 961 msg, err) 962 break 963 } 964 965 pk := (*btcec.PublicKey)(&key.PublicKey). 966 SerializeCompressed() 967 address, err := godashutil.NewAddressPubKey(pk, 968 &chaincfg.TestNet3Params) 969 if err != nil { 970 t.Errorf("failed to make address for %s: %v", 971 msg, err) 972 break 973 } 974 975 pkScript, err := txscript.PayToAddrScript(address) 976 if err != nil { 977 t.Errorf("failed to make pkscript "+ 978 "for %s: %v", msg, err) 979 } 980 981 scriptAddr, err := godashutil.NewAddressScriptHash( 982 pkScript, &chaincfg.TestNet3Params) 983 if err != nil { 984 t.Errorf("failed to make p2sh addr for %s: %v", 985 msg, err) 986 break 987 } 988 989 scriptPkScript, err := txscript.PayToAddrScript( 990 scriptAddr) 991 if err != nil { 992 t.Errorf("failed to make script pkscript for "+ 993 "%s: %v", msg, err) 994 break 995 } 996 997 if err := signAndCheck(msg, tx, i, scriptPkScript, 998 hashType, 999 mkGetKey(map[string]addressToKey{ 1000 address.EncodeAddress(): {key, true}, 1001 }), mkGetScript(map[string][]byte{ 1002 scriptAddr.EncodeAddress(): pkScript, 1003 }), nil); err != nil { 1004 t.Error(err) 1005 break 1006 } 1007 } 1008 } 1009 1010 // Pay to PubKey (compressed) 1011 for _, hashType := range hashTypes { 1012 for i := range tx.TxIn { 1013 msg := fmt.Sprintf("%d:%d", hashType, i) 1014 1015 key, err := btcec.NewPrivateKey(btcec.S256()) 1016 if err != nil { 1017 t.Errorf("failed to make privKey for %s: %v", 1018 msg, err) 1019 break 1020 } 1021 1022 pk := (*btcec.PublicKey)(&key.PublicKey). 1023 SerializeCompressed() 1024 address, err := godashutil.NewAddressPubKey(pk, 1025 &chaincfg.TestNet3Params) 1026 if err != nil { 1027 t.Errorf("failed to make address for %s: %v", 1028 msg, err) 1029 break 1030 } 1031 1032 pkScript, err := txscript.PayToAddrScript(address) 1033 if err != nil { 1034 t.Errorf("failed to make pkscript "+ 1035 "for %s: %v", msg, err) 1036 } 1037 1038 scriptAddr, err := godashutil.NewAddressScriptHash( 1039 pkScript, &chaincfg.TestNet3Params) 1040 if err != nil { 1041 t.Errorf("failed to make p2sh addr for %s: %v", 1042 msg, err) 1043 break 1044 } 1045 1046 scriptPkScript, err := txscript.PayToAddrScript( 1047 scriptAddr) 1048 if err != nil { 1049 t.Errorf("failed to make script pkscript for "+ 1050 "%s: %v", msg, err) 1051 break 1052 } 1053 1054 sigScript, err := txscript.SignTxOutput( 1055 &chaincfg.TestNet3Params, tx, i, scriptPkScript, 1056 hashType, mkGetKey(map[string]addressToKey{ 1057 address.EncodeAddress(): {key, true}, 1058 }), mkGetScript(map[string][]byte{ 1059 scriptAddr.EncodeAddress(): pkScript, 1060 }), nil) 1061 if err != nil { 1062 t.Errorf("failed to sign output %s: %v", msg, 1063 err) 1064 break 1065 } 1066 1067 // by the above loop, this should be valid, now sign 1068 // again and merge. 1069 sigScript, err = txscript.SignTxOutput( 1070 &chaincfg.TestNet3Params, tx, i, scriptPkScript, 1071 hashType, mkGetKey(map[string]addressToKey{ 1072 address.EncodeAddress(): {key, true}, 1073 }), mkGetScript(map[string][]byte{ 1074 scriptAddr.EncodeAddress(): pkScript, 1075 }), nil) 1076 if err != nil { 1077 t.Errorf("failed to sign output %s a "+ 1078 "second time: %v", msg, err) 1079 break 1080 } 1081 1082 err = checkScripts(msg, tx, i, sigScript, scriptPkScript) 1083 if err != nil { 1084 t.Errorf("twice signed script invalid for "+ 1085 "%s: %v", msg, err) 1086 break 1087 } 1088 } 1089 } 1090 1091 // Basic Multisig 1092 for _, hashType := range hashTypes { 1093 for i := range tx.TxIn { 1094 msg := fmt.Sprintf("%d:%d", hashType, i) 1095 1096 key1, err := btcec.NewPrivateKey(btcec.S256()) 1097 if err != nil { 1098 t.Errorf("failed to make privKey for %s: %v", 1099 msg, err) 1100 break 1101 } 1102 1103 pk1 := (*btcec.PublicKey)(&key1.PublicKey). 1104 SerializeCompressed() 1105 address1, err := godashutil.NewAddressPubKey(pk1, 1106 &chaincfg.TestNet3Params) 1107 if err != nil { 1108 t.Errorf("failed to make address for %s: %v", 1109 msg, err) 1110 break 1111 } 1112 1113 key2, err := btcec.NewPrivateKey(btcec.S256()) 1114 if err != nil { 1115 t.Errorf("failed to make privKey 2 for %s: %v", 1116 msg, err) 1117 break 1118 } 1119 1120 pk2 := (*btcec.PublicKey)(&key2.PublicKey). 1121 SerializeCompressed() 1122 address2, err := godashutil.NewAddressPubKey(pk2, 1123 &chaincfg.TestNet3Params) 1124 if err != nil { 1125 t.Errorf("failed to make address 2 for %s: %v", 1126 msg, err) 1127 break 1128 } 1129 1130 pkScript, err := txscript.MultiSigScript( 1131 []*godashutil.AddressPubKey{address1, address2}, 1132 2) 1133 if err != nil { 1134 t.Errorf("failed to make pkscript "+ 1135 "for %s: %v", msg, err) 1136 } 1137 1138 scriptAddr, err := godashutil.NewAddressScriptHash( 1139 pkScript, &chaincfg.TestNet3Params) 1140 if err != nil { 1141 t.Errorf("failed to make p2sh addr for %s: %v", 1142 msg, err) 1143 break 1144 } 1145 1146 scriptPkScript, err := txscript.PayToAddrScript( 1147 scriptAddr) 1148 if err != nil { 1149 t.Errorf("failed to make script pkscript for "+ 1150 "%s: %v", msg, err) 1151 break 1152 } 1153 1154 if err := signAndCheck(msg, tx, i, scriptPkScript, 1155 hashType, 1156 mkGetKey(map[string]addressToKey{ 1157 address1.EncodeAddress(): {key1, true}, 1158 address2.EncodeAddress(): {key2, true}, 1159 }), mkGetScript(map[string][]byte{ 1160 scriptAddr.EncodeAddress(): pkScript, 1161 }), nil); err != nil { 1162 t.Error(err) 1163 break 1164 } 1165 } 1166 } 1167 1168 // Two part multisig, sign with one key then the other. 1169 for _, hashType := range hashTypes { 1170 for i := range tx.TxIn { 1171 msg := fmt.Sprintf("%d:%d", hashType, i) 1172 1173 key1, err := btcec.NewPrivateKey(btcec.S256()) 1174 if err != nil { 1175 t.Errorf("failed to make privKey for %s: %v", 1176 msg, err) 1177 break 1178 } 1179 1180 pk1 := (*btcec.PublicKey)(&key1.PublicKey). 1181 SerializeCompressed() 1182 address1, err := godashutil.NewAddressPubKey(pk1, 1183 &chaincfg.TestNet3Params) 1184 if err != nil { 1185 t.Errorf("failed to make address for %s: %v", 1186 msg, err) 1187 break 1188 } 1189 1190 key2, err := btcec.NewPrivateKey(btcec.S256()) 1191 if err != nil { 1192 t.Errorf("failed to make privKey 2 for %s: %v", 1193 msg, err) 1194 break 1195 } 1196 1197 pk2 := (*btcec.PublicKey)(&key2.PublicKey). 1198 SerializeCompressed() 1199 address2, err := godashutil.NewAddressPubKey(pk2, 1200 &chaincfg.TestNet3Params) 1201 if err != nil { 1202 t.Errorf("failed to make address 2 for %s: %v", 1203 msg, err) 1204 break 1205 } 1206 1207 pkScript, err := txscript.MultiSigScript( 1208 []*godashutil.AddressPubKey{address1, address2}, 1209 2) 1210 if err != nil { 1211 t.Errorf("failed to make pkscript "+ 1212 "for %s: %v", msg, err) 1213 } 1214 1215 scriptAddr, err := godashutil.NewAddressScriptHash( 1216 pkScript, &chaincfg.TestNet3Params) 1217 if err != nil { 1218 t.Errorf("failed to make p2sh addr for %s: %v", 1219 msg, err) 1220 break 1221 } 1222 1223 scriptPkScript, err := txscript.PayToAddrScript( 1224 scriptAddr) 1225 if err != nil { 1226 t.Errorf("failed to make script pkscript for "+ 1227 "%s: %v", msg, err) 1228 break 1229 } 1230 1231 sigScript, err := txscript.SignTxOutput( 1232 &chaincfg.TestNet3Params, tx, i, scriptPkScript, 1233 hashType, mkGetKey(map[string]addressToKey{ 1234 address1.EncodeAddress(): {key1, true}, 1235 }), mkGetScript(map[string][]byte{ 1236 scriptAddr.EncodeAddress(): pkScript, 1237 }), nil) 1238 if err != nil { 1239 t.Errorf("failed to sign output %s: %v", msg, 1240 err) 1241 break 1242 } 1243 1244 // Only 1 out of 2 signed, this *should* fail. 1245 if checkScripts(msg, tx, i, sigScript, 1246 scriptPkScript) == nil { 1247 t.Errorf("part signed script valid for %s", msg) 1248 break 1249 } 1250 1251 // Sign with the other key and merge 1252 sigScript, err = txscript.SignTxOutput( 1253 &chaincfg.TestNet3Params, tx, i, scriptPkScript, 1254 hashType, mkGetKey(map[string]addressToKey{ 1255 address2.EncodeAddress(): {key2, true}, 1256 }), mkGetScript(map[string][]byte{ 1257 scriptAddr.EncodeAddress(): pkScript, 1258 }), sigScript) 1259 if err != nil { 1260 t.Errorf("failed to sign output %s: %v", msg, err) 1261 break 1262 } 1263 1264 err = checkScripts(msg, tx, i, sigScript, 1265 scriptPkScript) 1266 if err != nil { 1267 t.Errorf("fully signed script invalid for "+ 1268 "%s: %v", msg, err) 1269 break 1270 } 1271 } 1272 } 1273 1274 // Two part multisig, sign with one key then both, check key dedup 1275 // correctly. 1276 for _, hashType := range hashTypes { 1277 for i := range tx.TxIn { 1278 msg := fmt.Sprintf("%d:%d", hashType, i) 1279 1280 key1, err := btcec.NewPrivateKey(btcec.S256()) 1281 if err != nil { 1282 t.Errorf("failed to make privKey for %s: %v", 1283 msg, err) 1284 break 1285 } 1286 1287 pk1 := (*btcec.PublicKey)(&key1.PublicKey). 1288 SerializeCompressed() 1289 address1, err := godashutil.NewAddressPubKey(pk1, 1290 &chaincfg.TestNet3Params) 1291 if err != nil { 1292 t.Errorf("failed to make address for %s: %v", 1293 msg, err) 1294 break 1295 } 1296 1297 key2, err := btcec.NewPrivateKey(btcec.S256()) 1298 if err != nil { 1299 t.Errorf("failed to make privKey 2 for %s: %v", 1300 msg, err) 1301 break 1302 } 1303 1304 pk2 := (*btcec.PublicKey)(&key2.PublicKey). 1305 SerializeCompressed() 1306 address2, err := godashutil.NewAddressPubKey(pk2, 1307 &chaincfg.TestNet3Params) 1308 if err != nil { 1309 t.Errorf("failed to make address 2 for %s: %v", 1310 msg, err) 1311 break 1312 } 1313 1314 pkScript, err := txscript.MultiSigScript( 1315 []*godashutil.AddressPubKey{address1, address2}, 1316 2) 1317 if err != nil { 1318 t.Errorf("failed to make pkscript "+ 1319 "for %s: %v", msg, err) 1320 } 1321 1322 scriptAddr, err := godashutil.NewAddressScriptHash( 1323 pkScript, &chaincfg.TestNet3Params) 1324 if err != nil { 1325 t.Errorf("failed to make p2sh addr for %s: %v", 1326 msg, err) 1327 break 1328 } 1329 1330 scriptPkScript, err := txscript.PayToAddrScript( 1331 scriptAddr) 1332 if err != nil { 1333 t.Errorf("failed to make script pkscript for "+ 1334 "%s: %v", msg, err) 1335 break 1336 } 1337 1338 sigScript, err := txscript.SignTxOutput( 1339 &chaincfg.TestNet3Params, tx, i, scriptPkScript, 1340 hashType, mkGetKey(map[string]addressToKey{ 1341 address1.EncodeAddress(): {key1, true}, 1342 }), mkGetScript(map[string][]byte{ 1343 scriptAddr.EncodeAddress(): pkScript, 1344 }), nil) 1345 if err != nil { 1346 t.Errorf("failed to sign output %s: %v", msg, 1347 err) 1348 break 1349 } 1350 1351 // Only 1 out of 2 signed, this *should* fail. 1352 if checkScripts(msg, tx, i, sigScript, 1353 scriptPkScript) == nil { 1354 t.Errorf("part signed script valid for %s", msg) 1355 break 1356 } 1357 1358 // Sign with the other key and merge 1359 sigScript, err = txscript.SignTxOutput( 1360 &chaincfg.TestNet3Params, tx, i, scriptPkScript, 1361 hashType, mkGetKey(map[string]addressToKey{ 1362 address1.EncodeAddress(): {key1, true}, 1363 address2.EncodeAddress(): {key2, true}, 1364 }), mkGetScript(map[string][]byte{ 1365 scriptAddr.EncodeAddress(): pkScript, 1366 }), sigScript) 1367 if err != nil { 1368 t.Errorf("failed to sign output %s: %v", msg, err) 1369 break 1370 } 1371 1372 // Now we should pass. 1373 err = checkScripts(msg, tx, i, sigScript, 1374 scriptPkScript) 1375 if err != nil { 1376 t.Errorf("fully signed script invalid for "+ 1377 "%s: %v", msg, err) 1378 break 1379 } 1380 } 1381 } 1382 } 1383 1384 type tstInput struct { 1385 txout *wire.TxOut 1386 sigscriptGenerates bool 1387 inputValidates bool 1388 indexOutOfRange bool 1389 } 1390 1391 type tstSigScript struct { 1392 name string 1393 inputs []tstInput 1394 hashType txscript.SigHashType 1395 compress bool 1396 scriptAtWrongIndex bool 1397 } 1398 1399 var coinbaseOutPoint = &wire.OutPoint{ 1400 Index: (1 << 32) - 1, 1401 } 1402 1403 // Pregenerated private key, with associated public key and pkScripts 1404 // for the uncompressed and compressed hash160. 1405 var ( 1406 privKeyD = []byte{0x6b, 0x0f, 0xd8, 0xda, 0x54, 0x22, 0xd0, 0xb7, 1407 0xb4, 0xfc, 0x4e, 0x55, 0xd4, 0x88, 0x42, 0xb3, 0xa1, 0x65, 1408 0xac, 0x70, 0x7f, 0x3d, 0xa4, 0x39, 0x5e, 0xcb, 0x3b, 0xb0, 1409 0xd6, 0x0e, 0x06, 0x92} 1410 pubkeyX = []byte{0xb2, 0x52, 0xf0, 0x49, 0x85, 0x78, 0x03, 0x03, 0xc8, 1411 0x7d, 0xce, 0x51, 0x7f, 0xa8, 0x69, 0x0b, 0x91, 0x95, 0xf4, 1412 0xf3, 0x5c, 0x26, 0x73, 0x05, 0x05, 0xa2, 0xee, 0xbc, 0x09, 1413 0x38, 0x34, 0x3a} 1414 pubkeyY = []byte{0xb7, 0xc6, 0x7d, 0xb2, 0xe1, 0xff, 0xc8, 0x43, 0x1f, 1415 0x63, 0x32, 0x62, 0xaa, 0x60, 0xc6, 0x83, 0x30, 0xbd, 0x24, 1416 0x7e, 0xef, 0xdb, 0x6f, 0x2e, 0x8d, 0x56, 0xf0, 0x3c, 0x9f, 1417 0x6d, 0xb6, 0xf8} 1418 uncompressedPkScript = []byte{0x76, 0xa9, 0x14, 0xd1, 0x7c, 0xb5, 1419 0xeb, 0xa4, 0x02, 0xcb, 0x68, 0xe0, 0x69, 0x56, 0xbf, 0x32, 1420 0x53, 0x90, 0x0e, 0x0a, 0x86, 0xc9, 0xfa, 0x88, 0xac} 1421 compressedPkScript = []byte{0x76, 0xa9, 0x14, 0x27, 0x4d, 0x9f, 0x7f, 1422 0x61, 0x7e, 0x7c, 0x7a, 0x1c, 0x1f, 0xb2, 0x75, 0x79, 0x10, 1423 0x43, 0x65, 0x68, 0x27, 0x9d, 0x86, 0x88, 0xac} 1424 shortPkScript = []byte{0x76, 0xa9, 0x14, 0xd1, 0x7c, 0xb5, 1425 0xeb, 0xa4, 0x02, 0xcb, 0x68, 0xe0, 0x69, 0x56, 0xbf, 0x32, 1426 0x53, 0x90, 0x0e, 0x0a, 0x88, 0xac} 1427 uncompressedAddrStr = "1L6fd93zGmtzkK6CsZFVVoCwzZV3MUtJ4F" 1428 compressedAddrStr = "14apLppt9zTq6cNw8SDfiJhk9PhkZrQtYZ" 1429 ) 1430 1431 // Pretend output amounts. 1432 const coinbaseVal = 2500000000 1433 const fee = 5000000 1434 1435 var sigScriptTests = []tstSigScript{ 1436 { 1437 name: "one input uncompressed", 1438 inputs: []tstInput{ 1439 { 1440 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1441 sigscriptGenerates: true, 1442 inputValidates: true, 1443 indexOutOfRange: false, 1444 }, 1445 }, 1446 hashType: txscript.SigHashAll, 1447 compress: false, 1448 scriptAtWrongIndex: false, 1449 }, 1450 { 1451 name: "two inputs uncompressed", 1452 inputs: []tstInput{ 1453 { 1454 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1455 sigscriptGenerates: true, 1456 inputValidates: true, 1457 indexOutOfRange: false, 1458 }, 1459 { 1460 txout: wire.NewTxOut(coinbaseVal+fee, uncompressedPkScript), 1461 sigscriptGenerates: true, 1462 inputValidates: true, 1463 indexOutOfRange: false, 1464 }, 1465 }, 1466 hashType: txscript.SigHashAll, 1467 compress: false, 1468 scriptAtWrongIndex: false, 1469 }, 1470 { 1471 name: "one input compressed", 1472 inputs: []tstInput{ 1473 { 1474 txout: wire.NewTxOut(coinbaseVal, compressedPkScript), 1475 sigscriptGenerates: true, 1476 inputValidates: true, 1477 indexOutOfRange: false, 1478 }, 1479 }, 1480 hashType: txscript.SigHashAll, 1481 compress: true, 1482 scriptAtWrongIndex: false, 1483 }, 1484 { 1485 name: "two inputs compressed", 1486 inputs: []tstInput{ 1487 { 1488 txout: wire.NewTxOut(coinbaseVal, compressedPkScript), 1489 sigscriptGenerates: true, 1490 inputValidates: true, 1491 indexOutOfRange: false, 1492 }, 1493 { 1494 txout: wire.NewTxOut(coinbaseVal+fee, compressedPkScript), 1495 sigscriptGenerates: true, 1496 inputValidates: true, 1497 indexOutOfRange: false, 1498 }, 1499 }, 1500 hashType: txscript.SigHashAll, 1501 compress: true, 1502 scriptAtWrongIndex: false, 1503 }, 1504 { 1505 name: "hashType SigHashNone", 1506 inputs: []tstInput{ 1507 { 1508 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1509 sigscriptGenerates: true, 1510 inputValidates: true, 1511 indexOutOfRange: false, 1512 }, 1513 }, 1514 hashType: txscript.SigHashNone, 1515 compress: false, 1516 scriptAtWrongIndex: false, 1517 }, 1518 { 1519 name: "hashType SigHashSingle", 1520 inputs: []tstInput{ 1521 { 1522 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1523 sigscriptGenerates: true, 1524 inputValidates: true, 1525 indexOutOfRange: false, 1526 }, 1527 }, 1528 hashType: txscript.SigHashSingle, 1529 compress: false, 1530 scriptAtWrongIndex: false, 1531 }, 1532 { 1533 name: "hashType SigHashAnyoneCanPay", 1534 inputs: []tstInput{ 1535 { 1536 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1537 sigscriptGenerates: true, 1538 inputValidates: true, 1539 indexOutOfRange: false, 1540 }, 1541 }, 1542 hashType: txscript.SigHashAnyOneCanPay, 1543 compress: false, 1544 scriptAtWrongIndex: false, 1545 }, 1546 { 1547 name: "hashType non-standard", 1548 inputs: []tstInput{ 1549 { 1550 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1551 sigscriptGenerates: true, 1552 inputValidates: true, 1553 indexOutOfRange: false, 1554 }, 1555 }, 1556 hashType: 0x04, 1557 compress: false, 1558 scriptAtWrongIndex: false, 1559 }, 1560 { 1561 name: "invalid compression", 1562 inputs: []tstInput{ 1563 { 1564 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1565 sigscriptGenerates: true, 1566 inputValidates: false, 1567 indexOutOfRange: false, 1568 }, 1569 }, 1570 hashType: txscript.SigHashAll, 1571 compress: true, 1572 scriptAtWrongIndex: false, 1573 }, 1574 { 1575 name: "short PkScript", 1576 inputs: []tstInput{ 1577 { 1578 txout: wire.NewTxOut(coinbaseVal, shortPkScript), 1579 sigscriptGenerates: false, 1580 indexOutOfRange: false, 1581 }, 1582 }, 1583 hashType: txscript.SigHashAll, 1584 compress: false, 1585 scriptAtWrongIndex: false, 1586 }, 1587 { 1588 name: "valid script at wrong index", 1589 inputs: []tstInput{ 1590 { 1591 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1592 sigscriptGenerates: true, 1593 inputValidates: true, 1594 indexOutOfRange: false, 1595 }, 1596 { 1597 txout: wire.NewTxOut(coinbaseVal+fee, uncompressedPkScript), 1598 sigscriptGenerates: true, 1599 inputValidates: true, 1600 indexOutOfRange: false, 1601 }, 1602 }, 1603 hashType: txscript.SigHashAll, 1604 compress: false, 1605 scriptAtWrongIndex: true, 1606 }, 1607 { 1608 name: "index out of range", 1609 inputs: []tstInput{ 1610 { 1611 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript), 1612 sigscriptGenerates: true, 1613 inputValidates: true, 1614 indexOutOfRange: false, 1615 }, 1616 { 1617 txout: wire.NewTxOut(coinbaseVal+fee, uncompressedPkScript), 1618 sigscriptGenerates: true, 1619 inputValidates: true, 1620 indexOutOfRange: false, 1621 }, 1622 }, 1623 hashType: txscript.SigHashAll, 1624 compress: false, 1625 scriptAtWrongIndex: true, 1626 }, 1627 } 1628 1629 // Test the sigscript generation for valid and invalid inputs, all 1630 // hashTypes, and with and without compression. This test creates 1631 // sigscripts to spend fake coinbase inputs, as sigscripts cannot be 1632 // created for the MsgTxs in txTests, since they come from the blockchain 1633 // and we don't have the private keys. 1634 func TestSignatureScript(t *testing.T) { 1635 t.Parallel() 1636 1637 privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), privKeyD) 1638 1639 nexttest: 1640 for i := range sigScriptTests { 1641 tx := wire.NewMsgTx() 1642 1643 output := wire.NewTxOut(500, []byte{txscript.OP_RETURN}) 1644 tx.AddTxOut(output) 1645 1646 for range sigScriptTests[i].inputs { 1647 txin := wire.NewTxIn(coinbaseOutPoint, nil) 1648 tx.AddTxIn(txin) 1649 } 1650 1651 var script []byte 1652 var err error 1653 for j := range tx.TxIn { 1654 var idx int 1655 if sigScriptTests[i].inputs[j].indexOutOfRange { 1656 t.Errorf("at test %v", sigScriptTests[i].name) 1657 idx = len(sigScriptTests[i].inputs) 1658 } else { 1659 idx = j 1660 } 1661 script, err = txscript.SignatureScript(tx, idx, 1662 sigScriptTests[i].inputs[j].txout.PkScript, 1663 sigScriptTests[i].hashType, privKey, 1664 sigScriptTests[i].compress) 1665 1666 if (err == nil) != sigScriptTests[i].inputs[j].sigscriptGenerates { 1667 if err == nil { 1668 t.Errorf("passed test '%v' incorrectly", 1669 sigScriptTests[i].name) 1670 } else { 1671 t.Errorf("failed test '%v': %v", 1672 sigScriptTests[i].name, err) 1673 } 1674 continue nexttest 1675 } 1676 if !sigScriptTests[i].inputs[j].sigscriptGenerates { 1677 // done with this test 1678 continue nexttest 1679 } 1680 1681 tx.TxIn[j].SignatureScript = script 1682 } 1683 1684 // If testing using a correct sigscript but for an incorrect 1685 // index, use last input script for first input. Requires > 0 1686 // inputs for test. 1687 if sigScriptTests[i].scriptAtWrongIndex { 1688 tx.TxIn[0].SignatureScript = script 1689 sigScriptTests[i].inputs[0].inputValidates = false 1690 } 1691 1692 // Validate tx input scripts 1693 scriptFlags := txscript.ScriptBip16 | txscript.ScriptVerifyDERSignatures 1694 for j := range tx.TxIn { 1695 vm, err := txscript.NewEngine(sigScriptTests[i]. 1696 inputs[j].txout.PkScript, tx, j, scriptFlags, nil) 1697 if err != nil { 1698 t.Errorf("cannot create script vm for test %v: %v", 1699 sigScriptTests[i].name, err) 1700 continue nexttest 1701 } 1702 err = vm.Execute() 1703 if (err == nil) != sigScriptTests[i].inputs[j].inputValidates { 1704 if err == nil { 1705 t.Errorf("passed test '%v' validation incorrectly: %v", 1706 sigScriptTests[i].name, err) 1707 } else { 1708 t.Errorf("failed test '%v' validation: %v", 1709 sigScriptTests[i].name, err) 1710 } 1711 continue nexttest 1712 } 1713 } 1714 } 1715 }