commitment

package
v0.1.1-alpha Latest Latest
Warning

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

Go to latest
Published: Nov 9, 2022 License: MIT Imports: 16 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoAssets is an error returned when we attempt to instantiate a new
	// AssetCommitment without any assets.
	ErrNoAssets = errors.New("asset commitment: no assets provided")

	// ErrAssetGenesisMismatch is an error returned when we attempt to
	// create a new asset commitment and two assets disagree on their
	// genesis.
	ErrAssetGenesisMismatch = errors.New(
		"asset commitment: genesis mismatch",
	)

	// ErrAssetFamilyKeyMismatch is an error returned when we attempt to
	// create a new asset commitment and two assets disagree on their
	// family key.
	ErrAssetFamilyKeyMismatch = errors.New(
		"asset commitment: family key mismatch",
	)

	// ErrAssetDuplicateScriptKey is an error returned when we attempt to
	// create a new asset commitment that would include two assets with the
	// same script key.
	ErrAssetDuplicateScriptKey = errors.New(
		"asset commitment: duplicate script key",
	)

	// ErrAssetGenesisInvalidSig is an error returned when we attempt to
	// create a new asset commitment from a genesis with an invalid
	// signature with their family key.
	ErrAssetGenesisInvalidSig = errors.New(
		"asset commitment: invalid genesis signature",
	)
)
View Source
var (
	// ErrDuplicateSplitOutputIndex is an error returned when duplicate
	// split output indices are detected.
	ErrDuplicateSplitOutputIndex = errors.New(
		"found locator with duplicate output index",
	)

	// ErrInvalidSplitAmount is an error returned when a set of splits does
	// not fully consume the asset inputs.
	ErrInvalidSplitAmount = errors.New(
		"splits do not fully consume asset input amount",
	)

	// ErrInvalidSplitLocator is returned if a new split is attempted to be
	// created w/o a valid external split locator.
	ErrInvalidSplitLocator = errors.New(
		"at least one locator should be specified",
	)

	// ErrInvalidSplitLocatorCount is returned if a collectible split is
	// attempted with a count of external split locators not equal to one.
	ErrInvalidSplitLocatorCount = errors.New(
		"exactly one locator should be specified",
	)

	// ErrInvalidScriptKey is an error returned when a root locator has zero
	// value but does not use the correct unspendable script key.
	ErrInvalidScriptKey = errors.New(
		"invalid script key for zero-amount locator",
	)

	// ErrZeroSplitAmount is an error returned when a non-root split locator
	// has zero amount.
	ErrZeroSplitAmount = errors.New(
		"split locator has zero amount",
	)

	// ErrNonZeroSplitAmount is an error returned when a root locator uses
	// an unspendable script key but has a non-zero amount.
	ErrNonZeroSplitAmount = errors.New(
		"unspendable root locator has non-zero amount",
	)
)
View Source
var (
	// ErrMissingAssetProof is an error returned when attempting to derive a
	// TaroCommitment and an AssetProof is required but missing.
	ErrMissingAssetProof = errors.New("missing asset proof")
)
View Source
var (
	// TaroMarker is a static identifier included in the leaf script of a
	// Taro commitment to uniquely identify from any other leaves in the
	// tapscript tree.
	TaroMarker = sha256.Sum256([]byte(taroMarkerTag))
)

Functions

This section is empty.

Types

type AssetCommitment

type AssetCommitment struct {
	// Version is the max version of the assets committed.
	Version asset.Version

	// AssetID is the common identifier for all assets found within the
	// AssetCommitment. This can either be an asset.ID, which every
	// committed asset must match, or the hash of an asset.FamilyKey which
	// every committed asset must match if their asset.ID differs.
	AssetID [32]byte

	// TreeRoot is the root node of the MS-SMT containing all of the
	// committed assets.
	TreeRoot *mssmt.BranchNode
	// contains filtered or unexported fields
}

AssetCommitment represents the inner MS-SMT within the Taro protocol committing to a set of assets under the same ID/family. Assets within this tree, which are leaves represented as the serialized asset TLV payload, are keyed by their `asset_script_key`.

