Bitcoin Core - Erreur RPC de transaction PSBT : bad-txns-inputs-missingorspent
Je souhaite créer une transaction PSBT. Mais obtenez l’erreur quand appeler la méthode sendrawtransaction.
J'ai utilisé le package Golang : github.com/btcsuite/btcd
Voici mon code : entrées PSBT
Sorties PSBT
Ensuite, je les ai transmis à la fonction.
func GenerateSignedOwnerTx(ins []*TxInput, sorties []*TxOutput, réseau *chaincfg.Params) (chaîne, erreur) { entrées var []*wire.OutPoint var nSéquences []uint32 prevOuts := make(carte[wire.OutPoint]*wire.TxOut) pour _, in := range ins { var prevOut *wire.OutPoint txHash, err := chainhash.NewHashFromStr(in.TxId) if err ! = nil { panic(err) } prevOut = wire.NewOutPoint( txHash, in.VOut) inputs = append(inputs, prevOut) prevPkScript, err := AddrToPkScript(in.Address, network) if err ! = nil { panic(err) } WitnessUtxo := wire.NewTxOut(in.Amount, prevPkScript ) sorties précédentes[*prevOut] = WitnessUtxo nSequences = append(nSequences, wire.MaxTxInSequenceNum) } var sorties []*wire.TxOut pour _, out := range outs { pkScript, err := AddrToPkScript(out.Address, network) if err ! = nil { panic(err) } outputs = append(outputs, wire.NewTxOut(out.Amount, pkScript)) } bp, err := psbt.New(inputs, outputs, int32(2), uint32(0), nSequences) if err ! = nil { panic(err) } updater, err := psbt.NewUpdater( bp) if err ! = nil { panic(err) } prevOutputFetcher := txscript.NewMultiPrevOutFetcher(prevOuts) for i, in := range ins { if err = signInput(updater, i, in, prevOutputFetcher, txscript.SigHashAll, réseau) ; err ! = nil { panic(err) } if err = psbt.Finalize(bp, i); err ! = nil { panic(err) } } fmt.Println("signed bp base64 encode:") fmt.Println(bp.B64Encode()) if err = psbt.MaybeFinalizeAll(bp); err ! = nil { return "", err } acheteurSignedTx, err := psbt.Extract(bp) if err ! = nil { return "", err } var buf bytes.Buffer if err := acheteurSignedTx.Serialize(&buf); err ! = nil { return "", err } return hex.EncodeToString(buf.Bytes()), nil}
C'est la fonction de signe.
func signInput (updater *psbt.Updater, i int, dans *TxInput, prevOutFetcher *txscript.MultiPrevOutFetcher, hashType txscript.SigHashType, réseau *chaincfg.Params) erreur { wif, err := btcutil.DecodeWIF(in.PrivateKey) si erreur ! = nil && i ! = 1 { panic(err) } privKey := wif.PrivKey prevPkScript, err := AddrToPkScript(in.Address, network) if err ! = nil { panic(err) } if txscript.IsPayToPubKeyHash(prevPkScript ) { prevTx := wire.NewMsgTx(2) txBytes, err := hex.DecodeString(in.NonWitnessUtxo) if err ! = nil { panic(err) } if err = prevTx.Deserialize(bytes.NewReader(txBytes)); err ! = nil { panic(err) } if err = updater.AddInNonWitnessUtxo(prevTx, i); err ! = nil { panic(err) } } else { témoinUtxo := wire.NewTxOut(in.Amount, prevPkScript) if err = updater.AddInWitnessUtxo(witnessUtxo, i); err ! = nil { panic(err) } } if err = updater.AddInSighashType(hashType, i); err ! = nil { panic(err) } if txscript.IsPayToTaproot(prevPkScript) { internalPubKey := schnorr.SerializePubKey(privKey.PubKey()) updater.Upsbt.Inputs.TaprootInternalKey = internalPubKey sigHashes := txscript.NewTxSigHashes(updater.Upsbt.UnsignedTx, prevOutFetcher) if hashType == txscript.SigHashAll { hashType = txscript.SigHashDefault } témoin, err := txscript.TaprootWitnessSignature(updater.Upsbt.UnsignedTx, sig Des hachages, i, in.Amount, prevPkScript, hashType, privKey) if err ! = nil { panic(err) } updater.Upsbt.Inputs.TaprootKeySpendSig = témoin
} sinon if txscript.IsPayToPubKeyHash(prevPkScript) { signature, err := txscript.RawTxInSignature(updater.Upsbt.UnsignedTx, i, prevPkScript, hashType, privKey) if err ! = nil { panic(err) } if _, err := updater.Sign(i, signature, privKey.PubKey().SerializeCompressed(), nul, nul); err ! = nil { panic(err) } } else { pubKeyBytes := privKey.PubKey().SerializeCompressed() sigHashes := txscript.NewTxSigHashes(updater.Upsbt.UnsignedTx, prevOutFetcher) script, err := PayToPubKeyHashScript(btcutil.Hash160 (pubKeyBytes)) if err ! = nil { panic(err) } signature, err := txscript.RawTxInWitnessSignature(updater.Upsbt.UnsignedTx, sigHashes, i, in.Amount, script, hashType, privKey) if err ! = nil { panic(err) } if txscript.IsPayToScriptHash(prevPkScript) {racheScript, err := PayToWitnessPubKeyHashScript(btcutil.Hash160(pubKeyBytes)) if err ! = nil { panic(err) } err = updater.AddInRedeemScript(redeemScript, i) if err ! = nil { panic(err) } } if _, err := updater.Sign(i, signature, pubKeyBytes, nil, nil); err ! = nil { panic(err) } } return nul
}
