Documentation ¶
Index ¶
- Variables
- func AddBip32Derivation(derivations []*psbt.Bip32Derivation, target *psbt.Bip32Derivation) []*psbt.Bip32Derivation
- func AddOutput(pkt *VPacket, amount uint64, scriptAddr asset.ScriptKey, outputIndex uint32, ...)
- func AddTaprootBip32Derivation(derivations []*psbt.TaprootBip32Derivation, ...) []*psbt.TaprootBip32Derivation
- func Bip32DerivationFromKeyDesc(keyDesc keychain.KeyDescriptor, coinType uint32) (*psbt.Bip32Derivation, *psbt.TaprootBip32Derivation)
- func FromAddresses(receiverAddrs []*address.Tap, firstOutputIndex uint32) (*VPacket, OutputIdxToAddr, error)
- func KeyDescFromBip32Derivation(bip32Derivation *psbt.Bip32Derivation) (keychain.KeyDescriptor, error)
- type Anchor
- type ErrorTestCase
- type InputCommitments
- type OutputIdxToAddr
- type TestAnchor
- type TestBip32Derivation
- type TestTrBip32Derivation
- type TestVInput
- type TestVOutput
- type TestVPacket
- type TestVectors
- type VInput
- type VOutPredicate
- type VOutput
- type VOutputType
- type VPacket
- func ForInteractiveSend(id asset.ID, amount uint64, scriptAddr asset.ScriptKey, outputIndex uint32, ...) *VPacket
- func NewFromPsbt(packet *psbt.Packet) (*VPacket, error)
- func NewFromRawBytes(r io.Reader, b64 bool) (*VPacket, error)
- func OwnershipProofPacket(ownedAsset *asset.Asset, chainParams *address.ChainParams) *VPacket
- func RandPacket(t testing.TB) *VPacket
- func (p *VPacket) B64Encode() (string, error)
- func (p *VPacket) EncodeAsPsbt() (*psbt.Packet, error)
- func (p *VPacket) FirstInteractiveOutput() (*VOutput, error)
- func (p *VPacket) FirstNonSplitRootOutput() (*VOutput, error)
- func (p *VPacket) HasInteractiveOutput() bool
- func (p *VPacket) HasSplitCommitment() (bool, error)
- func (p *VPacket) HasSplitRootOutput() bool
- func (p *VPacket) PassiveAssetsOutput() (*VOutput, error)
- func (p *VPacket) Serialize(w io.Writer) error
- func (p *VPacket) SetInputAsset(index int, a *asset.Asset, proof []byte)
- func (p *VPacket) SplitRootOutput() (*VOutput, error)
- type ValidTestCase
Constants ¶
This section is empty.
Variables ¶
var ( PsbtKeyTypeGlobalTapIsVirtualTx = []byte{0x70} PsbtKeyTypeGlobalTapChainParamsHRP = []byte{0x71} PsbtKeyTypeGlobalTapPsbtVersion = []byte{0x72} PsbtKeyTypeInputTapPrevID = []byte{0x70} PsbtKeyTypeInputTapAnchorValue = []byte{0x71} PsbtKeyTypeInputTapAnchorPkScript = []byte{0x72} PsbtKeyTypeInputTapAnchorSigHashType = []byte{0x73} PsbtKeyTypeInputTapAnchorInternalKey = []byte{0x74} PsbtKeyTypeInputTapAnchorMerkleRoot = []byte{0x75} PsbtKeyTypeInputTapAnchorOutputBip32Derivation = []byte{0x76} PsbtKeyTypeInputTapAnchorOutputTaprootBip32Derivation = []byte{0x77} PsbtKeyTypeInputTapAnchorTapscriptSibling = []byte{0x78} PsbtKeyTypeInputTapAsset = []byte{0x79} PsbtKeyTypeInputTapAssetProof = []byte{0x7a} PsbtKeyTypeOutputTapType = []byte{0x70} PsbtKeyTypeOutputTapIsInteractive = []byte{0x71} PsbtKeyTypeOutputTapAnchorOutputIndex = []byte{0x72} PsbtKeyTypeOutputTapAnchorOutputInternalKey = []byte{0x73} PsbtKeyTypeOutputTapAnchorOutputBip32Derivation = []byte{0x74} PsbtKeyTypeOutputTapAnchorOutputTaprootBip32Derivation = []byte{0x75} PsbtKeyTypeOutputTapAsset = []byte{0x76} PsbtKeyTypeOutputTapSplitAsset = []byte{0x77} PsbtKeyTypeOutputTapAnchorTapscriptSibling = []byte{0x78} PsbtKeyTypeOutputAssetVersion = []byte{0x79} )
We define a set of Taproot Asset (TAP) specific global, input and output PSBT key types here that correspond to the custom types defined in the VPacket below. We start at 0x70 because that is sufficiently high to not conflict with any of the keys specified in BIP-0174. Also, 7 is leet speak for "t" as in Taproot Assets. It would perhaps make sense to wrap these values in the BIP-0174 defined proprietary types to make 100% sure that no parser removes them. But the BIP also mentions to not remove unknown keys, so we should be fine like this as well.
var ( PsbtKeyTypeInputTapProof = []byte{0x70} PsbtKeyTypeOutputTapProof = []byte{0x70} )
The following keys are used as custom fields on the BTC level anchor transaction PSBTs only. They are defined here for completeness' sake but are not directly used by the tappsbt package.
var ( // VOutIsSplitRoot is a predicate that returns true if the virtual // output is a split root output. VOutIsSplitRoot = func(o *VOutput) bool { return o.Type.IsSplitRoot() } // VOutCanCarryPassive is a predicate that returns true if the virtual // output can carry passive assets. VOutCanCarryPassive = func(o *VOutput) bool { return o.Type.CanCarryPassive() } // VOutIsNotSplitRoot is a predicate that returns true if the virtual // output is NOT a split root output. VOutIsNotSplitRoot = func(o *VOutput) bool { return !o.Type.IsSplitRoot() } // VOutIsInteractive is a predicate that returns true if the virtual // transaction is interactive. VOutIsInteractive = func(o *VOutput) bool { return o.Interactive } )
var ( // ErrKeyNotFound is returned when a key is not found among the unknown // fields of a packet. ErrKeyNotFound = errors.New("tappsbt: key not found") )
Functions ¶
func AddBip32Derivation ¶
func AddBip32Derivation(derivations []*psbt.Bip32Derivation, target *psbt.Bip32Derivation) []*psbt.Bip32Derivation
AddBip32Derivation adds the given target BIP-0032 derivation to the list of derivations if it is not already present.
func AddOutput ¶
func AddOutput(pkt *VPacket, amount uint64, scriptAddr asset.ScriptKey, outputIndex uint32, anchorInternalKey keychain.KeyDescriptor, assetVersion asset.Version)
AddOutput adds an interactive output to the given packet.
func AddTaprootBip32Derivation ¶
func AddTaprootBip32Derivation(derivations []*psbt.TaprootBip32Derivation, target *psbt.TaprootBip32Derivation) []*psbt.TaprootBip32Derivation
AddTaprootBip32Derivation adds the given target Taproot BIP-0032 derivation to the list of derivations if it is not already present.
func Bip32DerivationFromKeyDesc ¶
func Bip32DerivationFromKeyDesc(keyDesc keychain.KeyDescriptor, coinType uint32) (*psbt.Bip32Derivation, *psbt.TaprootBip32Derivation)
Bip32DerivationFromKeyDesc returns the default and Taproot BIP-0032 key derivation information from the given key descriptor information.
func FromAddresses ¶
func FromAddresses(receiverAddrs []*address.Tap, firstOutputIndex uint32) (*VPacket, OutputIdxToAddr, error)
FromAddresses creates an empty virtual transaction packet from the given addresses. Because sending to an address is always non-interactive, a change output is also added to the packet.
func KeyDescFromBip32Derivation ¶
func KeyDescFromBip32Derivation( bip32Derivation *psbt.Bip32Derivation) (keychain.KeyDescriptor, error)
KeyDescFromBip32Derivation attempts to extract the key descriptor from the given public key and BIP-0032 derivation information.
Types ¶
type Anchor ¶
type Anchor struct { // Value is output value of the anchor output. Value btcutil.Amount // PkScript is the output script of the anchor output. PkScript []byte // SigHashType is the signature hash type that should be used to sign // the anchor output spend. SigHashType txscript.SigHashType // InternalKey is the internal key of the anchor output that the input // is spending the asset from. InternalKey *btcec.PublicKey // MerkleRoot is the root of the tap script merkle tree that also // contains the Taproot Asset commitment of the anchor output. MerkleRoot []byte // TapscriptSibling is the tapscript sibling of the Taproot Asset // commitment. TapscriptSibling []byte // Bip32Derivation is the BIP-0032 derivation of the anchor output's // internal key. Bip32Derivation []*psbt.Bip32Derivation // TrBip32Derivation is the Taproot BIP-0032 derivation of the anchor // output's internal key. TrBip32Derivation []*psbt.TaprootBip32Derivation }
Anchor is a struct that contains all the information about an anchor output.
type ErrorTestCase ¶ added in v0.3.0
type ErrorTestCase struct { Packet *TestVPacket `json:"packet"` Error string `json:"error"` Comment string `json:"comment"` }
type InputCommitments ¶
type InputCommitments = map[int]*commitment.TapCommitment
InputCommitments is a map from virtual package input index to its associated Taproot Asset commitment.
type OutputIdxToAddr ¶ added in v0.3.0
OutputIdxToAddr is a map from a VPacket's VOutput index to its associated Tap address.
type TestAnchor ¶ added in v0.3.0
type TestAnchor struct { Value int64 `json:"value"` PkScript string `json:"pk_script"` SigHashType uint32 `json:"sig_hash_type"` InternalKey string `json:"internal_key"` MerkleRoot string `json:"merkle_root"` TapscriptSibling string `json:"tapscript_sibling"` Bip32Derivation []*TestBip32Derivation `json:"bip32_derivation"` TrBip32Derivation []*TestTrBip32Derivation `json:"tr_bip32_derivation"` }
func NewTestFromAnchor ¶ added in v0.3.0
func NewTestFromAnchor(a *Anchor) *TestAnchor
type TestBip32Derivation ¶ added in v0.3.0
type TestBip32Derivation struct { PubKey string `json:"pub_key"` Fingerprint uint32 `json:"fingerprint"` Bip32Path []uint32 `json:"bip32_path"` }
func NewTestFromBip32Derivation ¶ added in v0.3.0
func NewTestFromBip32Derivation(b *psbt.Bip32Derivation) *TestBip32Derivation
func (*TestBip32Derivation) ToBip32Derivation ¶ added in v0.3.0
func (td *TestBip32Derivation) ToBip32Derivation( t testing.TB) *psbt.Bip32Derivation
type TestTrBip32Derivation ¶ added in v0.3.0
type TestTrBip32Derivation struct { XOnlyPubKey string `json:"pub_key"` LeafHashes []string `json:"leaf_hashes"` Fingerprint uint32 `json:"fingerprint"` Bip32Path []uint32 `json:"bip32_path"` }
func NewTestFromTrBip32Derivation ¶ added in v0.3.0
func NewTestFromTrBip32Derivation( b *psbt.TaprootBip32Derivation) *TestTrBip32Derivation
func (*TestTrBip32Derivation) ToTrBip32Derivation ¶ added in v0.3.0
func (td *TestTrBip32Derivation) ToTrBip32Derivation( t testing.TB) *psbt.TaprootBip32Derivation
type TestVInput ¶ added in v0.3.0
type TestVInput struct { Bip32Derivation []*TestBip32Derivation `json:"bip32_derivation"` TrBip32Derivation []*TestTrBip32Derivation `json:"tr_bip32_derivation"` TrInternalKey string `json:"tr_internal_key"` TrMerkleRoot string `json:"tr_merkle_root"` PrevID *asset.TestPrevID `json:"prev_id"` Anchor *TestAnchor `json:"anchor"` Asset *asset.TestAsset `json:"asset"` Proof string `json:"proof"` }
func NewTestFromVInput ¶ added in v0.3.0
func NewTestFromVInput(t testing.TB, i *VInput) *TestVInput
type TestVOutput ¶ added in v0.3.0
type TestVOutput struct { Amount uint64 `json:"amount"` Type uint8 `json:"type"` AssetVersion uint32 `json:"asset_version"` Interactive bool `json:"interactive"` AnchorOutputIndex uint32 `json:"anchor_output_index"` AnchorOutputInternalKey string `json:"anchor_output_internal_key"` AnchorOutputBip32Derivation []*TestBip32Derivation `json:"anchor_output_bip32_derivation"` AnchorOutputTrBip32Derivation []*TestTrBip32Derivation `json:"anchor_output_tr_bip32_derivation"` AnchorOutputTapscriptSibling string `json:"anchor_output_tapscript_sibling"` Asset *asset.TestAsset `json:"asset"` SplitAsset *asset.TestAsset `json:"split_asset"` PkScript string `json:"pk_script"` Bip32Derivation []*TestBip32Derivation `json:"bip32_derivation"` TrBip32Derivation []*TestTrBip32Derivation `json:"tr_bip32_derivation"` TrInternalKey string `json:"tr_internal_key"` TrMerkleRoot string `json:"tr_merkle_root"` }
func NewTestFromVOutput ¶ added in v0.3.0
func NewTestFromVOutput(t testing.TB, v *VOutput, coinType uint32) *TestVOutput
type TestVPacket ¶ added in v0.3.0
type TestVPacket struct { Inputs []*TestVInput `json:"inputs"` Outputs []*TestVOutput `json:"outputs"` Version uint8 `json:"version"` ChainParamsHRP string `json:"chain_params_hrp"` }
func NewTestFromVPacket ¶ added in v0.3.0
func NewTestFromVPacket(t testing.TB, p *VPacket) *TestVPacket
type TestVectors ¶ added in v0.3.0
type TestVectors struct { ValidTestCases []*ValidTestCase `json:"valid_test_cases"` ErrorTestCases []*ErrorTestCase `json:"error_test_cases"` }
type VInput ¶
type VInput struct { // PInput is the embedded default PSBT input struct that is used for // asset related input data. psbt.PInput // PrevID is the asset previous ID of the asset being spent. PrevID asset.PrevID // Anchor contains the information about the BTC level anchor // transaction that committed to the asset being spent. Anchor Anchor // contains filtered or unexported fields }
VInput represents an input to a virtual asset state transition transaction.
type VOutPredicate ¶
VOutPredicate is a function that can be used to filter virtual outputs.
type VOutput ¶
type VOutput struct { // Amount is the amount of units of the asset that this output is // creating. This can be zero in case of an asset tombstone in a // non-interactive full value send scenario. When serialized, this will // be stored as the value of the wire.TxOut of the PSBT's unsigned TX. Amount uint64 // AssetVersion is the version of the asset that this output should // create. AssetVersion asset.Version // Type indicates what type of output this is, which has an influence on // whether the asset is set or what witness type is expected to be // generated for the asset. Type VOutputType // Interactive, when set to true, indicates that the receiver of the // output is aware of the asset transfer and can therefore receive a // full value send directly and without a tombstone in the change // output. Interactive bool // AnchorOutputIndex indicates in which output index of the BTC // transaction this asset output should be committed to. Multiple asset // outputs can be committed to within the same BTC transaction output. AnchorOutputIndex uint32 // AnchorOutputInternalKey is the internal key of the anchor output that // will be used to create the anchor Taproot output key to which this // asset output will be committed to. AnchorOutputInternalKey *btcec.PublicKey // AnchorOutputBip32Derivation is the BIP-0032 derivation of the anchor // output's internal key. AnchorOutputBip32Derivation []*psbt.Bip32Derivation // AnchorOutputTaprootBip32Derivation is the Taproot BIP-0032 derivation // of the anchor output's internal key. AnchorOutputTaprootBip32Derivation []*psbt.TaprootBip32Derivation // AnchorOutputTapscriptSibling is the preimage of the tapscript sibling // of the Taproot Asset commitment. AnchorOutputTapscriptSibling *commitment.TapscriptPreimage // Asset is the actual asset (including witness or split commitment // data) that this output will commit to on chain. This asset will be // included in the proof sent to the recipient of this output. Asset *asset.Asset // SplitAsset is the original split asset that was created when creating // the split commitment. // // NOTE: This is only set if the above Asset is the root asset of a // split. Compared to the root asset, this does not have a split // commitment root and no TX witness, but instead has the split // commitment set. SplitAsset *asset.Asset // ScriptKey is the new script key of the recipient of the asset. When // serialized, this will be stored in the TaprootInternalKey and // TaprootDerivationPath fields of the PSBT output. ScriptKey asset.ScriptKey }
VOutput represents an output of a virtual asset state transition.
func (*VOutput) AnchorKeyToDesc ¶
func (o *VOutput) AnchorKeyToDesc() (keychain.KeyDescriptor, error)
AnchorKeyToDesc attempts to extract the key descriptor of the anchor output from the anchor output BIP-0032 derivation information.
func (*VOutput) SetAnchorInternalKey ¶
func (o *VOutput) SetAnchorInternalKey(keyDesc keychain.KeyDescriptor, coinType uint32)
SetAnchorInternalKey sets the internal key and derivation path of the anchor output based on the given key descriptor and coin type.
func (*VOutput) SplitLocator ¶
func (o *VOutput) SplitLocator(assetID asset.ID) commitment.SplitLocator
SplitLocator creates a split locator from the output. The asset ID is passed in for cases in which the asset is not yet set on the output.
type VOutputType ¶
type VOutputType uint8
VOutputType represents the type of virtual output.
const ( // TypeSimple is a plain full-value or split output that is not a split // root and does not carry passive assets. In case of a split, the asset // of this output has a split commitment. TypeSimple VOutputType = 0 // TypeSplitRoot is a split root output that carries the change from a // split or a tombstone from a non-interactive full value send output. // In either case, the asset of this output has a tx witness. TypeSplitRoot VOutputType = 1 // TypePassiveAssetsOnly indicates that this output only carries passive // assets and therefore the asset in this output is nil. The passive // assets themselves are signed in their own virtual transactions and // are not present in this packet. TypePassiveAssetsOnly VOutputType = 2 // TypePassiveSplitRoot is a split root output that carries the change // from a split or a tombstone from a non-interactive full value send // output, as well as passive assets. TypePassiveSplitRoot VOutputType = 3 // TypeSimplePassiveAssets is a plain full-value interactive send output // that also carries passive assets. This is a special case where we // send the full value of a single asset in a commitment to a new script // key, but also carry passive assets in the same output. This is useful // for key rotation (send-to-self) scenarios or asset burns where we // burn the full supply of a single asset within a commitment. TypeSimplePassiveAssets VOutputType = 4 )
func (VOutputType) CanBeInteractive ¶
func (t VOutputType) CanBeInteractive() bool
CanBeInteractive returns true if the output type is compatible with being an interactive send.
func (VOutputType) CanCarryPassive ¶
func (t VOutputType) CanCarryPassive() bool
CanCarryPassive returns true if the output type is compatible with carrying passive assets.
func (VOutputType) IsSplitRoot ¶
func (t VOutputType) IsSplitRoot() bool
IsSplitRoot returns true if the output type is a split root, indicating that the asset has a tx witness instead of a split witness.
func (VOutputType) String ¶
func (t VOutputType) String() string
String returns a human-readable string representation of the output type.
type VPacket ¶
type VPacket struct { // Inputs is the list of asset inputs that are being spent. Inputs []*VInput // Outputs is the list of new asset outputs that are created by the // virtual transaction. Outputs []*VOutput // ChainParams are the Taproot Asset chain parameters that are used to // encode and decode certain contents of the virtual packet. ChainParams *address.ChainParams // Version is the version of the virtual transaction. This is currently // unused but can be used to signal a new version of the virtual PSBT // format in the future. Version uint8 }
VPacket is a PSBT extension packet for a virtual transaction. It represents the virtual asset state transition as it will be validated by the Taproot Asset VM. Some elements within the virtual packet may refer to on-chain elements (such as the anchor BTC transaction that was used to anchor the input that is spent). But in general a virtual transaction does NOT directly map onto a BTC transaction. It is entirely possible that multiple virtual transactions will be merged into a single BTC transaction. Thus, each asset state transfer is represented in a virtual TX and multiple asset state transfers can be anchored within a single BTC transaction.
NOTE: A virtual transaction only carries the asset state transition for a single asset ID. If multiple inputs are given, they must all belong to the same asset ID (which means those asset UTXOs are being merged and possibly split again in this virtual transaction). Therefore, if an anchor output carries commitments for multiple assets, a virtual transaction needs to be created, signed and then anchored for each asset ID separately.
TODO(guggero): Actually support merging multiple virtual transactions into a single BTC transaction.
func ForInteractiveSend ¶
func ForInteractiveSend(id asset.ID, amount uint64, scriptAddr asset.ScriptKey, outputIndex uint32, anchorInternalKey keychain.KeyDescriptor, assetVersion asset.Version, chainParams *address.ChainParams) *VPacket
ForInteractiveSend creates a virtual transaction packet for sending an output to a receiver in an interactive manner. Only one, interactive output is created. If the amount is not the full input amount, a change output will be added by the funding API.
func NewFromPsbt ¶
NewFromPsbt returns a new instance of a VPacket struct created by reading the custom fields on the given PSBT packet.
func NewFromRawBytes ¶
NewFromRawBytes returns a new instance of a VPacket 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.
func OwnershipProofPacket ¶
func OwnershipProofPacket(ownedAsset *asset.Asset, chainParams *address.ChainParams) *VPacket
OwnershipProofPacket creates a virtual transaction packet that is used to prove ownership of an asset. It creates a 1-in-1-out transaction that spends the owned asset to the NUMS key. The witness is created over an empty previous outpoint, so it can never be used in an actual state transition.
func RandPacket ¶
RandPacket generates a random virtual packet for testing purposes.
func (*VPacket) B64Encode ¶
B64Encode returns the base64 encoding of the serialization of the current virtual packet, or an error if the encoding fails.
func (*VPacket) EncodeAsPsbt ¶
EncodeAsPsbt returns the PSBT encoding of the current virtual packet, or an error if the encoding fails.
func (*VPacket) FirstInteractiveOutput ¶
FirstInteractiveOutput returns the first interactive output in the virtual transaction.
func (*VPacket) FirstNonSplitRootOutput ¶
FirstNonSplitRootOutput returns the first non-change output in the virtual transaction.
func (*VPacket) HasInteractiveOutput ¶
HasInteractiveOutput determines if this virtual transaction has an interactive output.
func (*VPacket) HasSplitCommitment ¶
HasSplitCommitment determines if this transaction results in an asset split. This is either the case if the value of the input asset is split or if one of the outputs is non-interactive (in which case we need to have a zero value tombstone asset in the change output).
func (*VPacket) HasSplitRootOutput ¶
HasSplitRootOutput determines if this virtual transaction has a split root output.
func (*VPacket) PassiveAssetsOutput ¶ added in v0.3.0
PassiveAssetsOutput returns the output in the virtual transaction that can carry passive assets, or an error if there is none or more than one.
func (*VPacket) Serialize ¶
Serialize creates a binary serialization of the referenced VPacket struct with lexicographical ordering (by key) of the subsections.
func (*VPacket) SetInputAsset ¶
SetInputAsset sets the input asset that is being spent.
func (*VPacket) SplitRootOutput ¶
SplitRootOutput returns the split root output in the virtual transaction, or an error if there is none or more than one.
type ValidTestCase ¶ added in v0.3.0
type ValidTestCase struct { Packet *TestVPacket `json:"packet"` Expected string `json:"expected"` Comment string `json:"comment"` }