asset

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: 21 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ZeroPrevID is the blank prev ID used for genesis assets and also
	// asset split leaves.
	ZeroPrevID PrevID

	// NUMSBytes is the NUMs point we'll use for unspendable script keys.
	// It was generated via a try-and-increment approach using the phrase
	// "taro" with SHA2-256. The code for the try-and-increment approach
	// can be seen here:
	// https://github.com/lightninglabs/lightning-node-connect/tree/master/mailbox/numsgen
	NUMSBytes, _ = hex.DecodeString(
		"0293bfe90658c79b480114ff6bbeda51b3ec6412deb367a4d41e1403e3cc" +
			"6583ed",
	)
	NUMSPubKey, _     = btcec.ParsePubKey(NUMSBytes)
	NUMSCompressedKey = ToSerialized(NUMSPubKey)
	NUMSScriptKey     = ScriptKey{
		PubKey: NUMSPubKey,
		TweakedScriptKey: &TweakedScriptKey{
			RawKey: keychain.KeyDescriptor{
				PubKey: NUMSPubKey,
			},
		},
	}
)
View Source
var (
	// ErrTooManyInputs is returned when an asset TLV atempts to reference
	// too many inputs.
	ErrTooManyInputs = errors.New("witnesses: witness elements")

	// ErrByteSliceTooLarge is returned when an encoded byte slice is too
	// large.
	ErrByteSliceTooLarge = errors.New("bytes: too large")
)

Functions

func AssetCommitmentKey

func AssetCommitmentKey(assetID ID, scriptKey *btcec.PublicKey,
	issuanceDisabled bool) [32]byte

AssetCommitmentKey is the key that maps to a specific owner of an asset within a Taro AssetCommitment.

NOTE: This function is also used outside the asset package.

func CompressedPubKeyDecoder

func CompressedPubKeyDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func CompressedPubKeyEncoder

func CompressedPubKeyEncoder(w io.Writer, val any, buf *[8]byte) error

func EqualKeyDescriptors

func EqualKeyDescriptors(a, o keychain.KeyDescriptor) bool

EqualKeyDescriptors returns true if the two key descriptors are equal.

func FamilyKeyDecoder

func FamilyKeyDecoder(r io.Reader, val any, buf *[8]byte, _ uint64) error

func FamilyKeyEncoder

func FamilyKeyEncoder(w io.Writer, val any, buf *[8]byte) error

func GenesisDecoder

func GenesisDecoder(r io.Reader, val any, buf *[8]byte, _ uint64) error

func GenesisEncoder

func GenesisEncoder(w io.Writer, val any, buf *[8]byte) error

func IDDecoder

func IDDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func IDEncoder

func IDEncoder(w io.Writer, val any, buf *[8]byte) error

func NewLeafAmountRecord

func NewLeafAmountRecord(amount *uint64) tlv.Record

func NewLeafFamilyKeyOnlyRecord

func NewLeafFamilyKeyOnlyRecord(familyKey **btcec.PublicKey) tlv.Record

func NewLeafFamilyKeyRecord

func NewLeafFamilyKeyRecord(familyKey **FamilyKey) tlv.Record

func NewLeafGenesisRecord

func NewLeafGenesisRecord(genesis *Genesis) tlv.Record

func NewLeafIDRecord

func NewLeafIDRecord(id *[sha256.Size]byte) tlv.Record

func NewLeafLockTimeRecord

func NewLeafLockTimeRecord(lockTime *uint64) tlv.Record

func NewLeafPrevWitnessRecord

func NewLeafPrevWitnessRecord(prevWitnesses *[]Witness) tlv.Record

func NewLeafRelativeLockTimeRecord

func NewLeafRelativeLockTimeRecord(relativeLockTime *uint64) tlv.Record

func NewLeafScriptKeyRecord

func NewLeafScriptKeyRecord(scriptKey **btcec.PublicKey) tlv.Record

func NewLeafScriptVersionRecord

func NewLeafScriptVersionRecord(version *ScriptVersion) tlv.Record

func NewLeafSplitCommitmentRootRecord

