Documentation ¶
Overview ¶
A modification of the BIP-174 standard for Partial Signed Elements Transaction. (https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki)
Index ¶
- Constants
- Variables
- func Extract(p *Pset) (*transaction.Transaction, error)
- func Finalize(p *Pset, inIndex int) error
- func FinalizeAll(p *Pset) error
- func MaybeFinalize(p *Pset, inIndex int) (bool, error)
- func MaybeFinalizeAll(p *Pset) error
- func VerifyBlinding(pset *Pset, blindingDataLikes []BlindingDataLike, ...) (bool, error)
- type AddIssuanceArgs
- type AddReissuanceArgs
- type Blinder
- type BlindingData
- type BlindingDataLike
- type IssuanceBlindingPrivateKeys
- type PInput
- type POutput
- type PSET_PACKAGE
- type PrivateBlindingKey
- type Pset
- type Unknown
- type Updater
- func (p *Updater) AddInBip32Derivation(masterKeyFingerprint uint32, bip32Path []uint32, pubKeyData []byte, ...) error
- func (p *Updater) AddInNonWitnessUtxo(tx *transaction.Transaction, inIndex int) error
- func (p *Updater) AddInRedeemScript(redeemScript []byte, inIndex int) error
- func (p *Updater) AddInSighashType(sighashType txscript.SigHashType, inIndex int) error
- func (p *Updater) AddInWitnessScript(witnessScript []byte, inIndex int) error
- func (p *Updater) AddInWitnessUtxo(txout *transaction.TxOutput, inIndex int) error
- func (p *Updater) AddInput(txInput *transaction.TxInput)
- func (p *Updater) AddIssuance(arg AddIssuanceArgs) error
- func (p *Updater) AddOutBip32Derivation(masterKeyFingerprint uint32, bip32Path []uint32, pubKeyData []byte, ...) error
- func (p *Updater) AddOutRedeemScript(redeemScript []byte, outIndex int) error
- func (p *Updater) AddOutWitnessScript(witnessScript []byte, outIndex int) error
- func (p *Updater) AddOutput(txOutput *transaction.TxOutput)
- func (p *Updater) AddReissuance(arg AddReissuanceArgs) error
- func (p *Updater) Sign(inIndex int, sig []byte, pubKey []byte, redeemScript []byte, ...) (psbt.SignOutcome, error)
Constants ¶
const ( NonConfidentialReissuanceTokenFlag = 0 ConfidentialReissuanceTokenFlag = 1 )
Variables ¶
var ( // ErrGenerateSurjectionProof is returned if the computation of the // surjection proof fails. ErrGenerateSurjectionProof = errors.New( "failed to generate surjection proof, please retry", ) // ErrNeedPrevout is returned if a BlindingDataLike needs the input's prevout but received nil ErrNeedPrevout = errors.New( "need prevout to get blinding data", ) )
Functions ¶
func Extract ¶
func Extract(p *Pset) (*transaction.Transaction, error)
Extract takes a finalized pset.Pset and outputs a finalized transaction instance. Note that if the PSET is in-complete, then an error ErrIncompletePSET will be returned. As the extracted transaction has been fully finalized, it will be ready for network broadcast once returned.
func Finalize ¶
Finalize assumes that the provided pset.Pset 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 FinalizeAll ¶
FinalizeAll finalizes all inputs of a partial elements transaction by calling the Finalize function for every partial input
func MaybeFinalize ¶
MaybeFinalize attempts to finalize the input at index inIndex in the PSET p, returning true with no error if it succeeds, OR if the input has already been finalized.
func MaybeFinalizeAll ¶
MaybeFinalizeAll attempts to finalize all inputs of the pset.Pset that are not already finalized, and returns an error if it fails to do so.
func VerifyBlinding ¶ added in v0.0.4
func VerifyBlinding( pset *Pset, blindingDataLikes []BlindingDataLike, outBlindKeysByIndex map[int][]byte, inIssuanceKeys []IssuanceBlindingPrivateKeys, ) (bool, error)
VerifyBlinding verifies the proofs of all the confidential outputs of the given transaction, with the given in/out private blinding keys.
Types ¶
type AddIssuanceArgs ¶ added in v0.1.0
type AddIssuanceArgs struct { Precision uint Contract *transaction.IssuanceContract AssetAmount uint64 TokenAmount uint64 AssetAddress string TokenAddress string }
AddIssuanceArgs is a struct encapsulating all the issuance data that can be attached to any specific transaction of the PSBT.
type AddReissuanceArgs ¶ added in v0.1.0
type AddReissuanceArgs struct { PrevOutHash string PrevOutIndex uint32 PrevOutBlinder []byte WitnessUtxo *transaction.TxOutput NonWitnessUtxo *transaction.Transaction Entropy string AssetAmount uint64 AssetAddress string TokenAmount uint64 TokenAddress string }
AddReissuanceArgs defines the mandatory fields that one needs to pass to the AddReissuance method of the *Updater type
PrevOutHash: the prevout hash of the token that will be added as input to the tx PrevOutIndex: the prevout index of the token that will be added as input to the tx PrevOutBlinder: the asset blinder used to blind the prevout token WitnessUtxo: the prevout token in case it is a witness one NonWitnessUtxo: the prevout tx that include the token output in case it is a non witness one Entropy: the entropy used to generate token and asset AssetAmount: the amount of asset to re-issue TokenAmount: the same unblinded amount of the prevout token AssetAddress: the destination address of the re-issuing asset TokenAddress: the destination address of the re-issuance token
type Blinder ¶ added in v0.2.0
type Blinder struct {
// contains filtered or unexported fields
}
Blinder is designed to blind ALL the outputs of the partial transaction.
func NewBlinder ¶ added in v0.0.2
func NewBlinder( pset *Pset, blindingDataLikes []BlindingDataLike, outputsPubKeyByIndex map[int][]byte, issuanceBlindingPrivateKeys []IssuanceBlindingPrivateKeys, rng randomNumberGenerator, ) (*Blinder, error)
NewBlinder is a factory function using a map to select outputs to blind
type BlindingData ¶ added in v0.2.0
type BlindingData confidential.UnblindOutputResult
BlindingData = blinders
func (BlindingData) GetUnblindOutputResult ¶ added in v0.2.0
func (blindingData BlindingData) GetUnblindOutputResult(prevout *transaction.TxOutput) (*confidential.UnblindOutputResult, error)
GetUnblindOutputResult only cast BlindingData to unblindOutputResult
type BlindingDataLike ¶ added in v0.2.0
type BlindingDataLike interface {
GetUnblindOutputResult(prevout *transaction.TxOutput) (*confidential.UnblindOutputResult, error)
}
BlindingDataLike defines data used to get blinders from input
type IssuanceBlindingPrivateKeys ¶ added in v0.0.3
IssuanceBlindingPrivateKeys stores the AssetKey and TokenKey that will be used in the Blinder.
func (IssuanceBlindingPrivateKeys) ToSlice ¶ added in v0.0.4
func (ik IssuanceBlindingPrivateKeys) ToSlice() [][]byte
ToSlice get private keys as []byte from IssuanceBlindingPrivateKeys
type PInput ¶
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 }
PInput is a struct encapsulating all the data that can be attached to any specific input of the PSBT.
func NewPsetInput ¶
func NewPsetInput(nonWitnessUtxo *transaction.Transaction, witnessUtxo *transaction.TxOutput) *PInput
NewPsetInput 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.
type POutput ¶
type POutput struct { RedeemScript []byte WitnessScript []byte Bip32Derivation []*psbt.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 []*psbt.Bip32Derivation) *POutput
NewPsbtOutput creates an instance of PsbtOutput; the three parameters redeemScript, witnessScript and Bip32Derivation are all allowed to be `nil`.
type PSET_PACKAGE ¶ added in v0.0.4
type PSET_PACKAGE int
This type is for GoDoc documentation purposes only. It explains on a deeper level how to use the PSET package correctly.
This package is designed in order to apply the possible fewer changes to the reference spec so that it can be used for Elements unblinded and blinded transactions. Essentially this version of partial transaction uses an underlying Elements unsigned transaction instead of a Bitcoin one, and the partial input WitnessUtxo field represents an Elements output rather than a Bitcoin one.
NOTE: The Elements implementation of PSET is under development at the moment (take a look here) and this package will likely change in the future to adapt to this standard.
func ROLE_1_Creator ¶ added in v0.0.4
func ROLE_1_Creator() *PSET_PACKAGE
The creator is an exported factory function named simply New with the following signature:
func New(inputs []*transaction.TxInput, outputs []*transaction.TxOutput, version int32, nLockTime uint32) (*Pset, error) {}
The role of this function is to simply create an unsigned partial transaction with the given inputs, outputs, version and locktime. The unblinded asset and amounts of the outputs are encoded into the "unsigned tx" field of the partial transaction.
func ROLE_2_Updater ¶ added in v0.0.4
func ROLE_2_Updater() *PSET_PACKAGE
The updater, as the name suggests, has the responsibility of updating the fields of any partial input or output. It consists of a collection of methods that, basically, has the purpose of adding any new field to an existing partial input (included issuance or reissuance placed in the unsigned tx) or output. It also allows to add new inputs or outputs to the underlying unsigned transaction. The updater can be instantiated by calling the NewUpdater factory function passing a partial transasction object.
func ROLE_3_Blinder ¶ added in v0.0.4
func ROLE_3_Blinder() *PSET_PACKAGE
At the moment the blinder role is designed to blind ALL the outputs of the partial transaction but this will change soon, letting one to blind only the set of outputs he wants. Also, this version of the blinder requires that all the private keys necessary to unblind all the confidential inputs used must be provided. Given this, the pset package is not useful in case multiple parties want to create a transaction by joining their inputs/outputs since they would need to reveal their blinding private keys and share them with the one encharged of assuming the blinder role. The pset package will change in the future to support the use case mentioned before, but this is not yet planned in the development.
func ROLE_4_Signer ¶ added in v0.0.4
func ROLE_4_Signer() *PSET_PACKAGE
The signer is in charge of checking that when adding a signature to an input of the pset, this is valid and that also the pset is correctly structured. Given that, this role is implemented as a function Sign of the *Updater type. This function accepts an input index, a signature, a public key, and one between a redeem or witness script and checks that the signature is valid against the given script and pubkey, along with setting the partial input's signature script to the one provided.
func ROLE_5_Finalizer ¶ added in v0.0.4
func ROLE_5_Finalizer() *PSET_PACKAGE
The finalizer takes a partial transaction and combines every input's PartialSignature into the final input's SignatureScript. After finalizing, the partial transaction is complete, and it's ready to be extracted from the Pset wrapper and broadcasted to the network. This role is accomplished by a Finalize function that accepts a *Pset instance and an input index, and performs the operations described above, returning an error if any occurs during the process. It previously checks that the provided partial transaction is valid in the sense that it's ready to be finalized; otherwise, an error is returned. A handy FinalizeAll that runs the above method for every input of the provided *Pset is also exported.
func ROLE_6_Extractor ¶ added in v0.0.4
func ROLE_6_Extractor() *PSET_PACKAGE
The extractor is a simple Extract function expecting a finalized partial transaction that returns the final signed transaction by adding the signatures of the partial inputs to the underlying unsigned transaction.
func TX_P2WPKH ¶ added in v0.0.4
func TX_P2WPKH() *PSET_PACKAGE
This is an exemplification on how to perform a P2WPKH transaction using the PSET package with the assistance of vulpemventures/nigiri for funding the address, retrieving the UTXOs and broadcasting.
privkey, err := btcec.NewPrivateKey( ) if err != nil { t.Fatal(err) } pubkey := privkey.PubKey() p2wpkh := payment.FromPublicKey(pubkey, &network.Regtest, nil) address, _ := p2wpkh.WitnessPubKeyHash() // Fund sender address. This function calls the API of vulpemventures/nigiri. _, err = faucet(address) if err != nil { t.Fatal(err) } // Retrieve sender utxos. This function calls the API of vulpemventures/nigiri. utxos, err := unspents(address) if err != nil { t.Fatal(err) } // The transaction will have 1 input and 3 outputs. txInputHash, _ := hex.DecodeString(utxos[0]["txid"].(string)) txInputHash = elementsutil.ReverseBytes(txInputHash) txInputIndex := uint32(utxos[0]["vout"].(float64)) txInput := transaction.NewTxInput(txInputHash, txInputIndex) lbtc, _ := hex.DecodeString( "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225", ) lbtc = append([]byte{0x01}, elementsutil.ReverseBytes(lbtc)...) receiverValue, _ := elementsutil.SatoshiToElementsValue(60000000) receiverScript, _ := hex.DecodeString("76a91439397080b51ef22c59bd7469afacffbeec0da12e88ac") receiverOutput := transaction.NewTxOutput(lbtc, receiverValue[:], receiverScript) changeScript := p2wpkh.WitnessScript changeValue, _ := elementsutil.SatoshiToElementsValue(39999500) changeOutput := transaction.NewTxOutput(lbtc, changeValue[:], changeScript) feeScript := []byte{} feeValue, _ := elementsutil.SatoshiToElementsValue(500) feeOutput := transaction.NewTxOutput(lbtc, feeValue[:], feeScript) // Create a new pset. inputs := []*transaction.TxInput{txInput} outputs := []*transaction.TxOutput{receiverOutput, changeOutput, feeOutput} p, err := New(inputs, outputs, 2, 0) if err != nil { t.Fatal(err) } // Add sighash type and witness utxo to the partial input. updater, err := NewUpdater(p) if err != nil { t.Fatal(err) } updater.AddInSighashType(txscript.SigHashAll, 0) if err != nil { t.Fatal(err) } witValue, _ := elementsutil.SatoshiToElementsValue(uint64(utxos[0]["value"].(float64))) witnessUtxo := transaction.NewTxOutput(lbtc, witValue[:], p2wpkh.WitnessScript) updater.AddInWitnessUtxo(witnessUtxo, 0) // The signing of the input is done by retrieving the proper hash of the serialization of the transaction witHash := updater.Data.UnsignedTx.HashForWitnessV0(0, p2wpkh.Script, witValue[:], txscript.SigHashAll) sig, err := privkey.Sign(witHash[:]) if err != nil { t.Fatal(err) } sigWithHashType := append(sig.Serialize(), byte(txscript.SigHashAll)) // Update the pset adding the input signature script and the pubkey. _, err = updater.Sign(0, sigWithHashType, pubkey.SerializeCompressed(), nil, nil) if err != nil { t.Fatal(err) } valid, err := updater.Data.ValidateAllSignatures() if err != nil { t.Fatal(err) } if !valid { t.Fatal(errors.New("invalid signatures")) } // Finalize the partial transaction. p = updater.Data err = FinalizeAll(p) if err != nil { t.Fatal(err) } // Extract the final signed transaction from the Pset wrapper. finalTx, err := Extract(p) if err != nil { t.Fatal(err) } // Serialize the transaction and try to broadcast. txHex, err := finalTx.ToHex() if err != nil { t.Fatal(err) } // This function calls the API of vulpemventures/nigiri. txid, err := broadcast(txHex) if err != nil { t.Fatal(err) } if len(txid) <= 0 { t.Fatal("Expected transaction to be broadcasted") }
type PrivateBlindingKey ¶ added in v0.2.0
type PrivateBlindingKey []byte
PrivateBlindingKey = a bytes slice | used on confidential input
func (PrivateBlindingKey) GetUnblindOutputResult ¶ added in v0.2.0
func (privKey PrivateBlindingKey) GetUnblindOutputResult(prevout *transaction.TxOutput) (*confidential.UnblindOutputResult, error)
GetUnblindOutputResult for PrivateBlindingKey unblind the associated prevout using the private key or return zero value blinders in case of unconfidential input
type Pset ¶
type Pset struct { // UnsignedTx is the decoded unsigned transaction for this PSET. UnsignedTx *transaction.Transaction // 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 PSET. Outputs []POutput // Unknowns are the set of custom types (global only) within this PSET. Unknowns []Unknown // Data of unknown type at global scope }
Pset 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 []*transaction.TxInput, outputs []*transaction.TxOutput, version int32, nLockTime uint32) (*Pset, error)
New on provision of an input and output 'skeleton' for the transaction, a new partially populated PSET. The populated pset will include the unsigned transaction, and the set of known inputs and outputs contained within the unsigned transaction. The values of nLockTime 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 the Creator.
func NewPsetFromBase64 ¶
NewPsetFromBase64 returns a new Pset from a serialized pset in base64 encoding
func NewPsetFromHex ¶
NewPsetFromHex returns a new Pset from serialized pset in hex encoiding.
func NewPsetFromUnsignedTx ¶
func NewPsetFromUnsignedTx(tx *transaction.Transaction) (*Pset, error)
NewPsetFromUnsignedTx creates a new Pset struct, without any signatures (i.e. only the global section is non-empty) using the passed unsigned transaction.
func (*Pset) IsComplete ¶
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 (*Pset) SanityCheck ¶
SanityCheck checks conditions on a PSBT to ensure that it obeys the rules of BIP174, and returns true if so, false if not.
func (*Pset) ToBase64 ¶
ToBase64 returns the base64 encoding of the serialization of the current PSET, or an error if the encoding fails.
func (*Pset) ToHex ¶
ToHex returns the hex encoding of the serialization of the current PSET, or an error if the encoding fails.
func (*Pset) ValidateAllSignatures ¶ added in v0.0.4
type Unknown ¶
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 PSET.
type Updater ¶
type Updater struct {
Data *Pset
}
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 ¶
NewUpdater returns a new instance of Updater, if the passed Psbt struct is in a valid form, else an error.a
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 *transaction.Transaction, 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 ¶
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 ¶
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 *transaction.TxOutput, 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) AddInput ¶ added in v0.0.3
func (p *Updater) AddInput(txInput *transaction.TxInput)
AddInput adds input to underlying unsignedTx
func (*Updater) AddIssuance ¶ added in v0.0.3
func (p *Updater) AddIssuance(arg AddIssuanceArgs) error
AddIssuance adds an unblinded issuance to the transaction
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 ¶
AddOutRedeemScript takes a redeem script as a byte slice and appends it to the output at index outIndex.
func (*Updater) AddOutWitnessScript ¶
AddOutWitnessScript takes a witness script as a byte slice and appends it to the output at index outIndex.
func (*Updater) AddOutput ¶ added in v0.0.3
func (p *Updater) AddOutput(txOutput *transaction.TxOutput)
AddOutput adds output to underlying unsignedTx
func (*Updater) AddReissuance ¶ added in v0.1.0
func (p *Updater) AddReissuance(arg AddReissuanceArgs) error
AddReissuance takes care of adding an input (the prevout token) and 2 outputs to the partial transaction. It also creates a new (re)issuance with the provided entropy, blinder and amounts and attaches it to the new input. NOTE: This transaction must be blinded later so that a new token blinding nonce is generated for the new token output
func (*Updater) Sign ¶
func (p *Updater) Sign(inIndex int, sig []byte, pubKey []byte, redeemScript []byte, witnessScript []byte) (psbt.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.