psbt

package
v0.0.0-...-35764ec Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 8, 2022 License: ISC Imports: 11 Imported by: 21

Documentation

Overview

Package psbt is an implementation of Partially Signed Brocoin Transactions (PSBT). The format is defined in BIP 174: https://github.com/brocoin/bips/blob/master/bip-0174.mediawiki

Index

Constants

View Source
const (
	// SignSuccesful indicates that the partial signature was successfully
	// attached.
	SignSuccesful = 0

	// SignFinalized  indicates that this input is already finalized, so the provided
	// signature was *not* attached
	SignFinalized = 1

	// SignInvalid indicates that the provided signature data was not valid. In this case
	// an error will also be returned.
	SignInvalid = -1
)
View Source
const MaxPsbtValueLength = 4000000

MaxPsbtValueLength is the size of the largest transaction serialization that could be passed in a NonWitnessUtxo field. This is definitely less than 4M.

View Source
const MinTxVersion = 1

MinTxVersion is the lowest transaction version that we'll permit.

Variables

View Source
var (

	// ErrInvalidPsbtFormat is a generic error for any situation in which a
	// provided Psbt serialization does not conform to the rules of BIP174.
	ErrInvalidPsbtFormat = errors.New("Invalid PSBT serialization format")

	// ErrDuplicateKey indicates that a passed Psbt serialization is invalid
	// due to having the same key repeated in the same key-value pair.
	ErrDuplicateKey = errors.New("Invalid Psbt due to duplicate key")

	// ErrInvalidKeydata indicates that a key-value pair in the PSBT
	// serialization contains data in the key which is not valid.
	ErrInvalidKeydata = errors.New("Invalid key data")

	// ErrInvalidMagicBytes indicates that a passed Psbt serialization is invalid
	// due to having incorrect magic bytes.
	ErrInvalidMagicBytes = errors.New("Invalid Psbt due to incorrect magic bytes")

	// ErrInvalidRawTxSigned indicates that the raw serialized transaction in the
	// global section of the passed Psbt serialization is invalid because it
	// contains scriptSigs/witnesses (i.e. is fully or partially signed), which
	// is not allowed by BIP174.
	ErrInvalidRawTxSigned = errors.New("Invalid Psbt, raw transaction must " +
		"be unsigned.")

	// ErrInvalidPrevOutNonWitnessTransaction indicates that the transaction
	// hash (i.e. SHA256^2) of the fully serialized previous transaction
	// provided in the NonWitnessUtxo key-value field doesn't match the prevout
	// hash in the UnsignedTx field in the PSBT itself.
	ErrInvalidPrevOutNonWitnessTransaction = errors.New("Prevout hash does " +
		"not match the provided non-witness utxo serialization")

	// ErrInvalidSignatureForInput indicates that the signature the user is
	// trying to append to the PSBT is invalid, either because it does
	// not correspond to the previous transaction hash, or redeem script,
	// or witness script.
	// NOTE this does not include ECDSA signature checking.
	ErrInvalidSignatureForInput = errors.New("Signature does not correspond " +
		"to this input")

	// ErrInputAlreadyFinalized indicates that the PSBT passed to a Finalizer
	// already contains the finalized scriptSig or witness.
	ErrInputAlreadyFinalized = errors.New("Cannot finalize PSBT, finalized " +
		"scriptSig or scriptWitnes already exists")

	// ErrIncompletePSBT indicates that the Extractor object
	// was unable to successfully extract the passed Psbt struct because
	// it is not complete
	ErrIncompletePSBT = errors.New("PSBT cannot be extracted as it is " +
		"incomplete")

	// ErrNotFinalizable indicates that the PSBT struct does not have
	// sufficient data (e.g. signatures) for finalization
	ErrNotFinalizable = errors.New("PSBT is not finalizable")

	// ErrInvalidSigHashFlags indicates that a signature added to the PSBT
	// uses Sighash flags that are not in accordance with the requirement
	// according to the entry in PsbtInSighashType, or otherwise not the
	// default value (SIGHASH_ALL)
	ErrInvalidSigHashFlags = errors.New("Invalid Sighash Flags")

	// ErrUnsupportedScriptType indicates that the redeem script or
	// scriptwitness given is not supported by this codebase, or is otherwise
	// not valid.
	ErrUnsupportedScriptType = errors.New("Unsupported script type")
)

Functions

func Extract

func Extract(p *Packet) (*wire.MsgTx, error)

