func (pi *PInput) serialize(w io.Writer) error {
	if !pi.IsSane() {
		return psbt.ErrInvalidPsbtFormat
	}
	if pi.NonWitnessUtxo != nil {
		buf, err := pi.NonWitnessUtxo.Serialize()
		if err != nil {
			return err
		}
		err = serializeKVPairWithType(w, uint8(psbt.NonWitnessUtxoType), nil, buf)
		if err != nil {
			return err
		}
	}
	if pi.WitnessUtxo != nil {
		buf, err := writeTxOut(pi.WitnessUtxo)
		if err != nil {
			return err
		}
		err = serializeKVPairWithType(w, uint8(psbt.WitnessUtxoType), nil, buf)
		if err != nil {
			return err
		}
	}
	if pi.FinalScriptSig == nil && pi.FinalScriptWitness == nil {
		sort.Sort(psbt.PartialSigSorter(pi.PartialSigs))
		for _, ps := range pi.PartialSigs {
			err := serializeKVPairWithType(
				w,
				uint8(psbt.PartialSigType), ps.PubKey,
				ps.Signature,
			)
			if err != nil {
				return err
			}
		}
		if pi.SighashType != 0 {
			var shtBytes [4]byte
			binary.LittleEndian.PutUint32(
				shtBytes[:], uint32(pi.SighashType),
			)
			err := serializeKVPairWithType(
				w, uint8(psbt.SighashType), nil, shtBytes[:],
			)
			if err != nil {
				return err
			}
		}
		if pi.RedeemScript != nil {
			err := serializeKVPairWithType(
				w, uint8(psbt.RedeemScriptInputType), nil,
				pi.RedeemScript,
			)
			if err != nil {
				return err
			}
		}
		if pi.WitnessScript != nil {
			err := serializeKVPairWithType(
				w, uint8(psbt.WitnessScriptInputType), nil,
				pi.WitnessScript,
			)
			if err != nil {
				return err
			}
		}
		sort.Sort(psbt.Bip32Sorter(pi.Bip32Derivation))
		for _, kd := range pi.Bip32Derivation {
			err := serializeKVPairWithType(
				w,
				uint8(psbt.Bip32DerivationInputType), kd.PubKey,
				psbt.SerializeBIP32Derivation(
					kd.MasterKeyFingerprint, kd.Bip32Path,
				),
			)
			if err != nil {
				return err
			}
		}
	}
	if pi.FinalScriptSig != nil {
		err := serializeKVPairWithType(
			w, uint8(psbt.FinalScriptSigType), nil, pi.FinalScriptSig,
		)
		if err != nil {
			return err
		}
	}
	if pi.FinalScriptWitness != nil {
		err := serializeKVPairWithType(
			w, uint8(psbt.FinalScriptWitnessType), nil, pi.FinalScriptWitness,
		)
		if err != nil {
			return err
		}
	}
	for _, kv := range pi.Unknowns {
		err := serializeKVpair(w, kv.Key, kv.Value)
		if err != nil {
			return err
		}
	}
	return nil
}
serialize attempts to serialize the target PInput into the passed io.Writer.
package pset
import (
	"bytes"
	"encoding/binary"
	"io"
	"sort"
	"github.com/btcsuite/btcd/txscript"
	"github.com/btcsuite/btcd/wire"
	"github.com/btcsuite/btcutil/psbt"
	"github.com/vulpemventures/go-elements/transaction"
)
type PInput struct {
	NonWitnessUtxo     *transaction.Transaction
	WitnessUtxo        *transaction.TxOutput
	PartialSigs        []*psbt.PartialSig
	SighashType        txscript.SigHashType
	RedeemScript       []byte
	WitnessScript      []byte
	Bip32Derivation    []*psbt.Bip32Derivation
	FinalScriptSig     []byte
	FinalScriptWitness []byte
	Unknowns           []*Unknown
}
func NewPsetInput(nonWitnessUtxo *transaction.Transaction,
	witnessUtxo *transaction.TxOutput) *PInput {
	return &PInput{
		NonWitnessUtxo:     nonWitnessUtxo,
		WitnessUtxo:        witnessUtxo,
		PartialSigs:        []*psbt.PartialSig{},
		SighashType:        0,
		RedeemScript:       nil,
		WitnessScript:      nil,
		Bip32Derivation:    []*psbt.Bip32Derivation{},
		FinalScriptSig:     nil,
		FinalScriptWitness: nil,
		Unknowns:           nil,
	}
}
func (pi *PInput) IsSane() bool {
	if pi.NonWitnessUtxo != nil && pi.WitnessUtxo != nil {
		return false
	}
	if pi.WitnessUtxo == nil && pi.WitnessScript != nil {
		return false
	}
	if pi.WitnessUtxo == nil && pi.FinalScriptWitness != nil {
		return false
	}
	return true
}
func (pi *PInput) deserialize(r io.Reader) error {
	for {
		keyint, keydata, err := getKey(r)
		if err != nil {
			return err
		}
		if keyint == -1 {
			break
		}
		value, err := wire.ReadVarBytes(
			r, 0, psbt.MaxPsbtValueLength, "PSET value",
		)
		if err != nil {
			return err
		}
		switch psbt.InputType(keyint) {
		case psbt.NonWitnessUtxoType:
			if pi.NonWitnessUtxo != nil {
				return psbt.ErrDuplicateKey
			}
			if keydata != nil {
				return psbt.ErrInvalidKeydata
			}
			tx, err := transaction.NewTxFromBuffer(bytes.NewBuffer(value))
			if err != nil {
				return err
			}
			pi.NonWitnessUtxo = tx
		case psbt.WitnessUtxoType:
			if pi.WitnessUtxo != nil {
				return psbt.ErrDuplicateKey
			}
			if keydata != nil {
				return psbt.ErrInvalidKeydata
			}
			txout, err := readTxOut(value)
			if err != nil {
				return err
			}
			pi.WitnessUtxo = txout
		case psbt.PartialSigType:
			newPartialSig := psbt.PartialSig{
				PubKey:    keydata,
				Signature: value,
			}
			if !checkValid(newPartialSig) {
				return psbt.ErrInvalidPsbtFormat
			}
			for _, x := range pi.PartialSigs {
				if bytes.Equal(x.PubKey, newPartialSig.PubKey) {
					return psbt.ErrDuplicateKey
				}
			}
			pi.PartialSigs = append(pi.PartialSigs, &newPartialSig)
		case psbt.SighashType:
			if pi.SighashType != 0 {
				return psbt.ErrDuplicateKey
			}
			if keydata != nil {
				return psbt.ErrInvalidKeydata
			}
			if len(value) != 4 {
				return psbt.ErrInvalidKeydata
			}
			shtype := txscript.SigHashType(
				binary.LittleEndian.Uint32(value),
			)
			pi.SighashType = shtype
		case psbt.RedeemScriptInputType:
			if pi.RedeemScript != nil {
				return psbt.ErrDuplicateKey
			}
			if keydata != nil {
				return psbt.ErrInvalidKeydata
			}
			pi.RedeemScript = value
		case psbt.WitnessScriptInputType:
			if pi.WitnessScript != nil {
				return psbt.ErrDuplicateKey
			}
			if keydata != nil {
				return psbt.ErrInvalidKeydata
			}
			pi.WitnessScript = value
		case psbt.Bip32DerivationInputType:
			if !validatePubkey(keydata) {
				return psbt.ErrInvalidPsbtFormat
			}
			master, derivationPath, err := readBip32Derivation(value)
			if err != nil {
				return err
			}
			for _, x := range pi.Bip32Derivation {
				if bytes.Equal(x.PubKey, keydata) {
					return psbt.ErrDuplicateKey
				}
			}
			pi.Bip32Derivation = append(
				pi.Bip32Derivation,
				&psbt.Bip32Derivation{
					PubKey:               keydata,
					MasterKeyFingerprint: master,
					Bip32Path:            derivationPath,
				},
			)
		case psbt.FinalScriptSigType:
			if pi.FinalScriptSig != nil {
				return psbt.ErrDuplicateKey
			}
			if keydata != nil {
				return psbt.ErrInvalidKeydata
			}
			pi.FinalScriptSig = value
		case psbt.FinalScriptWitnessType:
			if pi.FinalScriptWitness != nil {
				return psbt.ErrDuplicateKey
			}
			if keydata != nil {
				return psbt.ErrInvalidKeydata
			}
			pi.FinalScriptWitness = value
		default:
			keyintanddata := []byte{byte(keyint)}
			keyintanddata = append(keyintanddata, keydata...)
			newUnknown := &Unknown{
				Key:   keyintanddata,
				Value: value,
			}
			for _, x := range pi.Unknowns {
				if bytes.Equal(x.Key, newUnknown.Key) &&
					bytes.Equal(x.Value, newUnknown.Value) {
					return psbt.ErrDuplicateKey
				}
			}
			pi.Unknowns = append(pi.Unknowns, newUnknown)
		}
	}
	return nil
}