1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741 |
- // Copyright (c) 2013-2016 The btcsuite developers
- // Use of this source code is governed by an ISC
- // license that can be found in the LICENSE file.
- package txscript
- import (
- "bytes"
- "fmt"
- "testing"
- "github.com/pkt-cash/pktd/btcec"
- "github.com/pkt-cash/pktd/btcutil"
- "github.com/pkt-cash/pktd/btcutil/er"
- "github.com/pkt-cash/pktd/chaincfg"
- "github.com/pkt-cash/pktd/chaincfg/chainhash"
- "github.com/pkt-cash/pktd/txscript/opcode"
- "github.com/pkt-cash/pktd/txscript/params"
- "github.com/pkt-cash/pktd/wire"
- "github.com/pkt-cash/pktd/wire/constants"
- )
- type addressToKey struct {
- key *btcec.PrivateKey
- compressed bool
- }
- func mkGetKey(keys map[string]addressToKey) KeyDB {
- if keys == nil {
- return KeyClosure(func(addr btcutil.Address) (*btcec.PrivateKey,
- bool, er.R) {
- return nil, false, er.New("nope")
- })
- }
- return KeyClosure(func(addr btcutil.Address) (*btcec.PrivateKey,
- bool, er.R) {
- a2k, ok := keys[addr.EncodeAddress()]
- if !ok {
- return nil, false, er.New("nope")
- }
- return a2k.key, a2k.compressed, nil
- })
- }
- func mkGetScript(scripts map[string][]byte) ScriptDB {
- if scripts == nil {
- return ScriptClosure(func(addr btcutil.Address) ([]byte, er.R) {
- return nil, er.New("nope")
- })
- }
- return ScriptClosure(func(addr btcutil.Address) ([]byte, er.R) {
- script, ok := scripts[addr.EncodeAddress()]
- if !ok {
- return nil, er.New("nope")
- }
- return script, nil
- })
- }
- func checkScripts(msg string, tx *wire.MsgTx, idx int, inputAmt int64, sigScript, pkScript []byte) er.R {
- tx.TxIn[idx].SignatureScript = sigScript
- vm, err := NewEngine(pkScript, tx, idx,
- ScriptBip16|ScriptVerifyDERSignatures, nil, nil, inputAmt)
- if err != nil {
- return er.Errorf("failed to make script engine for %s: %v",
- msg, err)
- }
- err = vm.Execute()
- if err != nil {
- return er.Errorf("invalid script signature for %s: %v", msg,
- err)
- }
- return nil
- }
- func signAndCheck(msg string, tx *wire.MsgTx, idx int, inputAmt int64, pkScript []byte,
- hashType params.SigHashType, kdb KeyDB, sdb ScriptDB,
- previousScript []byte) er.R {
- sigScript, err := SignTxOutput(&chaincfg.TestNet3Params, tx, idx,
- pkScript, hashType, kdb, sdb, nil)
- if err != nil {
- return er.Errorf("failed to sign output %s: %v", msg, err)
- }
- return checkScripts(msg, tx, idx, inputAmt, sigScript, pkScript)
- }
- func TestSignTxOutput(t *testing.T) {
- // make key
- // make script based on key.
- // sign with magic pixie dust.
- hashTypes := []params.SigHashType{
- params.SigHashOld, // no longer used but should act like all
- params.SigHashAll,
- params.SigHashNone,
- params.SigHashSingle,
- params.SigHashAll | params.SigHashAnyOneCanPay,
- params.SigHashNone | params.SigHashAnyOneCanPay,
- params.SigHashSingle | params.SigHashAnyOneCanPay,
- }
- inputAmounts := []int64{5, 10, 15}
- tx := &wire.MsgTx{
- Version: 1,
- TxIn: []*wire.TxIn{
- {
- PreviousOutPoint: wire.OutPoint{
- Hash: chainhash.Hash{},
- Index: 0,
- },
- Sequence: 4294967295,
- },
- {
- PreviousOutPoint: wire.OutPoint{
- Hash: chainhash.Hash{},
- Index: 1,
- },
- Sequence: 4294967295,
- },
- {
- PreviousOutPoint: wire.OutPoint{
- Hash: chainhash.Hash{},
- Index: 2,
- },
- Sequence: 4294967295,
- },
- },
- TxOut: []*wire.TxOut{
- {
- Value: 1,
- },
- {
- Value: 2,
- },
- {
- Value: 3,
- },
- },
- LockTime: 0,
- }
- // Pay to Pubkey Hash (uncompressed)
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk := (*btcec.PublicKey)(&key.PublicKey).
- SerializeUncompressed()
- address, err := btcutil.NewAddressPubKeyHash(
- btcutil.Hash160(pk), &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- pkScript, err := PayToAddrScript(address)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- if err := signAndCheck(msg, tx, i, inputAmounts[i], pkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, false},
- }), mkGetScript(nil), nil); err != nil {
- t.Error(err)
- break
- }
- }
- }
- // Pay to Pubkey Hash (uncompressed) (merging with correct)
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk := (*btcec.PublicKey)(&key.PublicKey).
- SerializeUncompressed()
- address, err := btcutil.NewAddressPubKeyHash(
- btcutil.Hash160(pk), &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- pkScript, err := PayToAddrScript(address)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, pkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, false},
- }), mkGetScript(nil), nil)
- if err != nil {
- t.Errorf("failed to sign output %s: %v", msg,
- err)
- break
- }
- // by the above loop, this should be valid, now sign
- // again and merge.
- sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, pkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, false},
- }), mkGetScript(nil), sigScript)
- if err != nil {
- t.Errorf("failed to sign output %s a "+
- "second time: %v", msg, err)
- break
- }
- err = checkScripts(msg, tx, i, inputAmounts[i], sigScript, pkScript)
- if err != nil {
- t.Errorf("twice signed script invalid for "+
- "%s: %v", msg, err)
- break
- }
- }
- }
- // Pay to Pubkey Hash (compressed)
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk := (*btcec.PublicKey)(&key.PublicKey).
- SerializeCompressed()
- address, err := btcutil.NewAddressPubKeyHash(
- btcutil.Hash160(pk), &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- pkScript, err := PayToAddrScript(address)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- if err := signAndCheck(msg, tx, i, inputAmounts[i],
- pkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, true},
- }), mkGetScript(nil), nil); err != nil {
- t.Error(err)
- break
- }
- }
- }
- // Pay to Pubkey Hash (compressed) with duplicate merge
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk := (*btcec.PublicKey)(&key.PublicKey).
- SerializeCompressed()
- address, err := btcutil.NewAddressPubKeyHash(
- btcutil.Hash160(pk), &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- pkScript, err := PayToAddrScript(address)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, pkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, true},
- }), mkGetScript(nil), nil)
- if err != nil {
- t.Errorf("failed to sign output %s: %v", msg,
- err)
- break
- }
- // by the above loop, this should be valid, now sign
- // again and merge.
- sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, pkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, true},
- }), mkGetScript(nil), sigScript)
- if err != nil {
- t.Errorf("failed to sign output %s a "+
- "second time: %v", msg, err)
- break
- }
- err = checkScripts(msg, tx, i, inputAmounts[i],
- sigScript, pkScript)
- if err != nil {
- t.Errorf("twice signed script invalid for "+
- "%s: %v", msg, err)
- break
- }
- }
- }
- // Pay to PubKey (uncompressed)
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk := (*btcec.PublicKey)(&key.PublicKey).
- SerializeUncompressed()
- address, err := btcutil.NewAddressPubKey(pk,
- &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- pkScript, err := PayToAddrScript(address)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- if err := signAndCheck(msg, tx, i, inputAmounts[i],
- pkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, false},
- }), mkGetScript(nil), nil); err != nil {
- t.Error(err)
- break
- }
- }
- }
- // Pay to PubKey (uncompressed)
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk := (*btcec.PublicKey)(&key.PublicKey).
- SerializeUncompressed()
- address, err := btcutil.NewAddressPubKey(pk,
- &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- pkScript, err := PayToAddrScript(address)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, pkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, false},
- }), mkGetScript(nil), nil)
- if err != nil {
- t.Errorf("failed to sign output %s: %v", msg,
- err)
- break
- }
- // by the above loop, this should be valid, now sign
- // again and merge.
- sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, pkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, false},
- }), mkGetScript(nil), sigScript)
- if err != nil {
- t.Errorf("failed to sign output %s a "+
- "second time: %v", msg, err)
- break
- }
- err = checkScripts(msg, tx, i, inputAmounts[i], sigScript, pkScript)
- if err != nil {
- t.Errorf("twice signed script invalid for "+
- "%s: %v", msg, err)
- break
- }
- }
- }
- // Pay to PubKey (compressed)
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk := (*btcec.PublicKey)(&key.PublicKey).
- SerializeCompressed()
- address, err := btcutil.NewAddressPubKey(pk,
- &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- pkScript, err := PayToAddrScript(address)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- if err := signAndCheck(msg, tx, i, inputAmounts[i],
- pkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, true},
- }), mkGetScript(nil), nil); err != nil {
- t.Error(err)
- break
- }
- }
- }
- // Pay to PubKey (compressed) with duplicate merge
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk := (*btcec.PublicKey)(&key.PublicKey).
- SerializeCompressed()
- address, err := btcutil.NewAddressPubKey(pk,
- &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- pkScript, err := PayToAddrScript(address)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, pkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, true},
- }), mkGetScript(nil), nil)
- if err != nil {
- t.Errorf("failed to sign output %s: %v", msg,
- err)
- break
- }
- // by the above loop, this should be valid, now sign
- // again and merge.
- sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, pkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, true},
- }), mkGetScript(nil), sigScript)
- if err != nil {
- t.Errorf("failed to sign output %s a "+
- "second time: %v", msg, err)
- break
- }
- err = checkScripts(msg, tx, i, inputAmounts[i],
- sigScript, pkScript)
- if err != nil {
- t.Errorf("twice signed script invalid for "+
- "%s: %v", msg, err)
- break
- }
- }
- }
- // As before, but with p2sh now.
- // Pay to Pubkey Hash (uncompressed)
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk := (*btcec.PublicKey)(&key.PublicKey).
- SerializeUncompressed()
- address, err := btcutil.NewAddressPubKeyHash(
- btcutil.Hash160(pk), &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- pkScript, err := PayToAddrScript(address)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- break
- }
- scriptAddr, err := btcutil.NewAddressScriptHash(
- pkScript, &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make p2sh addr for %s: %v",
- msg, err)
- break
- }
- scriptPkScript, err := PayToAddrScript(
- scriptAddr)
- if err != nil {
- t.Errorf("failed to make script pkscript for "+
- "%s: %v", msg, err)
- break
- }
- if err := signAndCheck(msg, tx, i, inputAmounts[i],
- scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, false},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), nil); err != nil {
- t.Error(err)
- break
- }
- }
- }
- // Pay to Pubkey Hash (uncompressed) with duplicate merge
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk := (*btcec.PublicKey)(&key.PublicKey).
- SerializeUncompressed()
- address, err := btcutil.NewAddressPubKeyHash(
- btcutil.Hash160(pk), &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- pkScript, err := PayToAddrScript(address)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- break
- }
- scriptAddr, err := btcutil.NewAddressScriptHash(
- pkScript, &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make p2sh addr for %s: %v",
- msg, err)
- break
- }
- scriptPkScript, err := PayToAddrScript(
- scriptAddr)
- if err != nil {
- t.Errorf("failed to make script pkscript for "+
- "%s: %v", msg, err)
- break
- }
- sigScript0, err := SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, false},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), nil)
- if err != nil {
- t.Errorf("failed to sign output %s: %v", msg,
- err)
- break
- }
- // by the above loop, this should be valid, now sign
- // again and merge.
- sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, false},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), nil)
- if err != nil {
- t.Errorf("failed to sign output %s a "+
- "second time: %v", msg, err)
- break
- }
- if !bytes.Equal(sigScript0, sigScript) {
- t.Errorf("sigscripts did not match after signing twice")
- break
- }
- err = checkScripts(msg, tx, i, inputAmounts[i],
- sigScript, scriptPkScript)
- if err != nil {
- t.Errorf("twice signed script invalid for "+
- "%s: %v", msg, err)
- break
- }
- }
- }
- // Pay to Pubkey Hash (compressed)
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk := (*btcec.PublicKey)(&key.PublicKey).
- SerializeCompressed()
- address, err := btcutil.NewAddressPubKeyHash(
- btcutil.Hash160(pk), &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- pkScript, err := PayToAddrScript(address)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- scriptAddr, err := btcutil.NewAddressScriptHash(
- pkScript, &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make p2sh addr for %s: %v",
- msg, err)
- break
- }
- scriptPkScript, err := PayToAddrScript(
- scriptAddr)
- if err != nil {
- t.Errorf("failed to make script pkscript for "+
- "%s: %v", msg, err)
- break
- }
- if err := signAndCheck(msg, tx, i, inputAmounts[i],
- scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, true},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), nil); err != nil {
- t.Error(err)
- break
- }
- }
- }
- // Pay to Pubkey Hash (compressed) with duplicate merge
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk := (*btcec.PublicKey)(&key.PublicKey).
- SerializeCompressed()
- address, err := btcutil.NewAddressPubKeyHash(
- btcutil.Hash160(pk), &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- pkScript, err := PayToAddrScript(address)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- scriptAddr, err := btcutil.NewAddressScriptHash(
- pkScript, &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make p2sh addr for %s: %v",
- msg, err)
- break
- }
- scriptPkScript, err := PayToAddrScript(
- scriptAddr)
- if err != nil {
- t.Errorf("failed to make script pkscript for "+
- "%s: %v", msg, err)
- break
- }
- sigScript0, err := SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, true},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), nil)
- if err != nil {
- t.Errorf("failed to sign output %s: %v", msg,
- err)
- break
- }
- // by the above loop, this should be valid, now sign
- // again and merge.
- sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, true},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), nil)
- if err != nil {
- t.Errorf("failed to sign output %s a "+
- "second time: %v", msg, err)
- break
- }
- if !bytes.Equal(sigScript0, sigScript) {
- t.Errorf("sigscripts did not match after signing twice")
- break
- }
- err = checkScripts(msg, tx, i, inputAmounts[i],
- sigScript, scriptPkScript)
- if err != nil {
- t.Errorf("twice signed script invalid for "+
- "%s: %v", msg, err)
- break
- }
- }
- }
- // Pay to PubKey (uncompressed)
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk := (*btcec.PublicKey)(&key.PublicKey).
- SerializeUncompressed()
- address, err := btcutil.NewAddressPubKey(pk,
- &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- pkScript, err := PayToAddrScript(address)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- scriptAddr, err := btcutil.NewAddressScriptHash(
- pkScript, &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make p2sh addr for %s: %v",
- msg, err)
- break
- }
- scriptPkScript, err := PayToAddrScript(
- scriptAddr)
- if err != nil {
- t.Errorf("failed to make script pkscript for "+
- "%s: %v", msg, err)
- break
- }
- if err := signAndCheck(msg, tx, i, inputAmounts[i],
- scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, false},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), nil); err != nil {
- t.Error(err)
- break
- }
- }
- }
- // Pay to PubKey (uncompressed) with duplicate merge
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk := (*btcec.PublicKey)(&key.PublicKey).
- SerializeUncompressed()
- address, err := btcutil.NewAddressPubKey(pk,
- &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- pkScript, err := PayToAddrScript(address)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- scriptAddr, err := btcutil.NewAddressScriptHash(
- pkScript, &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make p2sh addr for %s: %v",
- msg, err)
- break
- }
- scriptPkScript, err := PayToAddrScript(scriptAddr)
- if err != nil {
- t.Errorf("failed to make script pkscript for "+
- "%s: %v", msg, err)
- break
- }
- sigScript0, err := SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, false},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), nil)
- if err != nil {
- t.Errorf("failed to sign output %s: %v", msg,
- err)
- break
- }
- // by the above loop, this should be valid, now sign
- // again and merge.
- sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, false},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), nil)
- if err != nil {
- t.Errorf("failed to sign output %s a "+
- "second time: %v", msg, err)
- break
- }
- if !bytes.Equal(sigScript0, sigScript) {
- t.Errorf("sigscripts did not match after signing twice")
- break
- }
- err = checkScripts(msg, tx, i, inputAmounts[i],
- sigScript, scriptPkScript)
- if err != nil {
- t.Errorf("twice signed script invalid for "+
- "%s: %v", msg, err)
- break
- }
- }
- }
- // Pay to PubKey (compressed)
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk := (*btcec.PublicKey)(&key.PublicKey).
- SerializeCompressed()
- address, err := btcutil.NewAddressPubKey(pk,
- &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- pkScript, err := PayToAddrScript(address)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- scriptAddr, err := btcutil.NewAddressScriptHash(
- pkScript, &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make p2sh addr for %s: %v",
- msg, err)
- break
- }
- scriptPkScript, err := PayToAddrScript(scriptAddr)
- if err != nil {
- t.Errorf("failed to make script pkscript for "+
- "%s: %v", msg, err)
- break
- }
- if err := signAndCheck(msg, tx, i, inputAmounts[i],
- scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, true},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), nil); err != nil {
- t.Error(err)
- break
- }
- }
- }
- // Pay to PubKey (compressed)
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk := (*btcec.PublicKey)(&key.PublicKey).
- SerializeCompressed()
- address, err := btcutil.NewAddressPubKey(pk,
- &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- pkScript, err := PayToAddrScript(address)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- scriptAddr, err := btcutil.NewAddressScriptHash(
- pkScript, &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make p2sh addr for %s: %v",
- msg, err)
- break
- }
- scriptPkScript, err := PayToAddrScript(scriptAddr)
- if err != nil {
- t.Errorf("failed to make script pkscript for "+
- "%s: %v", msg, err)
- break
- }
- _, err = SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, true},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), nil)
- if err != nil {
- t.Errorf("failed to sign output %s: %v", msg,
- err)
- break
- }
- // by the above loop, this should be valid, now sign
- // again and merge.
- sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address.EncodeAddress(): {key, true},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), nil)
- if err != nil {
- t.Errorf("failed to sign output %s a "+
- "second time: %v", msg, err)
- break
- }
- err = checkScripts(msg, tx, i, inputAmounts[i],
- sigScript, scriptPkScript)
- if err != nil {
- t.Errorf("twice signed script invalid for "+
- "%s: %v", msg, err)
- break
- }
- }
- }
- // Basic Multisig
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key1, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk1 := (*btcec.PublicKey)(&key1.PublicKey).
- SerializeCompressed()
- address1, err := btcutil.NewAddressPubKey(pk1,
- &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- key2, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey 2 for %s: %v",
- msg, err)
- break
- }
- pk2 := (*btcec.PublicKey)(&key2.PublicKey).
- SerializeCompressed()
- address2, err := btcutil.NewAddressPubKey(pk2,
- &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address 2 for %s: %v",
- msg, err)
- break
- }
- pkScript, err := MultiSigScript(
- []*btcutil.AddressPubKey{address1, address2},
- 2)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- scriptAddr, err := btcutil.NewAddressScriptHash(
- pkScript, &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make p2sh addr for %s: %v",
- msg, err)
- break
- }
- scriptPkScript, err := PayToAddrScript(scriptAddr)
- if err != nil {
- t.Errorf("failed to make script pkscript for "+
- "%s: %v", msg, err)
- break
- }
- if err := signAndCheck(msg, tx, i, inputAmounts[i],
- scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address1.EncodeAddress(): {key1, true},
- address2.EncodeAddress(): {key2, true},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), nil); err != nil {
- t.Error(err)
- break
- }
- }
- }
- // Two part multisig, sign with one key then the other.
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key1, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk1 := (*btcec.PublicKey)(&key1.PublicKey).
- SerializeCompressed()
- address1, err := btcutil.NewAddressPubKey(pk1,
- &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- key2, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey 2 for %s: %v",
- msg, err)
- break
- }
- pk2 := (*btcec.PublicKey)(&key2.PublicKey).
- SerializeCompressed()
- address2, err := btcutil.NewAddressPubKey(pk2,
- &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address 2 for %s: %v",
- msg, err)
- break
- }
- pkScript, err := MultiSigScript(
- []*btcutil.AddressPubKey{address1, address2},
- 2)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- scriptAddr, err := btcutil.NewAddressScriptHash(
- pkScript, &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make p2sh addr for %s: %v",
- msg, err)
- break
- }
- scriptPkScript, err := PayToAddrScript(scriptAddr)
- if err != nil {
- t.Errorf("failed to make script pkscript for "+
- "%s: %v", msg, err)
- break
- }
- sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address1.EncodeAddress(): {key1, true},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), nil)
- if err != nil {
- t.Errorf("failed to sign output %s: %v", msg,
- err)
- break
- }
- // Only 1 out of 2 signed, this *should* fail.
- if checkScripts(msg, tx, i, inputAmounts[i], sigScript,
- scriptPkScript) == nil {
- t.Errorf("part signed script valid for %s", msg)
- break
- }
- // Sign with the other key and merge
- sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address2.EncodeAddress(): {key2, true},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), sigScript)
- if err != nil {
- t.Errorf("failed to sign output %s: %v", msg, err)
- break
- }
- err = checkScripts(msg, tx, i, inputAmounts[i], sigScript,
- scriptPkScript)
- if err != nil {
- t.Errorf("fully signed script invalid for "+
- "%s: %v", msg, err)
- break
- }
- }
- }
- // Two part multisig, sign with one key then both, check key dedup
- // correctly.
- for _, hashType := range hashTypes {
- for i := range tx.TxIn {
- msg := fmt.Sprintf("%d:%d", hashType, i)
- key1, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey for %s: %v",
- msg, err)
- break
- }
- pk1 := (*btcec.PublicKey)(&key1.PublicKey).
- SerializeCompressed()
- address1, err := btcutil.NewAddressPubKey(pk1,
- &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address for %s: %v",
- msg, err)
- break
- }
- key2, err := btcec.NewPrivateKey(btcec.S256())
- if err != nil {
- t.Errorf("failed to make privKey 2 for %s: %v",
- msg, err)
- break
- }
- pk2 := (*btcec.PublicKey)(&key2.PublicKey).
- SerializeCompressed()
- address2, err := btcutil.NewAddressPubKey(pk2,
- &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make address 2 for %s: %v",
- msg, err)
- break
- }
- pkScript, err := MultiSigScript(
- []*btcutil.AddressPubKey{address1, address2},
- 2)
- if err != nil {
- t.Errorf("failed to make pkscript "+
- "for %s: %v", msg, err)
- }
- scriptAddr, err := btcutil.NewAddressScriptHash(
- pkScript, &chaincfg.TestNet3Params)
- if err != nil {
- t.Errorf("failed to make p2sh addr for %s: %v",
- msg, err)
- break
- }
- scriptPkScript, err := PayToAddrScript(scriptAddr)
- if err != nil {
- t.Errorf("failed to make script pkscript for "+
- "%s: %v", msg, err)
- break
- }
- sigScript, err := SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address1.EncodeAddress(): {key1, true},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), nil)
- if err != nil {
- t.Errorf("failed to sign output %s: %v", msg,
- err)
- break
- }
- // Only 1 out of 2 signed, this *should* fail.
- if checkScripts(msg, tx, i, inputAmounts[i], sigScript,
- scriptPkScript) == nil {
- t.Errorf("part signed script valid for %s", msg)
- break
- }
- // Sign with the other key and merge
- sigScript, err = SignTxOutput(&chaincfg.TestNet3Params,
- tx, i, scriptPkScript, hashType,
- mkGetKey(map[string]addressToKey{
- address1.EncodeAddress(): {key1, true},
- address2.EncodeAddress(): {key2, true},
- }), mkGetScript(map[string][]byte{
- scriptAddr.EncodeAddress(): pkScript,
- }), sigScript)
- if err != nil {
- t.Errorf("failed to sign output %s: %v", msg, err)
- break
- }
- // Now we should pass.
- err = checkScripts(msg, tx, i, inputAmounts[i],
- sigScript, scriptPkScript)
- if err != nil {
- t.Errorf("fully signed script invalid for "+
- "%s: %v", msg, err)
- break
- }
- }
- }
- }
- type tstInput struct {
- txout *wire.TxOut
- sigscriptGenerates bool
- inputValidates bool
- indexOutOfRange bool
- }
- type tstSigScript struct {
- name string
- inputs []tstInput
- hashType params.SigHashType
- compress bool
- scriptAtWrongIndex bool
- }
- var coinbaseOutPoint = &wire.OutPoint{
- Index: (1 << 32) - 1,
- }
- // Pregenerated private key, with associated public key and pkScripts
- // for the uncompressed and compressed hash160.
- var (
- privKeyD = []byte{
- 0x6b, 0x0f, 0xd8, 0xda, 0x54, 0x22, 0xd0, 0xb7,
- 0xb4, 0xfc, 0x4e, 0x55, 0xd4, 0x88, 0x42, 0xb3, 0xa1, 0x65,
- 0xac, 0x70, 0x7f, 0x3d, 0xa4, 0x39, 0x5e, 0xcb, 0x3b, 0xb0,
- 0xd6, 0x0e, 0x06, 0x92,
- }
- // pubkeyX = []byte{0xb2, 0x52, 0xf0, 0x49, 0x85, 0x78, 0x03, 0x03, 0xc8,
- // 0x7d, 0xce, 0x51, 0x7f, 0xa8, 0x69, 0x0b, 0x91, 0x95, 0xf4,
- // 0xf3, 0x5c, 0x26, 0x73, 0x05, 0x05, 0xa2, 0xee, 0xbc, 0x09,
- // 0x38, 0x34, 0x3a}
- // pubkeyY = []byte{0xb7, 0xc6, 0x7d, 0xb2, 0xe1, 0xff, 0xc8, 0x43, 0x1f,
- // 0x63, 0x32, 0x62, 0xaa, 0x60, 0xc6, 0x83, 0x30, 0xbd, 0x24,
- // 0x7e, 0xef, 0xdb, 0x6f, 0x2e, 0x8d, 0x56, 0xf0, 0x3c, 0x9f,
- // 0x6d, 0xb6, 0xf8}
- uncompressedPkScript = []byte{
- 0x76, 0xa9, 0x14, 0xd1, 0x7c, 0xb5,
- 0xeb, 0xa4, 0x02, 0xcb, 0x68, 0xe0, 0x69, 0x56, 0xbf, 0x32,
- 0x53, 0x90, 0x0e, 0x0a, 0x86, 0xc9, 0xfa, 0x88, 0xac,
- }
- compressedPkScript = []byte{
- 0x76, 0xa9, 0x14, 0x27, 0x4d, 0x9f, 0x7f,
- 0x61, 0x7e, 0x7c, 0x7a, 0x1c, 0x1f, 0xb2, 0x75, 0x79, 0x10,
- 0x43, 0x65, 0x68, 0x27, 0x9d, 0x86, 0x88, 0xac,
- }
- shortPkScript = []byte{
- 0x76, 0xa9, 0x14, 0xd1, 0x7c, 0xb5,
- 0xeb, 0xa4, 0x02, 0xcb, 0x68, 0xe0, 0x69, 0x56, 0xbf, 0x32,
- 0x53, 0x90, 0x0e, 0x0a, 0x88, 0xac,
- }
- // uncompressedAddrStr = "1L6fd93zGmtzkK6CsZFVVoCwzZV3MUtJ4F"
- // compressedAddrStr = "14apLppt9zTq6cNw8SDfiJhk9PhkZrQtYZ"
- )
- // Pretend output amounts.
- const (
- coinbaseVal = 2500000000
- fee = 5000000
- )
- var sigScriptTests = []tstSigScript{
- {
- name: "one input uncompressed",
- inputs: []tstInput{
- {
- txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
- sigscriptGenerates: true,
- inputValidates: true,
- indexOutOfRange: false,
- },
- },
- hashType: params.SigHashAll,
- compress: false,
- scriptAtWrongIndex: false,
- },
- {
- name: "two inputs uncompressed",
- inputs: []tstInput{
- {
- txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
- sigscriptGenerates: true,
- inputValidates: true,
- indexOutOfRange: false,
- },
- {
- txout: wire.NewTxOut(coinbaseVal+fee, uncompressedPkScript),
- sigscriptGenerates: true,
- inputValidates: true,
- indexOutOfRange: false,
- },
- },
- hashType: params.SigHashAll,
- compress: false,
- scriptAtWrongIndex: false,
- },
- {
- name: "one input compressed",
- inputs: []tstInput{
- {
- txout: wire.NewTxOut(coinbaseVal, compressedPkScript),
- sigscriptGenerates: true,
- inputValidates: true,
- indexOutOfRange: false,
- },
- },
- hashType: params.SigHashAll,
- compress: true,
- scriptAtWrongIndex: false,
- },
- {
- name: "two inputs compressed",
- inputs: []tstInput{
- {
- txout: wire.NewTxOut(coinbaseVal, compressedPkScript),
- sigscriptGenerates: true,
- inputValidates: true,
- indexOutOfRange: false,
- },
- {
- txout: wire.NewTxOut(coinbaseVal+fee, compressedPkScript),
- sigscriptGenerates: true,
- inputValidates: true,
- indexOutOfRange: false,
- },
- },
- hashType: params.SigHashAll,
- compress: true,
- scriptAtWrongIndex: false,
- },
- {
- name: "hashType SigHashNone",
- inputs: []tstInput{
- {
- txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
- sigscriptGenerates: true,
- inputValidates: true,
- indexOutOfRange: false,
- },
- },
- hashType: params.SigHashNone,
- compress: false,
- scriptAtWrongIndex: false,
- },
- {
- name: "hashType SigHashSingle",
- inputs: []tstInput{
- {
- txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
- sigscriptGenerates: true,
- inputValidates: true,
- indexOutOfRange: false,
- },
- },
- hashType: params.SigHashSingle,
- compress: false,
- scriptAtWrongIndex: false,
- },
- {
- name: "hashType SigHashAnyoneCanPay",
- inputs: []tstInput{
- {
- txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
- sigscriptGenerates: true,
- inputValidates: true,
- indexOutOfRange: false,
- },
- },
- hashType: params.SigHashAnyOneCanPay,
- compress: false,
- scriptAtWrongIndex: false,
- },
- {
- name: "hashType non-standard",
- inputs: []tstInput{
- {
- txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
- sigscriptGenerates: true,
- inputValidates: true,
- indexOutOfRange: false,
- },
- },
- hashType: 0x04,
- compress: false,
- scriptAtWrongIndex: false,
- },
- {
- name: "invalid compression",
- inputs: []tstInput{
- {
- txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
- sigscriptGenerates: true,
- inputValidates: false,
- indexOutOfRange: false,
- },
- },
- hashType: params.SigHashAll,
- compress: true,
- scriptAtWrongIndex: false,
- },
- {
- name: "short PkScript",
- inputs: []tstInput{
- {
- txout: wire.NewTxOut(coinbaseVal, shortPkScript),
- sigscriptGenerates: false,
- indexOutOfRange: false,
- },
- },
- hashType: params.SigHashAll,
- compress: false,
- scriptAtWrongIndex: false,
- },
- {
- name: "valid script at wrong index",
- inputs: []tstInput{
- {
- txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
- sigscriptGenerates: true,
- inputValidates: true,
- indexOutOfRange: false,
- },
- {
- txout: wire.NewTxOut(coinbaseVal+fee, uncompressedPkScript),
- sigscriptGenerates: true,
- inputValidates: true,
- indexOutOfRange: false,
- },
- },
- hashType: params.SigHashAll,
- compress: false,
- scriptAtWrongIndex: true,
- },
- {
- name: "index out of range",
- inputs: []tstInput{
- {
- txout: wire.NewTxOut(coinbaseVal, uncompressedPkScript),
- sigscriptGenerates: true,
- inputValidates: true,
- indexOutOfRange: false,
- },
- {
- txout: wire.NewTxOut(coinbaseVal+fee, uncompressedPkScript),
- sigscriptGenerates: true,
- inputValidates: true,
- indexOutOfRange: false,
- },
- },
- hashType: params.SigHashAll,
- compress: false,
- scriptAtWrongIndex: true,
- },
- }
- // Test the sigscript generation for valid and invalid inputs, all
- // hashTypes, and with and without compression. This test creates
- // sigscripts to spend fake coinbase inputs, as sigscripts cannot be
- // created for the MsgTxs in txTests, since they come from the blockchain
- // and we don't have the private keys.
- func TestSignatureScript(t *testing.T) {
- privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), privKeyD)
- nexttest:
- for i := range sigScriptTests {
- tx := wire.NewMsgTx(constants.TxVersion)
- output := wire.NewTxOut(500, []byte{opcode.OP_RETURN})
- tx.AddTxOut(output)
- for range sigScriptTests[i].inputs {
- txin := wire.NewTxIn(coinbaseOutPoint, nil, nil)
- tx.AddTxIn(txin)
- }
- var script []byte
- var err er.R
- for j := range tx.TxIn {
- var idx int
- if sigScriptTests[i].inputs[j].indexOutOfRange {
- t.Errorf("at test %v", sigScriptTests[i].name)
- idx = len(sigScriptTests[i].inputs)
- } else {
- idx = j
- }
- script, err = SignatureScript(tx, idx,
- sigScriptTests[i].inputs[j].txout.PkScript,
- sigScriptTests[i].hashType, privKey,
- sigScriptTests[i].compress)
- if (err == nil) != sigScriptTests[i].inputs[j].sigscriptGenerates {
- if err == nil {
- t.Errorf("passed test '%v' incorrectly",
- sigScriptTests[i].name)
- } else {
- t.Errorf("failed test '%v': %v",
- sigScriptTests[i].name, err)
- }
- continue nexttest
- }
- if !sigScriptTests[i].inputs[j].sigscriptGenerates {
- // done with this test
- continue nexttest
- }
- tx.TxIn[j].SignatureScript = script
- }
- // If testing using a correct sigscript but for an incorrect
- // index, use last input script for first input. Requires > 0
- // inputs for test.
- if sigScriptTests[i].scriptAtWrongIndex {
- tx.TxIn[0].SignatureScript = script
- sigScriptTests[i].inputs[0].inputValidates = false
- }
- // Validate tx input scripts
- scriptFlags := ScriptBip16 | ScriptVerifyDERSignatures
- for j := range tx.TxIn {
- vm, err := NewEngine(sigScriptTests[i].
- inputs[j].txout.PkScript, tx, j, scriptFlags, nil, nil, 0)
- if err != nil {
- t.Errorf("cannot create script vm for test %v: %v",
- sigScriptTests[i].name, err)
- continue nexttest
- }
- err = vm.Execute()
- if (err == nil) != sigScriptTests[i].inputs[j].inputValidates {
- if err == nil {
- t.Errorf("passed test '%v' validation incorrectly: %v",
- sigScriptTests[i].name, err)
- } else {
- t.Errorf("failed test '%v' validation: %v",
- sigScriptTests[i].name, err)
- }
- continue nexttest
- }
- }
- }
- }
|