diff --git a/sighash143/sighash143.go b/sighash143/sighash143.go index 2fa27f2f..62eb45c8 100644 --- a/sighash143/sighash143.go +++ b/sighash143/sighash143.go @@ -11,6 +11,7 @@ import ( "math" "strings" + "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/uspv" @@ -22,6 +23,8 @@ const ( inspk1 = "00141d0f172a0ecb48aee1be1f2687d2963ae33f71a1" inamt1 = int64(600000000) + + xpecthash = "c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670" ) // calcWitnessSignatureHash is the witnessified version of calcSignatureHash @@ -97,7 +100,7 @@ func calcWitnessSignatureHash( binary.LittleEndian.PutUint32(buf4[:], uint32(hashType)) pre = append(pre, buf4[:]...) - fmt.Printf("pre: %x\n", pre) + fmt.Printf("calcWitnessSignatureHash pre: %x\n", pre) hsh := wire.DoubleSha256SH(pre) return hsh.Bytes() } @@ -119,7 +122,7 @@ func calcHashPrevOuts(tx *wire.MsgTx, hType txscript.SigHashType) wire.ShaHash { binary.LittleEndian.PutUint32(buf[:], in.PreviousOutPoint.Index) pre = append(pre, buf[:]...) } - fmt.Printf("pre: %x\n", pre) + fmt.Printf("calcHashPrevOuts pre: %x\n", pre) return wire.DoubleSha256SH(pre) } @@ -138,7 +141,7 @@ func calcHashSequence(tx *wire.MsgTx, hType txscript.SigHashType) wire.ShaHash { binary.LittleEndian.PutUint32(buf[:], in.Sequence) pre = append(pre, buf[:]...) } - fmt.Printf("pre: %x\n", pre) + fmt.Printf("calcHashSequence pre: %x\n", pre) return wire.DoubleSha256SH(pre) } @@ -163,7 +166,7 @@ func calcHashOutputs( writeTxOut(&buf, 0, 0, out) pre = append(pre, buf.Bytes()...) } - fmt.Printf("pre: %x\n", pre) + fmt.Printf("calcHashOutputs pre: %x\n", pre) return wire.DoubleSha256SH(pre) } @@ -179,6 +182,10 @@ func main() { if err != nil { log.Fatal(err) } + xpkt, err := hex.DecodeString(string(xpecthash)) + if err != nil { + log.Fatal(err) + } // load tx skeleton from local file fmt.Printf("loading tx from file tx.hex\n") @@ -207,9 +214,19 @@ func main() { fmt.Printf(uspv.TxToString(ttx)) + priv, err := btcec.NewPrivateKey(btcec.S256()) + if err != nil { + log.Fatal(err) + } + + sig, err := txscript.WitnessScript(ttx, 1, inamt1, in1spk, + txscript.SigHashAll, priv, true) + + fmt.Printf("got sig %x\n", sig) hxh := calcWitnessSignatureHash(txscript.SigHashAll, ttx, 1, inamt1) fmt.Printf("got sigHash %x\n", hxh) + fmt.Printf("expect hash %x\n ", xpkt) } // pver can be 0, doesn't do anything in these. Same for msg.Version diff --git a/uspv/sortsignsend.go b/uspv/sortsignsend.go index 0061f9e7..c6aa3ebf 100644 --- a/uspv/sortsignsend.go +++ b/uspv/sortsignsend.go @@ -167,6 +167,8 @@ func (s *SPVCon) SendCoins(adr btcutil.Address, sendAmt int64) error { // if wit utxo, convert address to generate pkscript if in.IsWit { + // adding a witness input, so set the tx as witness tx + tx.Flags = 0x01 wa, err := btcutil.NewAddressWitnessPubKeyHash( s.TS.Adrs[in.KeyIdx].PkhAdr.ScriptAddress(), s.TS.Param) prevPKs, err = txscript.PayToAddrScript(wa) @@ -187,6 +189,7 @@ func (s *SPVCon) SendCoins(adr btcutil.Address, sendAmt int64) error { // tx is ready for signing, sigStash := make([][]byte, len(ins)) + witStash := make([][][]byte, len(ins)) for i, txin := range tx.TxIn { // pick key child, err := s.TS.rootPrivKey.Child( @@ -202,7 +205,7 @@ func (s *SPVCon) SendCoins(adr btcutil.Address, sendAmt int64) error { // This is where witness based sighash types need to happen // sign into stash if ins[i].IsWit { - sigStash[i], err = txscript.WitnessSignatureScript( + witStash[i], err = txscript.WitnessScript( tx, i, ins[i].Value, txin.SignatureScript, txscript.SigHashAll, priv, true) if err != nil { @@ -219,7 +222,14 @@ func (s *SPVCon) SendCoins(adr btcutil.Address, sendAmt int64) error { } // swap sigs into sigScripts in txins for i, txin := range tx.TxIn { - txin.SignatureScript = sigStash[i] + if sigStash[i] != nil { + txin.SignatureScript = sigStash[i] + } + if witStash[i] != nil { + txin.Witness = witStash[i] + txin.SignatureScript = nil + } + } fmt.Printf("tx: %s", TxToString(tx))