func NewAssetCommitment

func NewAssetCommitment(assets ...*asset.Asset) (*AssetCommitment, error)

NewAssetCommitment constructs a new commitment for the given assets capable of computing merkle proofs. All assets provided should be related, i.e., their `ID` or `FamilyKey` should match.

func (*AssetCommitment) AssetProof

func (c *AssetCommitment) AssetProof(key [32]byte) (
	*asset.Asset, *mssmt.Proof, error)

AssetProof computes the AssetCommitment merkle proof for the asset leaf located at `key`. A `nil` asset is returned if the asset is not committed to.

func (*AssetCommitment) Assets

func (c *AssetCommitment) Assets() CommittedAssets

Assets returns the set of assets committed to in the asset commitment.

func (*AssetCommitment) Copy

func (c *AssetCommitment) Copy() (*AssetCommitment, error)

Copy returns a deep copy of tha target AssetCommitment.

func (*AssetCommitment) Root

func (c *AssetCommitment) Root() [sha256.Size]byte

Root computes the root identifier required to commit to this specific asset commitment within the outer commitment, also known as the Taro commitment.

func (*AssetCommitment) TaroCommitmentKey

func (c *AssetCommitment) TaroCommitmentKey() [32]byte

TaroCommitmentKey computes the insertion key for this specific asset commitment to include in the Taro commitment MS-SMT.

func (*AssetCommitment) TaroCommitmentLeaf

func (c *AssetCommitment) TaroCommitmentLeaf() *mssmt.LeafNode

TaroCommitmentLeaf computes the leaf node for this specific asset commitment to include in the Taro commitment MS-SMT.

func (*AssetCommitment) Update

func (c *AssetCommitment) Update(asset *asset.Asset, deletion bool) error

Update modifies one entry in the AssetCommitment by inserting or deleting it in the inner MS-SMT and adding or deleting it in the internal asset map.

type AssetCommitments

type AssetCommitments map[[32]byte]*AssetCommitment

AssetCommitments is the set of assetCommitments backing a TaroCommitment. The map is keyed by the AssetCommitment's TaroCommitmentKey.

type AssetDetails

type AssetDetails struct {
	// Type is the type of asset to mint.
	Type asset.Type

	// ScriptKey is the Taproot key with ownership of the asset.
	ScriptKey keychain.KeyDescriptor

	// Amount is the amount of assets that should be minted for `ScriptKey`.
	// NOTE: This should be nil when minting `Collectible` assets.
	Amount *uint64

	// LockTime is the earliest height in the blockchain at which the
	// asset(s) to mint can be spent from `ScriptKey`.
	LockTime uint64

	// RelativeLockTime is the number of blocks after the on-chain
	// confirmation height in the blockchain at which the asset(s) to mint
	// can be spent from `ScriptKey`.
	RelativeLockTime uint64
}

AssetDetails contains all of the configurable parameters of an Asset to specify upon mint.

type AssetProof

type AssetProof struct {
	mssmt.Proof

	// Version is the max version of the assets committed.
	Version asset.Version

	// AssetID is the common identifier for all assets found within the
	// AssetCommitment. This can either be an asset.ID, which every
	// committed asset must match, otherwise an asset.FamilyKey which every
	// committed asset must match.
	AssetID [32]byte
}

AssetProof is the proof used along with an asset leaf to arrive at the root of the AssetCommitment MS-SMT.

type CommittedAssets

type CommittedAssets map[[32]byte]*asset.Asset

CommittedAssets is the set of Assets backing an AssetCommitment. The map is keyed by the Asset's AssetCommitmentKey.

type InputSet

type InputSet map[asset.PrevID]*asset.Asset

InputSet represents the set of inputs for a given asset indexed by their `PrevID`.

type Proof

type Proof struct {
	// AssetProof is the proof used along with the asset to arrive at the
	// root of the AssetCommitment MS-SMT.
	//
	// NOTE: This proof must be nil if the asset commitment for this
	// particular asset is not found within the Taro commitment. In this
	// case, the TaroProof below would be a non-inclusion proof of the asset
	// commitment.
	AssetProof *AssetProof

	// TaroProof is the proof used along with the asset commitment to arrive
	// at the root of the TaroCommitment MS-SMT.
	TaroProof TaroProof
}