func NewLeafSplitCommitmentRootRecord(root *mssmt.Node) tlv.Record

func NewLeafTypeRecord

func NewLeafTypeRecord(assetType *Type) tlv.Record

func NewLeafVersionRecord

func NewLeafVersionRecord(version *Version) tlv.Record

func NewWitnessPrevIDRecord

func NewWitnessPrevIDRecord(prevID **PrevID) tlv.Record

func NewWitnessSplitCommitmentRecord

func NewWitnessSplitCommitmentRecord(commitment **SplitCommitment) tlv.Record

func NewWitnessTxWitnessRecord

func NewWitnessTxWitnessRecord(witness *wire.TxWitness) tlv.Record

func OutPointDecoder

func OutPointDecoder(r io.Reader, val any, buf *[8]byte, _ uint64) error

func OutPointEncoder

func OutPointEncoder(w io.Writer, val any, buf *[8]byte) error

func PrevIDDecoder

func PrevIDDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func PrevIDEncoder

func PrevIDEncoder(w io.Writer, val any, buf *[8]byte) error

func SchnorrSignatureDecoder

func SchnorrSignatureDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func SchnorrSignatureEncoder

func SchnorrSignatureEncoder(w io.Writer, val any, buf *[8]byte) error

func ScriptVersionDecoder

func ScriptVersionDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func ScriptVersionEncoder

func ScriptVersionEncoder(w io.Writer, val any, buf *[8]byte) error

func SerializedKeyDecoder

func SerializedKeyDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func SerializedKeyEncoder

func SerializedKeyEncoder(w io.Writer, val any, buf *[8]byte) error

func SplitCommitmentDecoder

func SplitCommitmentDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func SplitCommitmentEncoder

func SplitCommitmentEncoder(w io.Writer, val any, buf *[8]byte) error

func SplitCommitmentRootDecoder

func SplitCommitmentRootDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func SplitCommitmentRootEncoder

func SplitCommitmentRootEncoder(w io.Writer, val any, buf *[8]byte) error

func TaroCommitmentKey

func TaroCommitmentKey(assetID ID, familyKey *btcec.PublicKey) [32]byte

TaroCommitmentKey is the key that maps to the root commitment for a specific asset family within a TaroCommitment.

NOTE: This function is also used outside the asset package.

func TxWitnessDecoder

func TxWitnessDecoder(r io.Reader, val any, buf *[8]byte, _ uint64) error

func TxWitnessEncoder

func TxWitnessEncoder(w io.Writer, val any, buf *[8]byte) error

func TypeDecoder

func TypeDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func TypeEncoder

func TypeEncoder(w io.Writer, val any, buf *[8]byte) error

func VarBytesDecoder

func VarBytesDecoder(r io.Reader, val any, buf *[8]byte, _ uint64) error

func VarBytesEncoder

func VarBytesEncoder(w io.Writer, val any, buf *[8]byte) error

func VarIntDecoder

func VarIntDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func VarIntEncoder

func VarIntEncoder(w io.Writer, val any, buf *[8]byte) error

func VersionDecoder

func VersionDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func VersionEncoder

func VersionEncoder(w io.Writer, val any, buf *[8]byte) error

func WitnessDecoder

func WitnessDecoder(r io.Reader, val any, buf *[8]byte, _ uint64) error

func WitnessEncoder

func WitnessEncoder(w io.Writer, val any, buf *[8]byte) error

Types

type Asset

