Documentation
¶
Index ¶
- Constants
- Variables
- func AreValidIndexes(locators SpendLocators) (bool, error)
- func CreateSpendOutputs(addr address.Taro, locators SpendLocators, ...) error
- func CreateTemplatePsbt(locators SpendLocators) (*psbt.Packet, error)
- func InputAssetPrevOut(prevAsset asset.Asset) (*wire.TxOut, error)
- func InputKeySpendSigHash(virtualTx *wire.MsgTx, input *asset.Asset, idx uint32) ([]byte, error)
- func InputPrevOutFetcher(prevAsset asset.Asset) (*txscript.CannedPrevOutputFetcher, error)
- func InputScriptSpendSigHash(virtualTx *wire.MsgTx, input *asset.Asset, idx uint32, ...) ([]byte, error)
- func IsValidInput(input *commitment.TaroCommitment, addr address.Taro, ...) (*asset.Asset, bool, error)
- func PayToAddrScript(internalKey btcec.PublicKey, sibling *chainhash.Hash, ...) ([]byte, error)
- func PayToTaprootScript(taprootKey *btcec.PublicKey) ([]byte, error)
- func SignTaprootKeySpend(internalKey btcec.PublicKey, virtualTx *wire.MsgTx, inputAsset *asset.Asset, ...) (*wire.TxWitness, error)
- func VirtualTx(newAsset *asset.Asset, prevAssets commitment.InputSet) (*wire.MsgTx, mssmt.Tree, error)
- func VirtualTxWithInput(virtualTx *wire.MsgTx, input *asset.Asset, idx uint32, witness wire.TxWitness) *wire.MsgTx
- type MockSigner
- type Signer
- type SpendCommitments
- type SpendDelta
- func CompleteAssetSpend(internalKey btcec.PublicKey, prevInput asset.PrevID, delta SpendDelta, ...) (*SpendDelta, error)
- func PrepareAssetCompleteSpend(addr address.Taro, prevInput asset.PrevID, delta SpendDelta) *SpendDelta
- func PrepareAssetSplitSpend(addr address.Taro, prevInput asset.PrevID, scriptKey btcec.PublicKey, ...) (*SpendDelta, error)
- type SpendLocators
- type TxValidator
Constants ¶
const ( // DummyAmtSats is the default amount of sats we'll use in Bitcoin // outputs embedding Taro commitments. This value just needs to be // greater than dust, and we assume that this value is updated to match // the input asset bearing UTXOs before finalizing the transfer TX. DummyAmtSats = btcutil.Amount(1_000) // SendConfTarget is the confirmation target we'll use to query for // a fee estimate. SendConfTarget = 6 )
Variables ¶
var ( // ErrMissingInputAsset is an error returned when we attempt to spend // to a Taro address from an input that does not contain // the matching asset. ErrMissingInputAsset = errors.New( "send: Input does not contain requested asset", ) // ErrInsufficientInputAsset is an error returned when we attempt // to spend to a Taro address from an input that contains // insufficient asset funds. ErrInsufficientInputAsset = errors.New( "send: Input asset value is insufficient", ) // ErrInvalidOutputIndexes is an error returned when we attempt to spend // to Bitcoin output indexes that do not start at 0 or // are not continuous. ErrInvalidOutputIndexes = errors.New( "send: Output indexes not starting at 0 and continuous", ) // ErrMissingSplitAsset is an error returned when we attempt to look up // a split asset in a map and the specified asset is not found. ErrMissingSplitAsset = errors.New( "send: split asset not found", ) // ErrMissingAssetCommitment is an error returned when we attempt to // look up an Asset commitment in a map and the specified commitment // is not found. ErrMissingAssetCommitment = errors.New( "send: Asset commitment not found", ) // ErrMissingTaroCommitment is an error returned when we attempt to // look up a Taro commitment in a map and the specified commitment // is not found. ErrMissingTaroCommitment = errors.New( "send: Taro commitment not found", ) )
var ( // ErrNoInputs represents an error case where an asset undergoing a // state transition does not have any or a specific input required. ErrNoInputs = errors.New("missing asset input(s)") // ErrInputMismatch represents an error case where an asset's set of // inputs mismatch the set provided to the virtual machine. ErrInputMismatch = errors.New("asset input(s) mismatch") // ErrInvalidScriptVersion represents an error case where an asset input // commits to an invalid script version. ErrInvalidScriptVersion = errors.New("invalid script version") )
Functions ¶
func AreValidIndexes ¶
func AreValidIndexes(locators SpendLocators) (bool, error)
AreValidIndexes checks a set of split locators to check for the minimum number of locators, and tests if the locators could be used for a Taro-only spend, i.e. a TX that does not need other outputs added to be valid.
func CreateSpendOutputs ¶
func CreateSpendOutputs(addr address.Taro, locators SpendLocators, internalKey, scriptKey btcec.PublicKey, commitments SpendCommitments, pkt *psbt.Packet) error
CreateSpendOutputs updates a PSBT with outputs embedding TaroCommitments involved in an asset send. The sender must attach the Bitcoin input holding the corresponding Taro input asset to this PSBT before finalizing the TX. Locators MUST be checked beforehand.
func CreateTemplatePsbt ¶
func CreateTemplatePsbt(locators SpendLocators) (*psbt.Packet, error)
Build a template TX with dummy outputs TODO(jhb): godoc
func InputAssetPrevOut ¶
InputAssetPrevOut returns a TxOut that represents the input asset in a Taro virtual TX.
func InputKeySpendSigHash ¶
InputKeySpendSigHash returns the signature hash of a virtual transaction for a specific Taro input that can be spent through the key path. This is the message over which signatures are generated over.
func InputPrevOutFetcher ¶
func InputPrevOutFetcher(prevAsset asset.Asset) (*txscript.CannedPrevOutputFetcher, error)
InputPrevOutFetcher returns a Taro input's `PrevOutFetcher` to be used throughout signing.
func InputScriptSpendSigHash ¶
func InputScriptSpendSigHash(virtualTx *wire.MsgTx, input *asset.Asset, idx uint32, tapLeaf *txscript.TapLeaf) ([]byte, error)
InputScriptSpendSigHash returns the signature hash of a virtual transaction for a specific Taro input that can be spent through the script path. This is the message over which signatures are generated over.
func IsValidInput ¶
func IsValidInput(input *commitment.TaroCommitment, addr address.Taro, inputScriptKey btcec.PublicKey, net address.ChainParams) (*asset.Asset, bool, error)
IsValidInput verifies that the Taro commitment of the input contains an asset that could be spent to the given Taro address.
func PayToAddrScript ¶
func PayToAddrScript(internalKey btcec.PublicKey, sibling *chainhash.Hash, commitment commitment.TaroCommitment) ([]byte, error)
PayToAddrScript constructs a P2TR script that embeds a Taro commitment by tweaking the receiver key by a Tapscript tree that contains the Taro commitment root. The Taro commitment must be reconstructed by the receiver, and they also need to Tapscript sibling hash used here if present.
func PayToTaprootScript ¶
PayToTaprootScript creates a pk script for a pay-to-taproot output key.
func SignTaprootKeySpend ¶
func SignTaprootKeySpend(internalKey btcec.PublicKey, virtualTx *wire.MsgTx, inputAsset *asset.Asset, idx int, txSigner Signer) (*wire.TxWitness, error)
SignTaprootKeySpend computes a signature over a Taro virtual transaction spending a Taro input through the key path, following BIP 86. This signature is attached to a Taro output asset before state transition validation.
func VirtualTx ¶
func VirtualTx(newAsset *asset.Asset, prevAssets commitment.InputSet) ( *wire.MsgTx, mssmt.Tree, error)
VirtualTx constructs the virtual transaction that enables the movement of an asset representing an asset state transition.
func VirtualTxWithInput ¶
func VirtualTxWithInput(virtualTx *wire.MsgTx, input *asset.Asset, idx uint32, witness wire.TxWitness) *wire.MsgTx
VirtualTxWithInput returns a copy of the `virtualTx` amended to include all input-specific details.
This is used to further bind a given witness to the "true" input it spends. We'll use the index of the serialized input to bind the prev index, which represents the "leaf index" of the virtual input MS-SMT.
Types ¶
type MockSigner ¶
type MockSigner struct {
PrivKey *btcec.PrivateKey
}
func NewMockSigner ¶
func NewMockSigner(privKey *btcec.PrivateKey) *MockSigner
func (*MockSigner) SignOutputRaw ¶
func (m *MockSigner) SignOutputRaw(tx *wire.MsgTx, signDesc *input.SignDescriptor) (*schnorr.Signature, error)
SignOutputRaw creates a signature for a single input. Taken from lnd/lnwallet/btcwallet/signer:L344, SignOutputRaw
func (*MockSigner) SignVirtualTx ¶
func (m *MockSigner) SignVirtualTx(signDesc *lndclient.SignDescriptor, tx *wire.MsgTx, prevOut *wire.TxOut) (*schnorr.Signature, error)
type Signer ¶
type Signer interface { // SignVirtualTx generates a signature according to the passed signing // descriptor and TX. // // NOTE: We currently assume the signature requested is for the/ BIP 86 // spending type. SignVirtualTx(signDesc *lndclient.SignDescriptor, tx *wire.MsgTx, prevOut *wire.TxOut) (*schnorr.Signature, error) }
Signer is the interface used to compute the witness for a Taro virtual TX.
type SpendCommitments ¶
type SpendCommitments = map[[32]byte]commitment.TaroCommitment
SpendCommitments stores the Taro commitment for each receiver (including the sender), which is needed to create the final PSBT for the transfer.
func CreateSpendCommitments ¶
func CreateSpendCommitments(inputCommitment *commitment.TaroCommitment, prevInput asset.PrevID, spend SpendDelta, addr address.Taro, senderScriptKey btcec.PublicKey) (SpendCommitments, error)
CreateSpendCommitments creates the final set of TaroCommitments representing the asset send. The input TaroCommitment must become a valid change commitment by removing the input asset and adding the root split asset if present. The receiver TaroCommitment must include the output asset.
type SpendDelta ¶
type SpendDelta struct { // NewAsset is the Asset that will be validated by the Taro VM. // In the case of an asset split, it is the root locator that also // contains the split commitment. Otherwise, it is the asset that will // be sent to the receiver. NewAsset asset.Asset // InputAssets maps asset PrevIDs to Assets being spent by the sender. InputAssets commitment.InputSet // Locators maps AssetCommitmentKeys for all receivers to splitLocators. // The locators are used to create split commitments, and store indexes // for each receiver's corresponding Bitcoin output. Locators SpendLocators // NOTE: This is nil unless the InputAsset is being split. SplitCommitment *commitment.SplitCommitment }
SpendDelta stores the information needed to prepare new asset leaves or a split commitment, and validated a spend with the Taro VM. SpendDelta is also used to create the final TaroCommitments for each receiver.
func CompleteAssetSpend ¶
func CompleteAssetSpend(internalKey btcec.PublicKey, prevInput asset.PrevID, delta SpendDelta, signer Signer, validator TxValidator) (*SpendDelta, error)
CompleteAssetSpend updates the new Asset by creating a signature over the asset transfer, verifying the transfer with the Taro VM, and attaching that signature to the new Asset.
func PrepareAssetCompleteSpend ¶
func PrepareAssetCompleteSpend(addr address.Taro, prevInput asset.PrevID, delta SpendDelta) *SpendDelta
PrepareAssetCompleteSpend computes a new asset leaf for spends that fully consume the input, i.e. collectibles or an equal-valued send. Input MUST be checked as valid beforehand.
func PrepareAssetSplitSpend ¶
func PrepareAssetSplitSpend(addr address.Taro, prevInput asset.PrevID, scriptKey btcec.PublicKey, delta SpendDelta) (*SpendDelta, error)
PrepareAssetSplitSpend computes a split commitment with the given input and spend information. Input MUST be checked as valid beforehand, and locators MUST be checked for validity beforehand if provided.
TODO(jhb): This assumes only 2 split outputs / 1 receiver; needs update to support multiple receivers.
func (*SpendDelta) Copy ¶
func (s *SpendDelta) Copy() SpendDelta
Copy returns a deep copy of a SpendDelta.
type SpendLocators ¶
type SpendLocators = map[[32]byte]commitment.SplitLocator
SpendLocators stores a split locators for each receiver, keyed by their AssetCommitmentKey. These locators are used to create split commitments and the final PSBT for the transfer. AssetCommitmentKeys are unique to each asset and each receiver due to the inclusion of the receiver's ScriptKey.
func CreateDummyLocators ¶
func CreateDummyLocators(stateKeys [][32]byte) SpendLocators
CreateDummyLocators creates a set of split locators with continuous output indexes, starting for 0. These mock locators are used for initial split commitment validation, and are the default for the final PSBT.
type TxValidator ¶
type TxValidator interface { // Execute creates an instance of the Taro VM and validates // an asset transfer, including the attached witnesses. Execute(newAsset *asset.Asset, splitAsset *commitment.SplitAsset, prevAssets commitment.InputSet) error }
TxValidator is the interface used to validate an asset transfer with the Taro VM.