BSV.Tokens.Lineage (bsv_sdk v2.0.0)

Copy Markdown View Source

Off-chain lineage validator for STAS tokens.

Status: EXPERIMENTAL — not functional for STAS 3.0

This validator classifies only :stas / :stas_btg / :p2pkh script types; a STAS 3.0 ancestor hits the fallthrough clause and returns an error. It also does NOT model the STAS 3.0 issuance-set invariant (Vin[0] == protoID) or illegal_roots taint propagation. Do not rely on it to validate STAS 3.0 lineage — the authoritative STAS 3.0 lineage/validity model lives in the athanor indexer. Reviving this for STAS 3.0 requires adding a :stas3 clause.

Walks the ancestor chain of a token UTXO back to the genesis (contract) transaction, verifying that every hop is a legitimate STAS token transfer or issuance.

Usage

validator = BSV.Tokens.Lineage.new(contract_txid, redemption_pkh)
{:ok, validator} = BSV.Tokens.Lineage.validate(validator, utxo_txid, vout, tx_fetcher_fn)

The tx_fetcher_fn is a function (txid_binary -> {:ok, raw_tx} | {:error, reason}).

Security Notice — Trust Model

This validator verifies the chain of txids and script types back to genesis, and confirms that sha256d(raw_tx) == expected_txid for each hop. However, it does not verify transaction signatures. It trusts the tx_fetcher to return authentic transaction data.

If the tx_fetcher is backed by an untrusted source, an attacker could supply fabricated transactions with valid txid hashes but forged scripts/outputs. For maximum security, combine lineage validation with SPV proof verification (Merkle path against a trusted block header) to confirm each transaction was actually mined.

Summary

Functions

Check whether a specific txid has already been validated.

Create a new lineage validator.

Validate a token UTXO's lineage back to the genesis transaction.

Return the number of txids that have been validated so far.

Types

t()

@type t() :: %BSV.Tokens.Lineage{
  contract_txid: <<_::256>>,
  redemption_pkh: <<_::160>>,
  validated: MapSet.t(binary())
}

Functions

is_validated?(lineage, txid)

@spec is_validated?(t(), binary()) :: boolean()

Check whether a specific txid has already been validated.

new(arg1, arg2)

@spec new(<<_::256>>, <<_::160>>) :: t()

Create a new lineage validator.

The contract TX is pre-validated (it is the trust anchor).

validate(validator, utxo_txid, vout, tx_fetcher)

@spec validate(t(), <<_::256>>, non_neg_integer(), (binary() ->
                                                {:ok, binary()}
                                                | {:error, term()})) ::
  {:ok, t()} | {:error, term()}

Validate a token UTXO's lineage back to the genesis transaction.

Note: Only the first input of each transaction is followed during ancestor traversal. Multi-input token merges are not fully validated — only the lineage through input 0 is checked.

The tx_fetcher is a function (txid :: binary -> {:ok, raw_tx} | {:error, reason}).

Returns {:ok, updated_validator} on success.

validated_count(lineage)

@spec validated_count(t()) :: non_neg_integer()

Return the number of txids that have been validated so far.