type Asset struct {
	// Version is the Taro version of the asset.
	Version Version

	// Genesis encodes an asset's genesis metadata which directly maps to
	// its unique ID within the Taro protocol.
	Genesis

	// Amount is the number of units represented by the asset.
	Amount uint64

	// LockTime, if non-zero, restricts an asset from being moved prior to
	// the represented block height in the chain.
	LockTime uint64

	// RelativeLockTime, if non-zero, restricts an asset from being moved
	// until a number of blocks after the confirmation height of the latest
	// transaction for the asset is reached.
	RelativeLockTime uint64

	// PrevWitnesses contains the witness(es) of an asset's previous
	// transfer.
	PrevWitnesses []Witness

	// SplitCommitmentRoot is the root node of the MS-SMT storing split
	// commitments.
	//
	// NOTE: This should only be set when the previous transfer of an asset
	// resulted in a value split.
	SplitCommitmentRoot mssmt.Node

	// ScriptVersion denotes how an asset's ScriptKey should be validated.
	ScriptVersion ScriptVersion

	// ScriptKey represents a tweaked Taproot output key encumbering the
	// different ways an asset can be spent.
	ScriptKey ScriptKey

	// FamilyKey is the tweaked public key that is used to associate assets
	// together across distinct asset IDs, allowing further issuance of the
	// asset to be made possible.
	FamilyKey *FamilyKey
}

Asset represents a Taro asset.

func New

func New(genesis Genesis, amount, locktime, relativeLocktime uint64,
	scriptKey ScriptKey, familyKey *FamilyKey) (*Asset, error)

New instantiates a new asset with a genesis asset witness.

func (*Asset) AssetCommitmentKey

func (a *Asset) AssetCommitmentKey() [32]byte

AssetCommitmentKey is the key that maps to a specific owner of an asset within a Taro AssetCommitment.

func (*Asset) Copy

func (a *Asset) Copy() *Asset

Copy returns a deep copy of an Asset.

func (*Asset) Decode

func (a *Asset) Decode(r io.Reader) error

Decode decodes an asset from a TLV stream.

func (*Asset) DecodeRecords

func (a *Asset) DecodeRecords() []tlv.Record

DecodeRecords provides all records known for an asset witness for proper decoding.

func (*Asset) DeepEqual

func (a *Asset) DeepEqual(o *Asset) bool

DeepEqual returns true if this asset is equal with the given asset.

func (*Asset) Encode

func (a *Asset) Encode(w io.Writer) error

Encode encodes an asset into a TLV stream.

func (*Asset) EncodeRecords

func (a *Asset) EncodeRecords() []tlv.Record

EncodeRecords determines the non-nil records to include when encoding an asset at runtime.

func (*Asset) HasGenesisWitness

func (a *Asset) HasGenesisWitness() bool

HasGenesisWitness determines whether an asset has a valid genesis witness, which should only have one input with a zero PrevID and empty witness and split commitment proof.

func (*Asset) HasSplitCommitmentWitness

func (a *Asset) HasSplitCommitmentWitness() bool

HasSplitCommitmentWitness returns true if an asset has a split commitment witness.

func (*Asset) IsUnspendable

func (a *Asset) IsUnspendable() bool

IsUnspendable returns true if an asset uses the unspendable script key and has zero value.

func (*Asset) Leaf

func (a *Asset) Leaf() (*mssmt.LeafNode, error)

Leaf returns the asset encoded as a MS-SMT leaf node.

func (*Asset) TaroCommitmentKey

func (a *Asset) TaroCommitmentKey() [32]byte

TaroCommitmentKey is the key that maps to the root commitment for a specific asset family within a TaroCommitment.

type FamilyKey

type FamilyKey struct {
	// RawKey is the raw family key before the tweak with the genesis point
	// has been applied.
	RawKey keychain.KeyDescriptor

	// FamKey is the tweaked public key that is used to associate assets
	// together across distinct asset IDs, allowing further issuance of the
	// asset to be made possible. The tweaked public key is the result of:
	//   familyInternalKey + sha256(familyInternalKey || genesisOutPoint) * G
	FamKey btcec.PublicKey

	// Sig is a signature over an asset's ID by `Key`.
	Sig schnorr.Signature
}

FamilyKey is the tweaked public key that is used to associate assets together across distinct asset IDs, allowing further issuance of the asset to be made possible.

func DeriveFamilyKey

func DeriveFamilyKey(genSigner GenesisSigner, rawKey keychain.KeyDescriptor,
	genesis Genesis) (*FamilyKey, error)

DeriveFamilyKey derives an asset's family key based on an internal public key descriptor key and an asset genesis.

func RandFamilyKey