Proof represents a full commitment proof for a particular `Asset`. It proves that an asset does or does not exist within a Taro commitment.

func (Proof) DeriveByAssetCommitmentExclusion

func (p Proof) DeriveByAssetCommitmentExclusion(taroCommitmentKey [32]byte) (
	*TaroCommitment, error)

DeriveByAssetCommitmentExclusion derives the Taro commitment excluding the given asset commitment identified by its key within a TaroCommitment. This consists of proving with the TaroProof that an AssetCommitment does not exist within the outer MS-SMT, also known as the TaroCommitment.

func (Proof) DeriveByAssetExclusion

func (p Proof) DeriveByAssetExclusion(assetCommitmentKey [32]byte) (
	*TaroCommitment, error)

DeriveByAssetExclusion derives the Taro commitment excluding the given asset identified by its key within an AssetCommitment. This consists of proving with the AssetProof that an asset does not exist within the inner MS-SMT, also known as the AssetCommitment. With the AssetCommitment obtained, the TaroProof is used to prove that the AssetCommitment exists within the outer MS-SMT, also known as the TaroCommitment.

func (Proof) DeriveByAssetInclusion

func (p Proof) DeriveByAssetInclusion(asset *asset.Asset) (*TaroCommitment,
	error)

DeriveByAssetInclusion derives the Taro commitment containing the provided asset. This consists of proving that an asset exists within the inner MS-SMT with the AssetProof, also known as the AssetCommitment. With the AssetCommitment obtained, the TaroProof is used to prove that it exists or within the outer MS-SMT, also known as the TaroCommitment.

type SplitAsset

type SplitAsset struct {
	asset.Asset

	// OutputIndex is the index of the on-chain transaction that held the
	// split asset at the time of its creation.
	OutputIndex uint32
}

SplitAsset is an asset resulting from a split. This is the same as the underlying asset, except it also encodes its `OutputIndex`.

type SplitCommitment

type SplitCommitment struct {
	// PrevAssets is the set of asset inputs being split.
	PrevAssets InputSet

	// RootAsset is the root asset resulting after the creation of split
	// assets containing the SplitCommitmentRoot.
	RootAsset *asset.Asset

	// SplitAssets is the set of asset splits within the on-chain
	// transaction committed to within the split commitment MS-SMT.
	SplitAssets SplitSet
	// contains filtered or unexported fields
}

SplitCommitment encodes all of the data necessary to generate and validate a set of asset splits from its root.

func NewSplitCommitment

func NewSplitCommitment(input *asset.Asset, outPoint wire.OutPoint,
	rootLocator *SplitLocator, externalLocators ...*SplitLocator) (
	*SplitCommitment, error)

NewSplitCommitment computes a new SplitCommitment based on the given asset input creating a set of asset splits uniquely identified by their `locators`. The resulting asset splits are committed to within a MS-SMT and its root is placed within the root asset, which should have a signature over the split state transition to authenticate the transfer. This signature on the root asset needs to be provided after the fact. The rootLocator field is considered to be the "change" output in the transfer: this is the location where all the other splits (elsewhere in the transaction are committed to).

TODO: Is it allowed to merge several assets to create a split within a single state transition? Imagine 3 separate UTXOs containing 5 USD each and merged to create a split payment of 7 USD in one UTXO for the recipient and a change UTXO of 8 USD.

type SplitLocator

type SplitLocator struct {
	// OutputIndex is the output index of the on-chain transaction which
	// the asset split was sent to.
	OutputIndex uint32

	// AssetID is the unique ID of the asset.
	AssetID asset.ID

	// ScriptKey is the Taproot tweaked key encoding the different spend
	// conditions possible for the asset split.
	ScriptKey asset.SerializedKey

	// Amount is the amount of units for the asset split.
	Amount uint64
}

