1 // Copyright (c) 2013-2016 The btcsuite developers
2 // Use of this source code is governed by an ISC
3 // license that can be found in the LICENSE file.
12 "github.com/btcsuite/btcd/btcec"
13 "github.com/btcsuite/btcd/chaincfg"
14 "github.com/btcsuite/btcd/chaincfg/chainhash"
15 "github.com/btcsuite/btcd/wire"
16 "github.com/btcsuite/btcutil"
19 type addressToKey struct {
24 func mkGetKey(keys map[string]addressToKey) KeyDB {
26 return KeyClosure(func(addr btcutil.Address) (*btcec.PrivateKey,
28 return nil, false, errors.New("nope")
31 return KeyClosure(func(addr btcutil.Address) (*btcec.PrivateKey,
33 a2k, ok := keys[addr.EncodeAddress()]
35 return nil, false, errors.New("nope")
37 return a2k.key, a2k.compressed, nil
41 func mkGetScript(scripts map[string][]byte) ScriptDB {
43 return ScriptClosure(func(addr btcutil.Address) ([]byte, error) {
44 return nil, errors.New("nope")
47 return ScriptClosure(func(addr btcutil.Address) ([]byte, error) {
48 script, ok := scripts[addr.EncodeAddress()]
50 return nil, errors.New("nope")
56 func checkScripts(msg string, tx *wire.MsgTx, idx int, inputAmt int64, sigScript, pkScript []byte) error {
57 tx.TxIn[idx].SignatureScript = sigScript
58 vm, err := NewEngine(pkScript, tx, idx,
59 ScriptBip16|ScriptVerifyDERSignatures, nil, nil, inputAmt)
61 return fmt.Errorf("failed to make script engine for %s: %v",
67 return fmt.Errorf("invalid script signature for %s: %v", msg,
74 func signAndCheck(msg string, tx *wire.MsgTx, idx int, inputAmt int64, pkScript []byte,
75 hashType SigHashType, kdb KeyDB, sdb ScriptDB,
76 previousScript []byte) error {
78 sigScript, err := SignTxOutput(&chaincfg.TestNet3Params, tx, idx,
79 pkScript, hashType, kdb, sdb, nil)
81 return fmt.Errorf("failed to sign output %s: %v", msg, err)
84 return checkScripts(msg, tx, idx, inputAmt, sigScript, pkScript)
87 func TestSignTxOutput(t *testing.T) {
91 // make script based on key.
92 // sign with magic pixie dust.
93 hashTypes := []SigHashType{
94 SigHashOld, // no longer used but should act like all
98 SigHashAll | SigHashAnyOneCanPay,
99 SigHashNone | SigHashAnyOneCanPay,
100 SigHashSingle | SigHashAnyOneCanPay,
102 inputAmounts := []int64{5, 10, 15}
107 PreviousOutPoint: wire.OutPoint{
108 Hash: chainhash.Hash{},
111 Sequence: 4294967295,
114 PreviousOutPoint: wire.OutPoint{
115 Hash: chainhash.Hash{},
118 Sequence: 4294967295,
121 PreviousOutPoint: wire.OutPoint{
122 Hash: chainhash.Hash{},
125 Sequence: 4294967295,
128 TxOut: []*wire.TxOut{
142 // Pay to Pubkey Hash (uncompressed)
143 for _, hashType := range hashTypes {
144 for i := range tx.TxIn {
145 msg := fmt.Sprintf("%d:%d", hashType, i)
146 key, err := btcec.NewPrivateKey(btcec.S256())
148 t.Errorf("failed to make privKey for %s: %v",
153 pk := (*btcec.PublicKey)(&key.PublicKey).
154 SerializeUncompressed()
155 address, err := btcutil.NewAddressPubKeyHash(
156 btcutil.Hash160(pk), &chaincfg.TestNet3Params)
158 t.Errorf("failed to make address for %s: %v",
163 pkScript, err := PayToAddrScript(address)
165 t.Errorf("failed to make pkscript "+
166 "for %s: %v", msg, err)
169 if err := signAndCheck(msg, tx, i, inputAmounts[i], pkScript, hashType,
170 mkGetKey(map[string]addressToKey{
171 address.EncodeAddress(): {key, false},
172 }), mkGetScript(nil), nil); err != nil {
179 // Pay to Pubkey Hash (uncompressed) (merging with correct)
180 for _, hashType := range hashTypes {
181 for i := range tx.TxIn {
182 msg := fmt.Sprintf("%d:%d", hashType, i)
183 key, err := btcec.NewPrivateKey(btcec.S256())
185 t.Errorf("failed to make privKey for %s: %v",
190 pk := (*btcec.PublicKey)(&key.PublicKey).
191 SerializeUncompressed()
192 address, err := btcutil.NewAddressPubKeyHash(
193 btcutil.Hash160(pk), &chaincfg.TestNet3Params)
195 t.Errorf("failed to make address for %s: %v",
200 pkScript, err := PayToAddrScript(address)
202 t.Errorf("failed to make pkscript "+
203 "for %s: %v", msg, err)
206 sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
207 tx, i, pkScript, hashType,
208 mkGetKey(map[string]addressToKey{
209 address.EncodeAddress(): {key, false},
210 }), mkGetScript(nil), nil)
212 t.Errorf("failed to sign output %s: %v", msg,
217 // by the above loop, this should be valid, now sign
219 sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
220 tx, i, pkScript, hashType,
221 mkGetKey(map[string]addressToKey{
222 address.EncodeAddress(): {key, false},
223 }), mkGetScript(nil), sigScript)
225 t.Errorf("failed to sign output %s a "+
226 "second time: %v", msg, err)
230 err = checkScripts(msg, tx, i, inputAmounts[i], sigScript, pkScript)
232 t.Errorf("twice signed script invalid for "+
239 // Pay to Pubkey Hash (compressed)
240 for _, hashType := range hashTypes {
241 for i := range tx.TxIn {
242 msg := fmt.Sprintf("%d:%d", hashType, i)
244 key, err := btcec.NewPrivateKey(btcec.S256())
246 t.Errorf("failed to make privKey for %s: %v",
251 pk := (*btcec.PublicKey)(&key.PublicKey).
252 SerializeCompressed()
253 address, err := btcutil.NewAddressPubKeyHash(
254 btcutil.Hash160(pk), &chaincfg.TestNet3Params)
256 t.Errorf("failed to make address for %s: %v",
261 pkScript, err := PayToAddrScript(address)
263 t.Errorf("failed to make pkscript "+
264 "for %s: %v", msg, err)
267 if err := signAndCheck(msg, tx, i, inputAmounts[i],
269 mkGetKey(map[string]addressToKey{
270 address.EncodeAddress(): {key, true},
271 }), mkGetScript(nil), nil); err != nil {
278 // Pay to Pubkey Hash (compressed) with duplicate merge
279 for _, hashType := range hashTypes {
280 for i := range tx.TxIn {
281 msg := fmt.Sprintf("%d:%d", hashType, i)
283 key, err := btcec.NewPrivateKey(btcec.S256())
285 t.Errorf("failed to make privKey for %s: %v",
290 pk := (*btcec.PublicKey)(&key.PublicKey).
291 SerializeCompressed()
292 address, err := btcutil.NewAddressPubKeyHash(
293 btcutil.Hash160(pk), &chaincfg.TestNet3Params)
295 t.Errorf("failed to make address for %s: %v",
300 pkScript, err := PayToAddrScript(address)
302 t.Errorf("failed to make pkscript "+
303 "for %s: %v", msg, err)
306 sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
307 tx, i, pkScript, hashType,
308 mkGetKey(map[string]addressToKey{
309 address.EncodeAddress(): {key, true},
310 }), mkGetScript(nil), nil)
312 t.Errorf("failed to sign output %s: %v", msg,
317 // by the above loop, this should be valid, now sign
319 sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
320 tx, i, pkScript, hashType,
321 mkGetKey(map[string]addressToKey{
322 address.EncodeAddress(): {key, true},
323 }), mkGetScript(nil), sigScript)
325 t.Errorf("failed to sign output %s a "+
326 "second time: %v", msg, err)
330 err = checkScripts(msg, tx, i, inputAmounts[i],
333 t.Errorf("twice signed script invalid for "+
340 // Pay to PubKey (uncompressed)
341 for _, hashType := range hashTypes {
342 for i := range tx.TxIn {
343 msg := fmt.Sprintf("%d:%d", hashType, i)
345 key, err := btcec.NewPrivateKey(btcec.S256())
347 t.Errorf("failed to make privKey for %s: %v",
352 pk := (*btcec.PublicKey)(&key.PublicKey).
353 SerializeUncompressed()
354 address, err := btcutil.NewAddressPubKey(pk,
355 &chaincfg.TestNet3Params)
357 t.Errorf("failed to make address for %s: %v",
362 pkScript, err := PayToAddrScript(address)
364 t.Errorf("failed to make pkscript "+
365 "for %s: %v", msg, err)
368 if err := signAndCheck(msg, tx, i, inputAmounts[i],
370 mkGetKey(map[string]addressToKey{
371 address.EncodeAddress(): {key, false},
372 }), mkGetScript(nil), nil); err != nil {
379 // Pay to PubKey (uncompressed)
380 for _, hashType := range hashTypes {
381 for i := range tx.TxIn {
382 msg := fmt.Sprintf("%d:%d", hashType, i)
384 key, err := btcec.NewPrivateKey(btcec.S256())
386 t.Errorf("failed to make privKey for %s: %v",
391 pk := (*btcec.PublicKey)(&key.PublicKey).
392 SerializeUncompressed()
393 address, err := btcutil.NewAddressPubKey(pk,
394 &chaincfg.TestNet3Params)
396 t.Errorf("failed to make address for %s: %v",
401 pkScript, err := PayToAddrScript(address)
403 t.Errorf("failed to make pkscript "+
404 "for %s: %v", msg, err)
407 sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
408 tx, i, pkScript, hashType,
409 mkGetKey(map[string]addressToKey{
410 address.EncodeAddress(): {key, false},
411 }), mkGetScript(nil), nil)
413 t.Errorf("failed to sign output %s: %v", msg,
418 // by the above loop, this should be valid, now sign
420 sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
421 tx, i, pkScript, hashType,
422 mkGetKey(map[string]addressToKey{
423 address.EncodeAddress(): {key, false},
424 }), mkGetScript(nil), sigScript)
426 t.Errorf("failed to sign output %s a "+
427 "second time: %v", msg, err)
431 err = checkScripts(msg, tx, i, inputAmounts[i], sigScript, pkScript)
433 t.Errorf("twice signed script invalid for "+
440 // Pay to PubKey (compressed)
441 for _, hashType := range hashTypes {
442 for i := range tx.TxIn {
443 msg := fmt.Sprintf("%d:%d", hashType, i)
445 key, err := btcec.NewPrivateKey(btcec.S256())
447 t.Errorf("failed to make privKey for %s: %v",
452 pk := (*btcec.PublicKey)(&key.PublicKey).
453 SerializeCompressed()
454 address, err := btcutil.NewAddressPubKey(pk,
455 &chaincfg.TestNet3Params)
457 t.Errorf("failed to make address for %s: %v",
462 pkScript, err := PayToAddrScript(address)
464 t.Errorf("failed to make pkscript "+
465 "for %s: %v", msg, err)
468 if err := signAndCheck(msg, tx, i, inputAmounts[i],
470 mkGetKey(map[string]addressToKey{
471 address.EncodeAddress(): {key, true},
472 }), mkGetScript(nil), nil); err != nil {
479 // Pay to PubKey (compressed) with duplicate merge
480 for _, hashType := range hashTypes {
481 for i := range tx.TxIn {
482 msg := fmt.Sprintf("%d:%d", hashType, i)
484 key, err := btcec.NewPrivateKey(btcec.S256())
486 t.Errorf("failed to make privKey for %s: %v",
491 pk := (*btcec.PublicKey)(&key.PublicKey).
492 SerializeCompressed()
493 address, err := btcutil.NewAddressPubKey(pk,
494 &chaincfg.TestNet3Params)
496 t.Errorf("failed to make address for %s: %v",
501 pkScript, err := PayToAddrScript(address)
503 t.Errorf("failed to make pkscript "+
504 "for %s: %v", msg, err)
507 sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
508 tx, i, pkScript, hashType,
509 mkGetKey(map[string]addressToKey{
510 address.EncodeAddress(): {key, true},
511 }), mkGetScript(nil), nil)
513 t.Errorf("failed to sign output %s: %v", msg,
518 // by the above loop, this should be valid, now sign
520 sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
521 tx, i, pkScript, hashType,
522 mkGetKey(map[string]addressToKey{
523 address.EncodeAddress(): {key, true},
524 }), mkGetScript(nil), sigScript)
526 t.Errorf("failed to sign output %s a "+
527 "second time: %v", msg, err)
531 err = checkScripts(msg, tx, i, inputAmounts[i],
534 t.Errorf("twice signed script invalid for "+
541 // As before, but with p2sh now.
542 // Pay to Pubkey Hash (uncompressed)
543 for _, hashType := range hashTypes {
544 for i := range tx.TxIn {
545 msg := fmt.Sprintf("%d:%d", hashType, i)
546 key, err := btcec.NewPrivateKey(btcec.S256())
548 t.Errorf("failed to make privKey for %s: %v",
553 pk := (*btcec.PublicKey)(&key.PublicKey).
554 SerializeUncompressed()
555 address, err := btcutil.NewAddressPubKeyHash(
556 btcutil.Hash160(pk), &chaincfg.TestNet3Params)
558 t.Errorf("failed to make address for %s: %v",
563 pkScript, err := PayToAddrScript(address)
565 t.Errorf("failed to make pkscript "+
566 "for %s: %v", msg, err)
570 scriptAddr, err := btcutil.NewAddressScriptHash(
571 pkScript, &chaincfg.TestNet3Params)
573 t.Errorf("failed to make p2sh addr for %s: %v",
578 scriptPkScript, err := PayToAddrScript(
581 t.Errorf("failed to make script pkscript for "+
586 if err := signAndCheck(msg, tx, i, inputAmounts[i],
587 scriptPkScript, hashType,
588 mkGetKey(map[string]addressToKey{
589 address.EncodeAddress(): {key, false},
590 }), mkGetScript(map[string][]byte{
591 scriptAddr.EncodeAddress(): pkScript,
592 }), nil); err != nil {
599 // Pay to Pubkey Hash (uncompressed) with duplicate merge
600 for _, hashType := range hashTypes {
601 for i := range tx.TxIn {
602 msg := fmt.Sprintf("%d:%d", hashType, i)
603 key, err := btcec.NewPrivateKey(btcec.S256())
605 t.Errorf("failed to make privKey for %s: %v",
610 pk := (*btcec.PublicKey)(&key.PublicKey).
611 SerializeUncompressed()
612 address, err := btcutil.NewAddressPubKeyHash(
613 btcutil.Hash160(pk), &chaincfg.TestNet3Params)
615 t.Errorf("failed to make address for %s: %v",
620 pkScript, err := PayToAddrScript(address)
622 t.Errorf("failed to make pkscript "+
623 "for %s: %v", msg, err)
627 scriptAddr, err := btcutil.NewAddressScriptHash(
628 pkScript, &chaincfg.TestNet3Params)
630 t.Errorf("failed to make p2sh addr for %s: %v",
635 scriptPkScript, err := PayToAddrScript(
638 t.Errorf("failed to make script pkscript for "+
643 sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
644 tx, i, scriptPkScript, hashType,
645 mkGetKey(map[string]addressToKey{
646 address.EncodeAddress(): {key, false},
647 }), mkGetScript(map[string][]byte{
648 scriptAddr.EncodeAddress(): pkScript,
651 t.Errorf("failed to sign output %s: %v", msg,
656 // by the above loop, this should be valid, now sign
658 sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
659 tx, i, scriptPkScript, hashType,
660 mkGetKey(map[string]addressToKey{
661 address.EncodeAddress(): {key, false},
662 }), mkGetScript(map[string][]byte{
663 scriptAddr.EncodeAddress(): pkScript,
666 t.Errorf("failed to sign output %s a "+
667 "second time: %v", msg, err)
671 err = checkScripts(msg, tx, i, inputAmounts[i],
672 sigScript, scriptPkScript)
674 t.Errorf("twice signed script invalid for "+
681 // Pay to Pubkey Hash (compressed)
682 for _, hashType := range hashTypes {
683 for i := range tx.TxIn {
684 msg := fmt.Sprintf("%d:%d", hashType, i)
686 key, err := btcec.NewPrivateKey(btcec.S256())
688 t.Errorf("failed to make privKey for %s: %v",
693 pk := (*btcec.PublicKey)(&key.PublicKey).
694 SerializeCompressed()
695 address, err := btcutil.NewAddressPubKeyHash(
696 btcutil.Hash160(pk), &chaincfg.TestNet3Params)
698 t.Errorf("failed to make address for %s: %v",
703 pkScript, err := PayToAddrScript(address)
705 t.Errorf("failed to make pkscript "+
706 "for %s: %v", msg, err)
709 scriptAddr, err := btcutil.NewAddressScriptHash(
710 pkScript, &chaincfg.TestNet3Params)
712 t.Errorf("failed to make p2sh addr for %s: %v",
717 scriptPkScript, err := PayToAddrScript(
720 t.Errorf("failed to make script pkscript for "+
725 if err := signAndCheck(msg, tx, i, inputAmounts[i],
726 scriptPkScript, hashType,
727 mkGetKey(map[string]addressToKey{
728 address.EncodeAddress(): {key, true},
729 }), mkGetScript(map[string][]byte{
730 scriptAddr.EncodeAddress(): pkScript,
731 }), nil); err != nil {
738 // Pay to Pubkey Hash (compressed) with duplicate merge
739 for _, hashType := range hashTypes {
740 for i := range tx.TxIn {
741 msg := fmt.Sprintf("%d:%d", hashType, i)
743 key, err := btcec.NewPrivateKey(btcec.S256())
745 t.Errorf("failed to make privKey for %s: %v",
750 pk := (*btcec.PublicKey)(&key.PublicKey).
751 SerializeCompressed()
752 address, err := btcutil.NewAddressPubKeyHash(
753 btcutil.Hash160(pk), &chaincfg.TestNet3Params)
755 t.Errorf("failed to make address for %s: %v",
760 pkScript, err := PayToAddrScript(address)
762 t.Errorf("failed to make pkscript "+
763 "for %s: %v", msg, err)
766 scriptAddr, err := btcutil.NewAddressScriptHash(
767 pkScript, &chaincfg.TestNet3Params)
769 t.Errorf("failed to make p2sh addr for %s: %v",
774 scriptPkScript, err := PayToAddrScript(
777 t.Errorf("failed to make script pkscript for "+
782 sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
783 tx, i, scriptPkScript, hashType,
784 mkGetKey(map[string]addressToKey{
785 address.EncodeAddress(): {key, true},
786 }), mkGetScript(map[string][]byte{
787 scriptAddr.EncodeAddress(): pkScript,
790 t.Errorf("failed to sign output %s: %v", msg,
795 // by the above loop, this should be valid, now sign
797 sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
798 tx, i, scriptPkScript, hashType,
799 mkGetKey(map[string]addressToKey{
800 address.EncodeAddress(): {key, true},
801 }), mkGetScript(map[string][]byte{
802 scriptAddr.EncodeAddress(): pkScript,
805 t.Errorf("failed to sign output %s a "+
806 "second time: %v", msg, err)
810 err = checkScripts(msg, tx, i, inputAmounts[i],
811 sigScript, scriptPkScript)
813 t.Errorf("twice signed script invalid for "+
820 // Pay to PubKey (uncompressed)
821 for _, hashType := range hashTypes {
822 for i := range tx.TxIn {
823 msg := fmt.Sprintf("%d:%d", hashType, i)
825 key, err := btcec.NewPrivateKey(btcec.S256())
827 t.Errorf("failed to make privKey for %s: %v",
832 pk := (*btcec.PublicKey)(&key.PublicKey).
833 SerializeUncompressed()
834 address, err := btcutil.NewAddressPubKey(pk,
835 &chaincfg.TestNet3Params)
837 t.Errorf("failed to make address for %s: %v",
842 pkScript, err := PayToAddrScript(address)
844 t.Errorf("failed to make pkscript "+
845 "for %s: %v", msg, err)
848 scriptAddr, err := btcutil.NewAddressScriptHash(
849 pkScript, &chaincfg.TestNet3Params)
851 t.Errorf("failed to make p2sh addr for %s: %v",
856 scriptPkScript, err := PayToAddrScript(
859 t.Errorf("failed to make script pkscript for "+
864 if err := signAndCheck(msg, tx, i, inputAmounts[i],
865 scriptPkScript, hashType,
866 mkGetKey(map[string]addressToKey{
867 address.EncodeAddress(): {key, false},
868 }), mkGetScript(map[string][]byte{
869 scriptAddr.EncodeAddress(): pkScript,
870 }), nil); err != nil {
877 // Pay to PubKey (uncompressed) with duplicate merge
878 for _, hashType := range hashTypes {
879 for i := range tx.TxIn {
880 msg := fmt.Sprintf("%d:%d", hashType, i)
882 key, err := btcec.NewPrivateKey(btcec.S256())
884 t.Errorf("failed to make privKey for %s: %v",
889 pk := (*btcec.PublicKey)(&key.PublicKey).
890 SerializeUncompressed()
891 address, err := btcutil.NewAddressPubKey(pk,
892 &chaincfg.TestNet3Params)
894 t.Errorf("failed to make address for %s: %v",
899 pkScript, err := PayToAddrScript(address)
901 t.Errorf("failed to make pkscript "+
902 "for %s: %v", msg, err)
905 scriptAddr, err := btcutil.NewAddressScriptHash(
906 pkScript, &chaincfg.TestNet3Params)
908 t.Errorf("failed to make p2sh addr for %s: %v",
913 scriptPkScript, err := PayToAddrScript(scriptAddr)
915 t.Errorf("failed to make script pkscript for "+
920 sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
921 tx, i, scriptPkScript, hashType,
922 mkGetKey(map[string]addressToKey{
923 address.EncodeAddress(): {key, false},
924 }), mkGetScript(map[string][]byte{
925 scriptAddr.EncodeAddress(): pkScript,
928 t.Errorf("failed to sign output %s: %v", msg,
933 // by the above loop, this should be valid, now sign
935 sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
936 tx, i, scriptPkScript, hashType,
937 mkGetKey(map[string]addressToKey{
938 address.EncodeAddress(): {key, false},
939 }), mkGetScript(map[string][]byte{
940 scriptAddr.EncodeAddress(): pkScript,
943 t.Errorf("failed to sign output %s a "+
944 "second time: %v", msg, err)
948 err = checkScripts(msg, tx, i, inputAmounts[i],
949 sigScript, scriptPkScript)
951 t.Errorf("twice signed script invalid for "+
958 // Pay to PubKey (compressed)
959 for _, hashType := range hashTypes {
960 for i := range tx.TxIn {
961 msg := fmt.Sprintf("%d:%d", hashType, i)
963 key, err := btcec.NewPrivateKey(btcec.S256())
965 t.Errorf("failed to make privKey for %s: %v",
970 pk := (*btcec.PublicKey)(&key.PublicKey).
971 SerializeCompressed()
972 address, err := btcutil.NewAddressPubKey(pk,
973 &chaincfg.TestNet3Params)
975 t.Errorf("failed to make address for %s: %v",
980 pkScript, err := PayToAddrScript(address)
982 t.Errorf("failed to make pkscript "+
983 "for %s: %v", msg, err)
986 scriptAddr, err := btcutil.NewAddressScriptHash(
987 pkScript, &chaincfg.TestNet3Params)
989 t.Errorf("failed to make p2sh addr for %s: %v",
994 scriptPkScript, err := PayToAddrScript(scriptAddr)
996 t.Errorf("failed to make script pkscript for "+
1001 if err := signAndCheck(msg, tx, i, inputAmounts[i],
1002 scriptPkScript, hashType,
1003 mkGetKey(map[string]addressToKey{
1004 address.EncodeAddress(): {key, true},
1005 }), mkGetScript(map[string][]byte{
1006 scriptAddr.EncodeAddress(): pkScript,
1007 }), nil); err != nil {
1014 // Pay to PubKey (compressed)
1015 for _, hashType := range hashTypes {
1016 for i := range tx.TxIn {
1017 msg := fmt.Sprintf("%d:%d", hashType, i)
1019 key, err := btcec.NewPrivateKey(btcec.S256())
1021 t.Errorf("failed to make privKey for %s: %v",
1026 pk := (*btcec.PublicKey)(&key.PublicKey).
1027 SerializeCompressed()
1028 address, err := btcutil.NewAddressPubKey(pk,
1029 &chaincfg.TestNet3Params)
1031 t.Errorf("failed to make address for %s: %v",
1036 pkScript, err := PayToAddrScript(address)
1038 t.Errorf("failed to make pkscript "+
1039 "for %s: %v", msg, err)
1042 scriptAddr, err := btcutil.NewAddressScriptHash(
1043 pkScript, &chaincfg.TestNet3Params)
1045 t.Errorf("failed to make p2sh addr for %s: %v",
1050 scriptPkScript, err := PayToAddrScript(scriptAddr)
1052 t.Errorf("failed to make script pkscript for "+
1057 sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
1058 tx, i, scriptPkScript, hashType,
1059 mkGetKey(map[string]addressToKey{
1060 address.EncodeAddress(): {key, true},
1061 }), mkGetScript(map[string][]byte{
1062 scriptAddr.EncodeAddress(): pkScript,
1065 t.Errorf("failed to sign output %s: %v", msg,
1070 // by the above loop, this should be valid, now sign
1072 sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
1073 tx, i, scriptPkScript, hashType,
1074 mkGetKey(map[string]addressToKey{
1075 address.EncodeAddress(): {key, true},
1076 }), mkGetScript(map[string][]byte{
1077 scriptAddr.EncodeAddress(): pkScript,
1080 t.Errorf("failed to sign output %s a "+
1081 "second time: %v", msg, err)
1085 err = checkScripts(msg, tx, i, inputAmounts[i],
1086 sigScript, scriptPkScript)
1088 t.Errorf("twice signed script invalid for "+
1096 for _, hashType := range hashTypes {
1097 for i := range tx.TxIn {
1098 msg := fmt.Sprintf("%d:%d", hashType, i)
1100 key1, err := btcec.NewPrivateKey(btcec.S256())
1102 t.Errorf("failed to make privKey for %s: %v",
1107 pk1 := (*btcec.PublicKey)(&key1.PublicKey).
1108 SerializeCompressed()
1109 address1, err := btcutil.NewAddressPubKey(pk1,
1110 &chaincfg.TestNet3Params)
1112 t.Errorf("failed to make address for %s: %v",
1117 key2, err := btcec.NewPrivateKey(btcec.S256())
1119 t.Errorf("failed to make privKey 2 for %s: %v",
1124 pk2 := (*btcec.PublicKey)(&key2.PublicKey).
1125 SerializeCompressed()
1126 address2, err := btcutil.NewAddressPubKey(pk2,
1127 &chaincfg.TestNet3Params)
1129 t.Errorf("failed to make address 2 for %s: %v",
1134 pkScript, err := MultiSigScript(
1135 []*btcutil.AddressPubKey{address1, address2},
1138 t.Errorf("failed to make pkscript "+
1139 "for %s: %v", msg, err)
1142 scriptAddr, err := btcutil.NewAddressScriptHash(
1143 pkScript, &chaincfg.TestNet3Params)
1145 t.Errorf("failed to make p2sh addr for %s: %v",
1150 scriptPkScript, err := PayToAddrScript(scriptAddr)
1152 t.Errorf("failed to make script pkscript for "+
1157 if err := signAndCheck(msg, tx, i, inputAmounts[i],
1158 scriptPkScript, hashType,
1159 mkGetKey(map[string]addressToKey{
1160 address1.EncodeAddress(): {key1, true},
1161 address2.EncodeAddress(): {key2, true},
1162 }), mkGetScript(map[string][]byte{
1163 scriptAddr.EncodeAddress(): pkScript,
1164 }), nil); err != nil {
1171 // Two part multisig, sign with one key then the other.
1172 for _, hashType := range hashTypes {
1173 for i := range tx.TxIn {
1174 msg := fmt.Sprintf("%d:%d", hashType, i)
1176 key1, err := btcec.NewPrivateKey(btcec.S256())
1178 t.Errorf("failed to make privKey for %s: %v",
1183 pk1 := (*btcec.PublicKey)(&key1.PublicKey).
1184 SerializeCompressed()
1185 address1, err := btcutil.NewAddressPubKey(pk1,
1186 &chaincfg.TestNet3Params)
1188 t.Errorf("failed to make address for %s: %v",
1193 key2, err := btcec.NewPrivateKey(btcec.S256())
1195 t.Errorf("failed to make privKey 2 for %s: %v",
1200 pk2 := (*btcec.PublicKey)(&key2.PublicKey).
1201 SerializeCompressed()
1202 address2, err := btcutil.NewAddressPubKey(pk2,
1203 &chaincfg.TestNet3Params)
1205 t.Errorf("failed to make address 2 for %s: %v",
1210 pkScript, err := MultiSigScript(
1211 []*btcutil.AddressPubKey{address1, address2},
1214 t.Errorf("failed to make pkscript "+
1215 "for %s: %v", msg, err)
1218 scriptAddr, err := btcutil.NewAddressScriptHash(
1219 pkScript, &chaincfg.TestNet3Params)
1221 t.Errorf("failed to make p2sh addr for %s: %v",
1226 scriptPkScript, err := PayToAddrScript(scriptAddr)
1228 t.Errorf("failed to make script pkscript for "+
1233 sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
1234 tx, i, scriptPkScript, hashType,
1235 mkGetKey(map[string]addressToKey{
1236 address1.EncodeAddress(): {key1, true},
1237 }), mkGetScript(map[string][]byte{
1238 scriptAddr.EncodeAddress(): pkScript,
1241 t.Errorf("failed to sign output %s: %v", msg,
1246 // Only 1 out of 2 signed, this *should* fail.
1247 if checkScripts(msg, tx, i, inputAmounts[i], sigScript,
1248 scriptPkScript) == nil {
1249 t.Errorf("part signed script valid for %s", msg)
1253 // Sign with the other key and merge
1254 sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
1255 tx, i, scriptPkScript, hashType,
1256 mkGetKey(map[string]addressToKey{
1257 address2.EncodeAddress(): {key2, true},
1258 }), mkGetScript(map[string][]byte{
1259 scriptAddr.EncodeAddress(): pkScript,
1262 t.Errorf("failed to sign output %s: %v", msg, err)
1266 err = checkScripts(msg, tx, i, inputAmounts[i], sigScript,
1269 t.Errorf("fully signed script invalid for "+
1276 // Two part multisig, sign with one key then both, check key dedup
1278 for _, hashType := range hashTypes {
1279 for i := range tx.TxIn {
1280 msg := fmt.Sprintf("%d:%d", hashType, i)
1282 key1, err := btcec.NewPrivateKey(btcec.S256())
1284 t.Errorf("failed to make privKey for %s: %v",
1289 pk1 := (*btcec.PublicKey)(&key1.PublicKey).
1290 SerializeCompressed()
1291 address1, err := btcutil.NewAddressPubKey(pk1,
1292 &chaincfg.TestNet3Params)
1294 t.Errorf("failed to make address for %s: %v",
1299 key2, err := btcec.NewPrivateKey(btcec.S256())
1301 t.Errorf("failed to make privKey 2 for %s: %v",
1306 pk2 := (*btcec.PublicKey)(&key2.PublicKey).
1307 SerializeCompressed()
1308 address2, err := btcutil.NewAddressPubKey(pk2,
1309 &chaincfg.TestNet3Params)
1311 t.Errorf("failed to make address 2 for %s: %v",
1316 pkScript, err := MultiSigScript(
1317 []*btcutil.AddressPubKey{address1, address2},
1320 t.Errorf("failed to make pkscript "+
1321 "for %s: %v", msg, err)
1324 scriptAddr, err := btcutil.NewAddressScriptHash(
1325 pkScript, &chaincfg.TestNet3Params)
1327 t.Errorf("failed to make p2sh addr for %s: %v",
1332 scriptPkScript, err := PayToAddrScript(scriptAddr)
1334 t.Errorf("failed to make script pkscript for "+
1339 sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
1340 tx, i, scriptPkScript, hashType,
1341 mkGetKey(map[string]addressToKey{
1342 address1.EncodeAddress(): {key1, true},
1343 }), mkGetScript(map[string][]byte{
1344 scriptAddr.EncodeAddress(): pkScript,
1347 t.Errorf("failed to sign output %s: %v", msg,
1352 // Only 1 out of 2 signed, this *should* fail.
1353 if checkScripts(msg, tx, i, inputAmounts[i], sigScript,
1354 scriptPkScript) == nil {
1355 t.Errorf("part signed script valid for %s", msg)
1359 // Sign with the other key and merge
1360 sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
1361 tx, i, scriptPkScript, hashType,
1362 mkGetKey(map[string]addressToKey{
1363 address1.EncodeAddress(): {key1, true},
1364 address2.EncodeAddress(): {key2, true},
1365 }), mkGetScript(map[string][]byte{
1366 scriptAddr.EncodeAddress(): pkScript,
1369 t.Errorf("failed to sign output %s: %v", msg, err)
1373 // Now we should pass.
1374 err = checkScripts(msg, tx, i, inputAmounts[i],
1375 sigScript, scriptPkScript)
1377 t.Errorf("fully signed script invalid for "+
1385 type tstInput struct {
1387 sigscriptGenerates bool
1389 indexOutOfRange bool
1392 type tstSigScript struct {
1395 hashType SigHashType
1397 scriptAtWrongIndex bool
1400 var coinbaseOutPoint = &wire.OutPoint{
1401 Index: (1 << 32) - 1,
1404 // Pregenerated private key, with associated public key and pkScripts
1405 // for the uncompressed and compressed hash160.
1407 privKeyD = []byte{0x6b, 0x0f, 0xd8, 0xda, 0x54, 0x22, 0xd0, 0xb7,
1408 0xb4, 0xfc, 0x4e, 0x55, 0xd4, 0x88, 0x42, 0xb3, 0xa1, 0x65,
1409 0xac, 0x70, 0x7f, 0x3d, 0xa4, 0x39, 0x5e, 0xcb, 0x3b, 0xb0,
1410 0xd6, 0x0e, 0x06, 0x92}
1411 pubkeyX = []byte{0xb2, 0x52, 0xf0, 0x49, 0x85, 0x78, 0x03, 0x03, 0xc8,
1412 0x7d, 0xce, 0x51, 0x7f, 0xa8, 0x69, 0x0b, 0x91, 0x95, 0xf4,
1413 0xf3, 0x5c, 0x26, 0x73, 0x05, 0x05, 0xa2, 0xee, 0xbc, 0x09,
1415 pubkeyY = []byte{0xb7, 0xc6, 0x7d, 0xb2, 0xe1, 0xff, 0xc8, 0x43, 0x1f,
1416 0x63, 0x32, 0x62, 0xaa, 0x60, 0xc6, 0x83, 0x30, 0xbd, 0x24,
1417 0x7e, 0xef, 0xdb, 0x6f, 0x2e, 0x8d, 0x56, 0xf0, 0x3c, 0x9f,
1419 uncompressedPkScript = []byte{0x76, 0xa9, 0x14, 0xd1, 0x7c, 0xb5,
1420 0xeb, 0xa4, 0x02, 0xcb, 0x68, 0xe0, 0x69, 0x56, 0xbf, 0x32,
1421 0x53, 0x90, 0x0e, 0x0a, 0x86, 0xc9, 0xfa, 0x88, 0xac}
1422 compressedPkScript = []byte{0x76, 0xa9, 0x14, 0x27, 0x4d, 0x9f, 0x7f,
1423 0x61, 0x7e, 0x7c, 0x7a, 0x1c, 0x1f, 0xb2, 0x75, 0x79, 0x10,
1424 0x43, 0x65, 0x68, 0x27, 0x9d, 0x86, 0x88, 0xac}
1425 shortPkScript = []byte{0x76, 0xa9, 0x14, 0xd1, 0x7c, 0xb5,
1426 0xeb, 0xa4, 0x02, 0xcb, 0x68, 0xe0, 0x69, 0x56, 0xbf, 0x32,
1427 0x53, 0x90, 0x0e, 0x0a, 0x88, 0xac}
1428 uncompressedAddrStr = "1L6fd93zGmtzkK6CsZFVVoCwzZV3MUtJ4F"
1429 compressedAddrStr = "14apLppt9zTq6cNw8SDfiJhk9PhkZrQtYZ"
1432 // Pretend output amounts.
1433 const coinbaseVal = 2500000000
1436 var sigScriptTests = []tstSigScript{
1438 name: "one input uncompressed",
1441 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1442 sigscriptGenerates: true,
1443 inputValidates: true,
1444 indexOutOfRange: false,
1447 hashType: SigHashAll,
1449 scriptAtWrongIndex: false,
1452 name: "two inputs uncompressed",
1455 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1456 sigscriptGenerates: true,
1457 inputValidates: true,
1458 indexOutOfRange: false,
1461 txout: wire.NewTxOut(coinbaseVal+fee, uncompressedPkScript),
1462 sigscriptGenerates: true,
1463 inputValidates: true,
1464 indexOutOfRange: false,
1467 hashType: SigHashAll,
1469 scriptAtWrongIndex: false,
1472 name: "one input compressed",
1475 txout: wire.NewTxOut(coinbaseVal, compressedPkScript),
1476 sigscriptGenerates: true,
1477 inputValidates: true,
1478 indexOutOfRange: false,
1481 hashType: SigHashAll,
1483 scriptAtWrongIndex: false,
1486 name: "two inputs compressed",
1489 txout: wire.NewTxOut(coinbaseVal, compressedPkScript),
1490 sigscriptGenerates: true,
1491 inputValidates: true,
1492 indexOutOfRange: false,
1495 txout: wire.NewTxOut(coinbaseVal+fee, compressedPkScript),
1496 sigscriptGenerates: true,
1497 inputValidates: true,
1498 indexOutOfRange: false,
1501 hashType: SigHashAll,
1503 scriptAtWrongIndex: false,
1506 name: "hashType SigHashNone",
1509 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1510 sigscriptGenerates: true,
1511 inputValidates: true,
1512 indexOutOfRange: false,
1515 hashType: SigHashNone,
1517 scriptAtWrongIndex: false,
1520 name: "hashType SigHashSingle",
1523 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1524 sigscriptGenerates: true,
1525 inputValidates: true,
1526 indexOutOfRange: false,
1529 hashType: SigHashSingle,
1531 scriptAtWrongIndex: false,
1534 name: "hashType SigHashAnyoneCanPay",
1537 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1538 sigscriptGenerates: true,
1539 inputValidates: true,
1540 indexOutOfRange: false,
1543 hashType: SigHashAnyOneCanPay,
1545 scriptAtWrongIndex: false,
1548 name: "hashType non-standard",
1551 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1552 sigscriptGenerates: true,
1553 inputValidates: true,
1554 indexOutOfRange: false,
1559 scriptAtWrongIndex: false,
1562 name: "invalid compression",
1565 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1566 sigscriptGenerates: true,
1567 inputValidates: false,
1568 indexOutOfRange: false,
1571 hashType: SigHashAll,
1573 scriptAtWrongIndex: false,
1576 name: "short PkScript",
1579 txout: wire.NewTxOut(coinbaseVal, shortPkScript),
1580 sigscriptGenerates: false,
1581 indexOutOfRange: false,
1584 hashType: SigHashAll,
1586 scriptAtWrongIndex: false,
1589 name: "valid script at wrong index",
1592 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1593 sigscriptGenerates: true,
1594 inputValidates: true,
1595 indexOutOfRange: false,
1598 txout: wire.NewTxOut(coinbaseVal+fee, uncompressedPkScript),
1599 sigscriptGenerates: true,
1600 inputValidates: true,
1601 indexOutOfRange: false,
1604 hashType: SigHashAll,
1606 scriptAtWrongIndex: true,
1609 name: "index out of range",
1612 txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
1613 sigscriptGenerates: true,
1614 inputValidates: true,
1615 indexOutOfRange: false,
1618 txout: wire.NewTxOut(coinbaseVal+fee, uncompressedPkScript),
1619 sigscriptGenerates: true,
1620 inputValidates: true,
1621 indexOutOfRange: false,
1624 hashType: SigHashAll,
1626 scriptAtWrongIndex: true,
1630 // Test the sigscript generation for valid and invalid inputs, all
1631 // hashTypes, and with and without compression. This test creates
1632 // sigscripts to spend fake coinbase inputs, as sigscripts cannot be
1633 // created for the MsgTxs in txTests, since they come from the blockchain
1634 // and we don't have the private keys.
1635 func TestSignatureScript(t *testing.T) {
1638 privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), privKeyD)
1641 for i := range sigScriptTests {
1642 tx := wire.NewMsgTx(wire.TxVersion)
1644 output := wire.NewTxOut(500, []byte{OP_RETURN})
1647 for range sigScriptTests[i].inputs {
1648 txin := wire.NewTxIn(coinbaseOutPoint, nil, nil)
1654 for j := range tx.TxIn {
1656 if sigScriptTests[i].inputs[j].indexOutOfRange {
1657 t.Errorf("at test %v", sigScriptTests[i].name)
1658 idx = len(sigScriptTests[i].inputs)
1662 script, err = SignatureScript(tx, idx,
1663 sigScriptTests[i].inputs[j].txout.PkScript,
1664 sigScriptTests[i].hashType, privKey,
1665 sigScriptTests[i].compress)
1667 if (err == nil) != sigScriptTests[i].inputs[j].sigscriptGenerates {
1669 t.Errorf("passed test '%v' incorrectly",
1670 sigScriptTests[i].name)
1672 t.Errorf("failed test '%v': %v",
1673 sigScriptTests[i].name, err)
1677 if !sigScriptTests[i].inputs[j].sigscriptGenerates {
1678 // done with this test
1682 tx.TxIn[j].SignatureScript = script
1685 // If testing using a correct sigscript but for an incorrect
1686 // index, use last input script for first input. Requires > 0
1688 if sigScriptTests[i].scriptAtWrongIndex {
1689 tx.TxIn[0].SignatureScript = script
1690 sigScriptTests[i].inputs[0].inputValidates = false
1693 // Validate tx input scripts
1694 scriptFlags := ScriptBip16 | ScriptVerifyDERSignatures
1695 for j := range tx.TxIn {
1696 vm, err := NewEngine(sigScriptTests[i].
1697 inputs[j].txout.PkScript, tx, j, scriptFlags, nil, nil, 0)
1699 t.Errorf("cannot create script vm for test %v: %v",
1700 sigScriptTests[i].name, err)
1704 if (err == nil) != sigScriptTests[i].inputs[j].inputValidates {
1706 t.Errorf("passed test '%v' validation incorrectly: %v",
1707 sigScriptTests[i].name, err)
1709 t.Errorf("failed test '%v' validation: %v",
1710 sigScriptTests[i].name, err)