func RandFamilyKey(t testing.TB, genesis *Genesis) *FamilyKey

RandFamilyKey creates a random family key for testing.

func (*FamilyKey) IsEqual

func (f *FamilyKey) IsEqual(otherFamilyKey *FamilyKey) bool

IsEqual returns true if this family key is equivalent to the passed other family key.

type Genesis

type Genesis struct {
	// FirstPrevOut represents the outpoint of the transaction's first
	// input that resulted in the creation of the asset.
	//
	// NOTE: This is immutable for the lifetime of the asset.
	FirstPrevOut wire.OutPoint

	// Tag is a human-readable identifier for the asset. This does not need
	// to be unique, but asset issuers should attempt for it to be unique if
	// possible.
	//
	// NOTE: This is immutable for the lifetime of the asset.
	Tag string

	// Metadata encodes metadata related to the asset.
	//
	// NOTE: This is immutable for the lifetime of the asset.
	//
	// TODO: Would this usually be a JSON blob? It may be worth
	// standardizing a schema subset for interoperability across wallets
	// when displaying this metadata.
	Metadata []byte

	// OutputIndex is the index of the output that carries the unique Taro
	// commitment in the genesis transaction.
	OutputIndex uint32

	// Type uniquely identifies the type of Taro asset.
	Type Type
}

Genesis encodes an asset's genesis metadata which directly maps to its unique ID within the Taro protocol.

func DecodeGenesis

func DecodeGenesis(r io.Reader) (Genesis, error)

DecodeGenesis decodes an asset genesis.

func RandGenesis

func RandGenesis(t testing.TB, assetType Type) Genesis

RandGenesis creates a random genesis for testing.

func (Genesis) Encode

func (g Genesis) Encode(w io.Writer) error

Encode encodes an asset genesis.

func (Genesis) FamilyKeyTweak

func (g Genesis) FamilyKeyTweak() []byte

FamilyKeyTweak returns the tweak bytes that commit to the previous outpoint, output index and type of the genesis.

func (Genesis) ID

func (g Genesis) ID() ID

ID computes an asset's unique identifier from its metadata.

func (Genesis) MetadataHash

func (g Genesis) MetadataHash() [sha256.Size]byte

MetadataHash computes the SHA-256 hash of the asset's metadata.

func (Genesis) TagHash

func (g Genesis) TagHash() [sha256.Size]byte

TagHash computes the SHA-256 hash of the asset's tag.

func (Genesis) VerifySignature

func (g Genesis) VerifySignature(sig *schnorr.Signature,
	pubKey *btcec.PublicKey) bool

VerifySignature verifies the given signature that it is valid over the asset's unique identifier with the given public key.

type GenesisSigner

type GenesisSigner interface {
	// SignGenesis signs the passed Genesis description using the public
	// key identified by the passed key descriptor. The final tweaked
	// public key and the signature are returned.
	SignGenesis(keychain.KeyDescriptor, Genesis) (*btcec.PublicKey,
		*schnorr.Signature, error)
}

GenesisSigner is used to sign the assetID using the family key public key for a given asset.

type ID

type ID [sha256.Size]byte

ID serves as a unique identifier of an asset, resulting from:

sha256(genesisOutPoint || sha256(tag) || sha256(metadata) ||
  outputIndex || assetType)

type LeafTlvType

type LeafTlvType = tlv.Type

LeafTlvType represents the different TLV types for Asset Leaf TLV records.

const (
	LeafVersion LeafTlvType = 0
	// TODO: LeafID and LeafGenesis have conflicting types. The BIP
	// specifies LeafID, but this would require wallets to store the
	// preimage to the asset ID elsewhere, when it could be included in the
	// TLV itself as done with LeafGenesis.
	LeafID                  LeafTlvType = 1
	LeafGenesis             LeafTlvType = 1
	LeafType                LeafTlvType = 2
	LeafAmount              LeafTlvType = 3
	LeafLockTime            LeafTlvType = 4
	LeafRelativeLockTime    LeafTlvType = 5
	LeafPrevWitness         LeafTlvType = 6
	LeafSplitCommitmentRoot LeafTlvType = 7
	LeafScriptVersion       LeafTlvType = 8
	LeafScriptKey           LeafTlvType = 9
	LeafFamilyKey           LeafTlvType = 10
)