Extract takes a finalized psbt.Packet and outputs a finalized transaction instance. Note that if the PSBT is in-complete, then an error ErrIncompletePSBT will be returned. As the extracted transaction has been fully finalized, it will be ready for network broadcast once returned.

func Finalize

func Finalize(p *Packet, inIndex int) error

Finalize assumes that the provided psbt.Packet struct has all partial signatures and redeem scripts/witness scripts already prepared for the specified input, and so removes all temporary data and replaces them with completed sigScript and witness fields, which are stored in key-types 07 and 08. The witness/non-witness utxo fields in the inputs (key-types 00 and 01) are left intact as they may be needed for validation (?). If there is any invalid or incomplete data, an error is returned.

func MaybeFinalize

func MaybeFinalize(p *Packet, inIndex int) (bool, error)

MaybeFinalize attempts to finalize the input at index inIndex in the PSBT p, returning true with no error if it succeeds, OR if the input has already been finalized.

func MaybeFinalizeAll

func MaybeFinalizeAll(p *Packet) error

MaybeFinalizeAll attempts to finalize all inputs of the psbt.Packet that are not already finalized, and returns an error if it fails to do so.

func SerializeBIP32Derivation

func SerializeBIP32Derivation(masterKeyFingerprint uint32,
	bip32Path []uint32) []byte

SerializeBIP32Derivation takes a master key fingerprint as defined in BIP32, along with a path specified as a list of uint32 values, and returns a bytestring specifying the derivation in the format required by BIP174: // master key fingerprint (4) || child index (4) || child index (4) || ....

Types

type Bip32Derivation

type Bip32Derivation struct {
	// PubKey is the raw pubkey serialized in compressed format.
	PubKey []byte

	// MasterKeyFingerprint is the finger print of the master pubkey.
	MasterKeyFingerprint uint32

	// Bip32Path is the BIP 32 path with child index as a distinct integer.
	Bip32Path []uint32
}

Bip32Derivation encapsulates the data for the input and output Bip32Derivation key-value fields.

TODO(roasbeef): use hdkeychain here instead?

type Bip32Sorter

type Bip32Sorter []*Bip32Derivation

Bip32Sorter implements sort.Interface for the Bip32Derivation struct.

func (Bip32Sorter) Len

func (s Bip32Sorter) Len() int

func (Bip32Sorter) Less

func (s Bip32Sorter) Less(i, j int) bool

func (Bip32Sorter) Swap

func (s Bip32Sorter) Swap(i, j int)

type GlobalType

type GlobalType uint8

GlobalType is the set of types that are used at the global scope level within the PSBT.

const (
	// UnsignedTxType is the global scope key that houses the unsigned
	// transaction of the PSBT. The value is a transaction in network
	// serialization. The scriptSigs and witnesses for each input must be
	// empty. The transaction must be in the old serialization format
	// (without witnesses). A PSBT must have a transaction, otherwise it is
	// invalid.
	UnsignedTxType GlobalType = 0

	// XpubType houses a global xpub for the entire PSBT packet.
	//
	// The key ({0x01}|{xpub}) is he 78 byte serialized extended public key
	// as defined by BIP 32.  Extended public keys are those that can be
	// used to derive public keys used in the inputs and outputs of this
	// transaction. It should be the public key at the highest hardened
	// derivation index so that
	// the unhardened child keys used in the transaction can be derived.
	//
	// The value is the master key fingerprint as defined by BIP 32
	// concatenated with the derivation path of the public key. The
	// derivation path is represented as 32-bit little endian unsigned
	// integer indexes concatenated with each other. The number of 32 bit
	// unsigned integer indexes must match the depth provided in the
	// extended public key.
	XpubType GlobalType = 1

	// VersionType houses the global version number of this PSBT. There is
	// no key (only contains the byte type), then the value if omitted, is
	// assumed to be zero.
	VersionType GlobalType = 0xFB

	// ProprietaryGlobalType is used to house any proper chary global-scope
	// keys within the PSBT.
	//
	// The key is ({0xFC}|<prefix>|{subtype}|{key data}) a variable length
	// identifier prefix, followed by a subtype, followed by the key data
	// itself.
	//
	// The value is any data as defined by the proprietary type user.
	ProprietaryGlobalType = 0xFC
)

type InputType

type InputType uint32

InputType is the set of types that are defined for each input included within the PSBT.