SplitLocator encodes the data that uniquely identifies an asset split within a split commitment tree.

func (SplitLocator) Hash

func (l SplitLocator) Hash() [sha256.Size]byte

Hash computes the hash of a SplitLocator, encumbering its `OutputIndex`, `AssetID` and `ScriptKey`. This hash is used as the key for the asset split within a split commitment tree.

type SplitSet

type SplitSet map[SplitLocator]*SplitAsset

SplitSet is a type to represent a set of asset splits.

type TaroCommitment

type TaroCommitment struct {
	// Version is the maximum Taro asset version found within all of the
	// assets committed.
	Version asset.Version

	// TreeRoot is the root node of the MS-SMT containing all of the asset
	// commitments.
	TreeRoot *mssmt.BranchNode
	// contains filtered or unexported fields
}

TaroCommitment represents the outer MS-SMT within the Taro protocol committing to a set of asset commitments. Asset commitments, which are leaves represented as `asset_version || asset_tree_root || asset_sum`, are keyed by their `asset_family_key` or `asset_id` otherwise.

func Mint

func Mint(genesis asset.Genesis, familyKey *asset.FamilyKey,
	details ...*AssetDetails) (*TaroCommitment, []*asset.Asset, error)

Mint mints a series of assets within a new Taro commitment. The distribution and other parameters of these assets can be specified through `AssetDetails`.

func NewTaroCommitment

func NewTaroCommitment(assets ...*AssetCommitment) (*TaroCommitment, error)

NewTaroCommitment creates a new Taro commitment for the given asset commitments capable of computing merkle proofs.

func NewTaroCommitmentWithRoot

func NewTaroCommitmentWithRoot(version asset.Version,
	root *mssmt.BranchNode) *TaroCommitment

NewTaroCommitmentWithRoot creates a new Taro commitment backed by the root node. The resulting commitment will not be able to compute merkle proofs as it only knows of the tree's root node, and not the tree itself.

func (*TaroCommitment) Commitments

func (c *TaroCommitment) Commitments() AssetCommitments

Commitments returns the set of assetCommitments committed to in the taro commitment.

func (*TaroCommitment) CommittedAssets

func (c *TaroCommitment) CommittedAssets() []*asset.Asset

CommittedAssets returns the set of assets committed to in the taro commitment.

func (*TaroCommitment) Copy

func (c *TaroCommitment) Copy() (*TaroCommitment, error)

Copy performs a deep copy of the passed Taro commitment.

func (*TaroCommitment) Proof

func (c *TaroCommitment) Proof(taroCommitmentKey,
	assetCommitmentKey [32]byte) (*asset.Asset, *Proof, error)

Proof computes the full TaroCommitment merkle proof for the asset leaf located at `assetCommitmentKey` within the AssetCommitment located at `taroCommitmentKey`.

func (*TaroCommitment) TapLeaf

func (c *TaroCommitment) TapLeaf() txscript.TapLeaf

TapLeaf constructs a new `TapLeaf` for this `TaroCommitment`.

func (*TaroCommitment) TapscriptRoot

func (c *TaroCommitment) TapscriptRoot(sibling *chainhash.Hash) chainhash.Hash

TapscriptRoot returns the tapscript root for this TaroCommitment. If `sibling` is not nil, we assume it is a valid sibling (e.g., not a duplicate Taro commitment), and hash it with the Taro commitment leaf to arrive at the tapscript root, otherwise the Taro commitment leaf itself becomes the tapscript root.

func (*TaroCommitment) Update

func (c *TaroCommitment) Update(asset *AssetCommitment, deletion bool) error

Update modifies one entry in the TaroCommitment by inserting or deleting it in the inner MS-SMT and adding or deleting it in the internal AssetCommitment map.

type TaroProof

type TaroProof struct {
	mssmt.Proof

	// Version is the max version committed of the AssetCommitment's
	// included in the TaroCommitment.
	Version asset.Version
}

TaroProof is the proof used along with an asset commitment leaf to arrive at the root of the TaroCommitment MS-SMT.

Jump to

Keyboard shortcuts

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