type PrevID

type PrevID struct {
	// OutPoint refers to the asset's previous output position within a
	// transaction.
	OutPoint wire.OutPoint

	// ID is the asset ID of the previous asset tree.
	ID ID

	// ScriptKey is the previously tweaked Taproot output key committing to
	// the possible spending conditions of the asset. PrevID is being used
	// as map keys, so we want to only use data types with fixed and
	// comparable content, which a btcec.PublicKey might not be.
	ScriptKey SerializedKey
}

PrevID serves as a reference to an asset's previous input.

func (PrevID) Hash

func (id PrevID) Hash() [sha256.Size]byte

Hash returns the SHA-256 hash of all items encapsulated by PrevID.

type RawKeyGenesisSigner

type RawKeyGenesisSigner struct {
	// contains filtered or unexported fields
}

RawKeyGenesisSigner implements the GenesisSigner interface using a raw private key.

func NewRawKeyGenesisSigner

func NewRawKeyGenesisSigner(priv *btcec.PrivateKey) *RawKeyGenesisSigner

NewRawKeyGenesisSigner creates a new RawKeyGenesisSigner instance given the passed public key.

func (*RawKeyGenesisSigner) SignGenesis

func (r *RawKeyGenesisSigner) SignGenesis(keyDesc keychain.KeyDescriptor,
	gen Genesis) (*btcec.PublicKey, *schnorr.Signature, error)

SignGenesis signs the passed Genesis description using the public key identified by the passed key descriptor. The final tweaked public key and the signature are returned.

type ScriptKey

type ScriptKey struct {
	// PubKey is the script key that'll be encoded in the final TLV format.
	// All signatures are checked against this script key.
	PubKey *btcec.PublicKey

	*TweakedScriptKey
}

ScriptKey represents a tweaked Taproot output key encumbering the different ways an asset can be spent.

func NewScriptKey

func NewScriptKey(key *btcec.PublicKey) ScriptKey

NewScriptKey constructs a ScriptKey with only the publicly available information. This resulting key may or may not have a tweak applied to it.

func NewScriptKeyBIP0086

func NewScriptKeyBIP0086(rawKey keychain.KeyDescriptor) ScriptKey

NewScriptKeyBIP0086 constructs a ScriptKey tweaked BIP0086 style. The resulting script key will include the specified BIP 86 tweak (no real tweak), and also apply that to the final external PubKey.

type ScriptVersion

type ScriptVersion uint16

ScriptVersion denotes the asset script versioning scheme.

const (
	// ScriptV0 represents the initial asset script version of the Taro
	// protocol. In this version, assets commit to a tweaked Taproot output
	// key, allowing the ability for an asset to indirectly commit to
	// multiple spending conditions.
	ScriptV0 ScriptVersion = 0
)

type SerializedKey

type SerializedKey [33]byte

SerializedKey is a type for representing a public key, serialized in the compressed, 33-byte form.

func ToSerialized

func ToSerialized(pubKey *btcec.PublicKey) SerializedKey

ToSerialized serializes a public key in its 33-byte compressed form.

func (SerializedKey) CopyBytes

func (s SerializedKey) CopyBytes() []byte

CopyBytes returns a copy of the underlying array as a byte slice.

func (SerializedKey) SchnorrSerialized

func (s SerializedKey) SchnorrSerialized() []byte

SchnorrSerialized returns the Schnorr serialized, x-only 32-byte representation of the serialized key.

type SplitCommitment

type SplitCommitment struct {
	// Proof is the proof for a particular asset split resulting from a
	// split commitment.
	Proof mssmt.Proof

	// RootAsset is the asset containing the root of the split commitment
	// tree from which the `Proof` above was computed from.
	RootAsset Asset
}

SplitCommitment represents the asset witness for an asset split.

func (*SplitCommitment) DeepEqual