const (
	// NonWitnessUtxoType has no key ({0x00}) and houses the transaction in
	// network serialization format the current input spends from. This
	// should only be present for inputs which spend non-segwit outputs.
	// However, if it is unknown whether an input spends a segwit output,
	// this type should be used. The entire input transaction is needed in
	// order to be able to verify the values of the input (pre-segwit they
	// aren't in the signature digest).
	NonWitnessUtxoType InputType = 0

	// WitnessUtxoType has no key ({0x01}), and houses the entire
	// transaction output in network serialization which the current input
	// spends from.  This should only be present for inputs which spend
	// segwit outputs, including P2SH embedded ones (value || script).
	WitnessUtxoType InputType = 1

	// PartialSigType is used to include a partial signature with key
	// ({0x02}|{public key}).
	//
	// The value is the signature as would be pushed to the stack from a
	// scriptSig or witness..
	PartialSigType InputType = 2

	// SighashType is an empty key ({0x03}).
	//
	// The value contains the 32-bit unsigned integer specifying the
	// sighash type to be used for this input. Signatures for this input
	// must use the sighash type, finalizers must fail to finalize inputs
	// which have signatures that do not match the specified sighash type.
	// Signers who cannot produce signatures with the sighash type must not
	// provide a signature.
	SighashType InputType = 3

	// RedeemScriptInputType is an empty key ({0x40}).
	//
	// The value is the redeem script of the input if present.
	RedeemScriptInputType InputType = 4

	// WitnessScriptInputType is an empty key ({0x05}).
	//
	// The value is the witness script of this input, if it has one.
	WitnessScriptInputType InputType = 5

	// Bip32DerivationInputType is a type that carries the pubkey along
	// with the key ({0x06}|{public key}).
	//
	// The value is master key fingerprint as defined by BIP 32
	// concatenated with the derivation path of the public key. The
	// derivation path is represented as 32 bit unsigned integer indexes
	// concatenated with each other. Public keys are those that will be
	// needed to sign this input.
	Bip32DerivationInputType InputType = 6

	// FinalScriptSigType is an empty key ({0x07}).
	//
	// The value contains a fully constructed scriptSig with signatures and
	// any other scripts necessary for the input to pass validation.
	FinalScriptSigType InputType = 7

	// FinalScriptWitnessType is an empty key ({0x08}). The value is a
	// fully constructed scriptWitness with signatures and any other
	// scripts necessary for the input to pass validation.
	FinalScriptWitnessType InputType = 8

	// ProprietaryInputType is a custom type for use by devs.
	//
	// The key ({0xFC}|<prefix>|{subtype}|{key data}), is a Variable length
	// identifier prefix, followed by a subtype, followed by the key data
	// itself.
	//
	// The value is any value data as defined by the proprietary type user.
	ProprietaryInputType InputType = 0xFC
)

type OutputType

type OutputType uint32

OutputType is the set of types defined per output within the PSBT.

const (
	// RedeemScriptOutputType is an empty key ({0x00}>
	//
	// The value is the redeemScript for this output if it has one.
	RedeemScriptOutputType OutputType = 0

	// WitnessScriptOutputType is an empty key ({0x01}).
	//
	// The value is the witness script of this input, if it has one.
	WitnessScriptOutputType OutputType = 1

	// needed to spend this output. The key is ({0x02}|{public key}).
	//
	// The value is master key fingerprint concatenated with the derivation
	// path of the public key. The derivation path is represented as 32-bit
	// little endian unsigned integer indexes concatenated with each other.
	// Public keys are those needed to spend this output.
	Bip32DerivationOutputType OutputType = 2
)

type PInput

type PInput struct {
	NonWitnessUtxo     *wire.MsgTx
	WitnessUtxo        *wire.TxOut
	PartialSigs        []*PartialSig
	SighashType        txscript.SigHashType
	RedeemScript       []byte
	WitnessScript      []byte
	Bip32Derivation    []*Bip32Derivation
	FinalScriptSig     []byte
	FinalScriptWitness []byte
	Unknowns           []*Unknown
}

PInput is a struct encapsulating all the data that can be attached to any specific input of the PSBT.

func NewPsbtInput

func NewPsbtInput(nonWitnessUtxo *wire.MsgTx,
	witnessUtxo *wire.TxOut) *PInput

NewPsbtInput creates an instance of PsbtInput given either a nonWitnessUtxo or a witnessUtxo.

NOTE: Only one of the two arguments should be specified, with the other being `nil`; otherwise the created PsbtInput object will fail IsSane() checks and will not be usable.

func (*PInput) IsSane

func (pi *PInput) IsSane() bool

IsSane returns true only if there are no conflicting values in the Psbt PInput. It checks that witness and non-witness utxo entries do not both exist, and that witnessScript entries are only added to witness inputs.

