Closed cevin closed 1 year ago
You used NewAddressWitnessPubKeyHash
for p2pkh.
You used
NewAddressWitnessPubKeyHash
for p2pkh.
o great, thanks.
fromAmount0, _ := btcutil.NewAmount(0.0001277)
hash0, _ := btcutil.NewAddressPubKeyHash(btcutil.Hash160(p2pkhWif.PrivKey.PubKey().SerializeCompressed()), params)
pkScript0, _ := txscript.PayToAddrScript(hash0)
broadcast successfully .
So, As long as a complete Bitcoin transaction contains any Input that is a SegWit transaction, the entire transaction must be signed, right?
For example, if there is an additional transaction that is MultiSig, you need to use NewAddressScriptHash to get pkScript and add it to prevOutFetcher, right?
How about the amount
,Does it have to be exactly the same as the original Input? For example, I just set it to 0 and tried to broadcast got an error .... CHECK (---) SIG Failed
You can use NewAddressScriptHash
or NewAddressWitnessPubKeyHash
for MultiSig, also need to add utxo into prevOutFetcher
.
amount
must match value in previous output.
I have two address mmc2XbDrsjzZucyKFMhwhbJEx6rBjzGfgG and tb1qj04gu6e0s8msp7ekht7d5j27dwclcd5gj07505. and use the same Input TxId
befdba0132ede2df465971536b633cc9310d4f43063902d38727308018c72013
(testnet)I generated a signed transaction like this
020000000001021320c71880302787d3023906434f0d31c93c636b53715946dfe2ed3201bafdbe000000004847304402201e7d5cb7f3c42331cb2931e1e8431bcfa395f3196c10ba53f56685cb56a8a9fe022038efd450b5bff617254e91e6334be771d5556d06e258466d6ddb8effac26d2b101000000001320c71880302787d3023906434f0d31c93c636b53715946dfe2ed3201bafdbe01000000000000000001947a0000000000001976a91442c65e4d88b6b42ce9a2ec40fff18f4502cdf69e88ac0002483045022100c4c1e06c75df147a092b0e6c87c6f8f368efa4a2caa88c4b04b0d0655edd02a202206593e30c9bc174874c0b97f78ff8406d8d2e8d3dd72989b52117749f2f383cf601210371fe7d505de8708257f3e50ee842fa3588888a4d11029c4cb3e6e446dda99a2b00000000
.broadcast it got error:
Script failed an OP_EQUALVERIFY operation
Code
```golang package main import ( "bytes" "encoding/hex" "fmt" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" ) func main() { params := &chaincfg.TestNet3Params txid := "befdba0132ede2df465971536b633cc9310d4f43063902d38727308018c72013" txHash, _ := chainhash.NewHashFromStr(txid) target := "mmc2XbDrsjzZucyKFMhwhbJEx6rBjzGfgG" toAddress, _ := btcutil.DecodeAddress(target, params) toAddressPkScript, _ := txscript.PayToAddrScript(toAddress) segwitWifStr := "cN8rp7Y......" segwitWif, _ := btcutil.DecodeWIF(segwitWifStr) p2pkhWifStr := "cTpiiQr2........" p2pkhWif, _ := btcutil.DecodeWIF(p2pkhWifStr) tx := wire.NewMsgTx(2) // input of to mmc2... tx.AddTxIn(&wire.TxIn{ PreviousOutPoint: wire.OutPoint{ Hash: *txHash, Index: 0, }, }) // input of to tb1.... (segwit) tx.AddTxIn(&wire.TxIn{ PreviousOutPoint: wire.OutPoint{ Hash: *txHash, Index: 1, }, }) //0.0001872 // new txout toAmount, _ := btcutil.NewAmount(0.0003138) tx.AddTxOut(wire.NewTxOut(int64(toAmount), toAddressPkScript)) // get signHashes // p2pkh fromAmount0, _ := btcutil.NewAmount(0.0001277) hash0, _ := btcutil.NewAddressWitnessPubKeyHash(btcutil.Hash160(p2pkhWif.PrivKey.PubKey().SerializeCompressed()), params) pkScript0, _ := txscript.PayToAddrScript(hash0) // native segwit fromAmount1, _ := btcutil.NewAmount(0.0001872) hash1, _ := btcutil.NewAddressWitnessPubKeyHash(btcutil.Hash160(segwitWif.PrivKey.PubKey().SerializeCompressed()), params) pkScript1, _ := txscript.PayToAddrScript(hash1) signHashes := txscript.NewTxSigHashes(tx, txscript.NewMultiPrevOutFetcher(map[wire.OutPoint]*wire.TxOut{ tx.TxIn[0].PreviousOutPoint: { Value: int64(fromAmount0), PkScript: pkScript0, }, tx.TxIn[1].PreviousOutPoint: { Value: int64(fromAmount1), PkScript: pkScript1, }, })) // sign txin addressPubKey, _ := btcutil.NewAddressPubKey(p2pkhWif.PrivKey.PubKey().SerializeCompressed(), params) p2pkhPkScript, _ := txscript.PayToAddrScript(addressPubKey) sign0, _ := txscript.SignTxOutput( params, tx, 0, p2pkhPkScript, txscript.SigHashAll, txscript.KeyClosure(func(address btcutil.Address) (*btcec.PrivateKey, bool, error) { return p2pkhWif.PrivKey, true, nil }), nil, tx.TxIn[0].SignatureScript, ) tx.TxIn[0].SignatureScript = sign0 sign1, _ := txscript.WitnessSignature(tx, signHashes, 1, int64(fromAmount1), pkScript1, txscript.SigHashAll, segwitWif.PrivKey, true) tx.TxIn[1].Witness = sign1 var out bytes.Buffer tx.Serialize(&out) fmt.Println(hex.EncodeToString(out.Bytes())) } ```