BSV.Tokens.Stas3UnlockWitness (bsv_sdk v1.5.0)

Copy Markdown View Source

STAS 3.0 v0.1 §7 unlocking-script witness assembly (slots 1-20).

A STAS 3.0 unlock script is built from three concatenated regions:

witness_bytes       (slots 1-20, this module)
 authz             (§10  `<sig> <pubkey>`, OP_0/<sigs>/<redeem>, or
                      OP_FALSE for no-auth)  emitted by
                      `BSV.Tokens.Template.Stas3.sign/3`.
 trailing_params   (§9.5 atomic-swap counterparty pieces, or
                      §8.1 merge piece array)  emitted by
                      `BSV.Tokens.Script.Stas3Pieces` when txType > 0.

This module is responsible for the FIRST region only — slots 1 through 20 pushed in spec order. The structure carries everything required to build those bytes; the encoder is to_script_bytes/1.

Slot layout (spec §7, in stack-push order)

#SlotTypeAbsence rule
1out1_amountminimal LE up to 8 Bempty push if no STAS out 1
2out1_addr20 B owner PKHempty push
3out1_var2single push(always pushed; can be empty)
4-6out2_*same as out1 tripletSKIPPED entirely if absent
7-9out3_*same as out1 tripletSKIPPED entirely if absent
10-12out4_*same as out1 tripletSKIPPED entirely if absent
13change_amountminimal LEOP_FALSE (<<0x00>>)
14change_addr20 B raw P2PKH-PKHOP_FALSE
15noteDatapayload (max 65 533 B)OP_FALSE
16fundIdx4 B LE uint32OP_FALSE
17fundTxid32 B rawOP_FALSE
18txType1 B (0..7)always present
19sighashPreimagevariablealways present
20spendType1 B (1..4)always present

Slots 4-6, 7-9, 10-12 are SKIPPED entirely (no opcode at all) when the matching STAS output is not produced. Slots 13-17 always emit a single push: either the value or OP_FALSE per the absence column above.

This split between "skip vs OP_FALSE" mirrors the spec verbatim (§7 footnotes ) and *).

Summary

Types

A change output (P2PKH satoshi remainder).

Funding-input identification.

A single STAS output triplet for the witness (slots 1-3, 4-6, 7-9, 10-12).

t()

Functions

Maximum permitted note-data payload length (spec §11).

Encode a Stas3UnlockWitness to its raw witness-script bytes (slots 1-20) per spec §7.

Types

change()

@type change() :: %{amount: non_neg_integer(), addr_pkh: <<_::160>>}

A change output (P2PKH satoshi remainder).

funding_input()

@type funding_input() :: %{txid: <<_::256>>, vout: non_neg_integer()}

Funding-input identification.

stas_output()

@type stas_output() :: %{
  amount: non_neg_integer(),
  owner_pkh: <<_::160>>,
  var2: binary()
}

A single STAS output triplet for the witness (slots 1-3, 4-6, 7-9, 10-12).

t()

@type t() :: %BSV.Tokens.Stas3UnlockWitness{
  change: change() | nil,
  funding_input: funding_input() | nil,
  note_data: binary() | nil,
  sighash_preimage: binary(),
  spend_type: BSV.Tokens.SpendType.t(),
  stas_outputs: [stas_output()],
  tx_type: BSV.Tokens.TxType.t() | non_neg_integer()
}

Functions

max_note_bytes()

@spec max_note_bytes() :: pos_integer()

Maximum permitted note-data payload length (spec §11).

to_script_bytes(w)

@spec to_script_bytes(t()) :: {:ok, binary()} | {:error, term()}

Encode a Stas3UnlockWitness to its raw witness-script bytes (slots 1-20) per spec §7.

Returns {:ok, bytes} on success or {:error, reason} on validation failure:

  • {:error, :note_data_too_large} — note payload exceeds 65 533 B.
  • {:error, {:too_many_stas_outputs, n}} — more than 4 STAS outputs.
  • {:error, :invalid_sighash_preimage} — preimage is not a binary.

The output of this function is meant to be concatenated with the authz bytes (and any txType-trailing piece-array bytes) to form the complete unlocking script.