type POutput

type POutput struct {
	RedeemScript    []byte
	WitnessScript   []byte
	Bip32Derivation []*Bip32Derivation
}

POutput is a struct encapsulating all the data that can be attached to any specific output of the PSBT.

func NewPsbtOutput

func NewPsbtOutput(redeemScript []byte, witnessScript []byte,
	bip32Derivation []*Bip32Derivation) *POutput

NewPsbtOutput creates an instance of PsbtOutput; the three parameters redeemScript, witnessScript and Bip32Derivation are all allowed to be `nil`.

type Packet

type Packet struct {
	// UnsignedTx is the decoded unsigned transaction for this PSBT.
	UnsignedTx *wire.MsgTx // Deserialization of unsigned tx

	// Inputs contains all the information needed to properly sign this
	// target input within the above transaction.
	Inputs []PInput

	// Outputs contains all information required to spend any outputs
	// produced by this PSBT.
	Outputs []POutput

	// Unknowns are the set of custom types (global only) within this PSBT.
	Unknowns []Unknown
}

Packet is the actual psbt repreesntation. It is a is a set of 1 + N + M key-value pair lists, 1 global, defining the unsigned transaction structure with N inputs and M outputs. These key-value pairs can contain scripts, signatures, key derivations and other transaction-defining data.

func New

func New(inputs []*wire.OutPoint,
	outputs []*wire.TxOut, version int32, nLockTime uint32,
	nSequences []uint32) (*Packet, error)

New on provision of an input and output 'skeleton' for the transaction, a new partially populated PBST packet. The populated packet will include the unsigned transaction, and the set of known inputs and outputs contained within the unsigned transaction. The values of nLockTime, nSequence (per input) and transaction version (must be 1 of 2) must be specified here. Note that the default nSequence value is wire.MaxTxInSequenceNum. Referencing the PSBT BIP, this function serves the roles of teh Creator.

func NewFromRawBytes

func NewFromRawBytes(r io.Reader, b64 bool) (*Packet, error)

NewFromRawBytes returns a new instance of a Packet struct created by reading from a byte slice. If the format is invalid, an error is returned. If the argument b64 is true, the passed byte slice is decoded from base64 encoding before processing.

NOTE: To create a Packet from one's own data, rather than reading in a serialization from a counterparty, one should use a psbt.New.

func NewFromUnsignedTx

func NewFromUnsignedTx(tx *wire.MsgTx) (*Packet, error)

NewFromUnsignedTx creates a new Psbt struct, without any signatures (i.e. only the global section is non-empty) using the passed unsigned transaction.

func (*Packet) B64Encode

func (p *Packet) B64Encode() (string, error)

B64Encode returns the base64 encoding of the serialization of the current PSBT, or an error if the encoding fails.

func (*Packet) IsComplete

func (p *Packet) IsComplete() bool

IsComplete returns true only if all of the inputs are finalized; this is particularly important in that it decides whether the final extraction to a network serialized signed transaction will be possible.

func (*Packet) SanityCheck

func (p *Packet) SanityCheck() error

SanityCheck checks conditions on a PSBT to ensure that it obeys the rules of BIP174, and returns true if so, false if not.

func (*Packet) Serialize

func (p *Packet) Serialize(w io.Writer) error

Serialize creates a binary serialization of the referenced Packet struct with lexicographical ordering (by key) of the subsections.

type PartialSig

type PartialSig struct {
	PubKey    []byte
	Signature []byte
}

PartialSig encapsulate a (BRON public key, ECDSA signature) pair, note that the fields are stored as byte slices, not bronec.PublicKey or bronec.Signature (because manipulations will be with the former not the latter, here); compliance with consensus serialization is enforced with .checkValid()

type PartialSigSorter

type PartialSigSorter []*PartialSig

PartialSigSorter implements sort.Interface for PartialSig.

func (PartialSigSorter) Len

func (s PartialSigSorter) Len() int

func (PartialSigSorter) Less

func (s PartialSigSorter) Less(i, j int) bool

func (PartialSigSorter) Swap

func (s PartialSigSorter) Swap(i, j int)

type SignOutcome

type SignOutcome int

SignOutcome is a enum-like value that expresses the outcome of a call to the Sign method.

type Unknown

type Unknown struct {
	Key   []byte
	Value []byte
}

Unknown is a struct encapsulating a key-value pair for which the key type is unknown by this package; these fields are allowed in both the 'Global' and the 'Input' section of a PSBT.