func (s *SplitCommitment) DeepEqual(o *SplitCommitment) bool

DeepEqual returns true if this split commitment is equal with the given split commitment.

type TweakedScriptKey

type TweakedScriptKey struct {
	// RawKey is the raw script key before the script key tweak is applied.
	// We store a full key descriptor here for wallet purposes, but will
	// only encode the pubkey above for the normal script leaf TLV
	// encoding.
	RawKey keychain.KeyDescriptor

	// Tweak is the tweak that is applied on the raw script key to get the
	// public key. If this is nil, then a BIP 86 tweak is assumed.
	Tweak []byte
}

TweakedScriptKey is an embedded struct which is primarily used by wallets to be able to keep track of the tweak of a script key along side the raw key derivation information.

type Type

type Type uint8

Type denotes the asset types supported by the Taro protocol.

const (
	// Normal is an asset that can be represented in multiple units,
	// resembling a divisible asset.
	Normal Type = 0

	// Collectible is a unique asset, one that cannot be represented in
	// multiple units.
	Collectible Type = 1
)

func (Type) String

func (t Type) String() string

String returns a human-readable description of the type.

type Version

type Version uint8

Version denotes the version of the Taro protocol in effect for an asset.

const (
	// V0 is the initial Taro protocol version.
	V0 Version = 0
)

type Witness

type Witness struct {
	// PrevID is a reference to an asset's previous input.
	//
	// NOTE: This should only be nil upon the creation of an asset.
	PrevID *PrevID

	// TxWitness is a witness that satisfies the asset's previous ScriptKey.
	//
	// NOTE: This field and `SplitCommitmentProof` are mutually exclusive,
	// except upon the creation of an asset, where both should be nil.
	TxWitness wire.TxWitness

	// SplitCommitmentProof is used to permit the spending of an asset UTXO
	// created as a result of an asset split. When an asset is split, the
	// non-change UTXO commits to the location of all other splits within an
	// MS-SMT tree. When spending a change UTXO resulting from a
	// `SplitCommitment`, a normal `Witness` isn't required, instead the
	// owner of the change asset UTXO must prove that it holds a valid split
	// which was authorized by the main transfer transaction.
	//
	// Outputs with the same `SplitCommitment` are said to share a single
	// `Witness` as such outputs are the result of a new asset split.
	// Therefore, we only need a single witness and the resulting merkle-sum
	// asset tree to verify a transfer.
	//
	// NOTE: This field and `TxWitness` are mutually exclusive,
	// except upon the creation of an asset, where both should be nil.
	//
	// TODO: This still needs to be specified further in the BIPs, see
	// https://github.com/lightninglabs/taro/issues/3.
	SplitCommitment *SplitCommitment
}

Witness is a nested TLV stream within the main Asset TLV stream that contains the necessary data to verify the movement of an asset. All fields should be nil to represent the creation of an asset, `TxWitness` and `SplitCommitmentProof` are mutually exclusive otherwise.

func (*Witness) Decode

func (w *Witness) Decode(r io.Reader) error

Decode decodes an asset witness from a TLV stream.

func (*Witness) DecodeRecords

func (w *Witness) DecodeRecords() []tlv.Record

DecodeRecords provides all records known for an asset witness for proper decoding.

func (*Witness) DeepEqual

func (w *Witness) DeepEqual(o *Witness) bool

DeepEqual returns true if this witness is equal with the given witness.

func (*Witness) Encode

func (w *Witness) Encode(writer io.Writer) error

Encode encodes an asset witness into a TLV stream.

func (*Witness) EncodeRecords

func (w *Witness) EncodeRecords() []tlv.Record

EncodeRecords determines the non-nil records to include when encoding an asset witness at runtime.

type WitnessTlvType

type WitnessTlvType = tlv.Type

WitnessTlvType represents the different TLV types for Asset Witness TLV records.

const (
	WitnessPrevID          WitnessTlvType = 0
	WitnessTxWitness       WitnessTlvType = 1
	WitnessSplitCommitment WitnessTlvType = 2
)

Jump to

Keyboard shortcuts

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