type Updater

type Updater struct {
	Upsbt *Packet
}

Updater encapsulates the role 'Updater' as specified in BIP174; it accepts Psbt structs and has methods to add fields to the inputs and outputs.

func NewUpdater

func NewUpdater(p *Packet) (*Updater, error)

NewUpdater returns a new instance of Updater, if the passed Psbt struct is in a valid form, else an error.

func (*Updater) AddInBip32Derivation

func (p *Updater) AddInBip32Derivation(masterKeyFingerprint uint32,
	bip32Path []uint32, pubKeyData []byte, inIndex int) error

AddInBip32Derivation takes a master key fingerprint as defined in BIP32, a BIP32 path as a slice of uint32 values, and a serialized pubkey as a byte slice, along with the integer index of the input, and inserts this data into that input.

NOTE: This can be called multiple times for the same input. An error is returned if addition of this key-value pair to the Psbt fails.

func (*Updater) AddInNonWitnessUtxo

func (p *Updater) AddInNonWitnessUtxo(tx *wire.MsgTx, inIndex int) error

AddInNonWitnessUtxo adds the utxo information for an input which is non-witness. This requires provision of a full transaction (which is the source of the corresponding prevOut), and the input index. If addition of this key-value pair to the Psbt fails, an error is returned.

func (*Updater) AddInRedeemScript

func (p *Updater) AddInRedeemScript(redeemScript []byte,
	inIndex int) error

AddInRedeemScript adds the redeem script information for an input. The redeem script is passed serialized, as a byte slice, along with the index of the input. An error is returned if addition of this key-value pair to the Psbt fails.

func (*Updater) AddInSighashType

func (p *Updater) AddInSighashType(sighashType txscript.SigHashType,
	inIndex int) error

AddInSighashType adds the sighash type information for an input. The sighash type is passed as a 32 bit unsigned integer, along with the index for the input. An error is returned if addition of this key-value pair to the Psbt fails.

func (*Updater) AddInWitnessScript

func (p *Updater) AddInWitnessScript(witnessScript []byte,
	inIndex int) error

AddInWitnessScript adds the witness script information for an input. The witness script is passed serialized, as a byte slice, along with the index of the input. An error is returned if addition of this key-value pair to the Psbt fails.

func (*Updater) AddInWitnessUtxo

func (p *Updater) AddInWitnessUtxo(txout *wire.TxOut, inIndex int) error

AddInWitnessUtxo adds the utxo information for an input which is witness. This requires provision of a full transaction *output* (which is the source of the corresponding prevOut); not the full transaction because BIP143 means the output information is sufficient, and the input index. If addition of this key-value pair to the Psbt fails, an error is returned.

func (*Updater) AddOutBip32Derivation

func (p *Updater) AddOutBip32Derivation(masterKeyFingerprint uint32,
	bip32Path []uint32, pubKeyData []byte, outIndex int) error

AddOutBip32Derivation takes a master key fingerprint as defined in BIP32, a BIP32 path as a slice of uint32 values, and a serialized pubkey as a byte slice, along with the integer index of the output, and inserts this data into that output.

NOTE: That this can be called multiple times for the same output. An error is returned if addition of this key-value pair to the Psbt fails.

func (*Updater) AddOutRedeemScript

func (p *Updater) AddOutRedeemScript(redeemScript []byte,
	outIndex int) error

AddOutRedeemScript takes a redeem script as a byte slice and appends it to the output at index outIndex.

func (*Updater) AddOutWitnessScript

func (p *Updater) AddOutWitnessScript(witnessScript []byte,
	outIndex int) error

AddOutWitnessScript takes a witness script as a byte slice and appends it to the output at index outIndex.

func (*Updater) Sign

func (u *Updater) Sign(inIndex int, sig []byte, pubKey []byte,
	redeemScript []byte, witnessScript []byte) (SignOutcome, error)

Sign allows the caller to sign a PSBT at a particular input; they must provide a signature and a pubkey, both as byte slices; they can also optionally provide both witnessScript and/or redeemScript, otherwise these arguments must be set as nil (and in that case, they must already be present in the PSBT if required for signing to succeed).

This serves as a wrapper around Updater.addPartialSignature; it ensures that the redeemScript and witnessScript are updated as needed (note that the Updater is allowed to add redeemScripts and witnessScripts independently, before signing), and ensures that the right form of utxo field (NonWitnessUtxo or WitnessUtxo) is included in the input so that signature insertion (and then finalization) can take place.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL