BSV.Contract.PushTxHelpers (bsv_sdk v2.0.0)

Copy Markdown View Source

Helpers for implementing OP_PUSH_TX in BSV.Contract modules.

OP_PUSH_TX is a technique enabling true smart contracts on Bitcoin:

  1. Push the BIP-143 transaction preimage into the unlocking script
  2. In the locking script, verify it is the correct preimage using script-level signature construction + OP_CHECKSIG
  3. Extract any data from the verified preimage for contract logic

This enables state tracking, spending conditions, and covenants.

Usage

defmodule MyContract do
  use BSV.Contract
  import BSV.Contract.PushTxHelpers

  def locking_script(ctx, _params) do
    check_tx(ctx)
  end

  def unlocking_script(ctx, _params) do
    push_tx(ctx)
  end
end

Summary

Functions

Verify the preimage on top of the stack using script-level OP_CHECKSIG.

Same as check_tx/1 but uses OP_CHECKSIGVERIFY.

Optimal OP_PUSH_TX — compiles to ~87 bytes.

Same as check_tx_opt/1 but uses OP_CHECKSIGVERIFY.

Get the 4-byte locktime from a preimage.

Get the 36-byte outpoint (txid + vout) from a preimage.

Get the 32-byte outputs hash from a preimage.

Get the 32-byte prevouts hash from a preimage on top of the stack.

Get the 8-byte input satoshis as a ScriptNum from a preimage.

Get the locking script from a preimage (with VarInt prefix trimmed).

Get the 4-byte input sequence number from a preimage.

Get the 32-byte sequence hash from a preimage.

Get the 4-byte sighash type from a preimage.

Get the 4-byte tx version from a preimage on top of the stack.

Push the BIP-143 transaction preimage onto the stack.

Functions

check_tx(ctx)

@spec check_tx(BSV.Contract.t()) :: BSV.Contract.t()

Verify the preimage on top of the stack using script-level OP_CHECKSIG.

Constructs a signature from the sighash in-script and verifies it against a known public key. Compiles to ~438 bytes of script.

check_tx!(ctx)

@spec check_tx!(BSV.Contract.t()) :: BSV.Contract.t()

Same as check_tx/1 but uses OP_CHECKSIGVERIFY.

check_tx_opt(ctx)

@spec check_tx_opt(BSV.Contract.t()) :: BSV.Contract.t()

Optimal OP_PUSH_TX — compiles to ~87 bytes.

Warning: Due to the Low-S constraint, the MSB of the sighash must be < 0x7E. There is roughly a 50% chance the signature is invalid per attempt. When using this, you must malleate the transaction (e.g. change locktime) until valid.

check_tx_opt!(ctx)

@spec check_tx_opt!(BSV.Contract.t()) :: BSV.Contract.t()

Same as check_tx_opt/1 but uses OP_CHECKSIGVERIFY.

get_lock_time(ctx)

@spec get_lock_time(BSV.Contract.t()) :: BSV.Contract.t()

Get the 4-byte locktime from a preimage.

get_outpoint(ctx)

@spec get_outpoint(BSV.Contract.t()) :: BSV.Contract.t()

Get the 36-byte outpoint (txid + vout) from a preimage.

get_outputs_hash(ctx)

@spec get_outputs_hash(BSV.Contract.t()) :: BSV.Contract.t()

Get the 32-byte outputs hash from a preimage.

get_prevouts_hash(ctx)

@spec get_prevouts_hash(BSV.Contract.t()) :: BSV.Contract.t()

Get the 32-byte prevouts hash from a preimage on top of the stack.

get_satoshis(ctx)

@spec get_satoshis(BSV.Contract.t()) :: BSV.Contract.t()

Get the 8-byte input satoshis as a ScriptNum from a preimage.

get_script(ctx)

@spec get_script(BSV.Contract.t()) :: BSV.Contract.t()

Get the locking script from a preimage (with VarInt prefix trimmed).

get_sequence(ctx)

@spec get_sequence(BSV.Contract.t()) :: BSV.Contract.t()

Get the 4-byte input sequence number from a preimage.

get_sequence_hash(ctx)

@spec get_sequence_hash(BSV.Contract.t()) :: BSV.Contract.t()

Get the 32-byte sequence hash from a preimage.

get_sighash_type(ctx)

@spec get_sighash_type(BSV.Contract.t()) :: BSV.Contract.t()

Get the 4-byte sighash type from a preimage.

get_version(ctx)

@spec get_version(BSV.Contract.t()) :: BSV.Contract.t()

Get the 4-byte tx version from a preimage on top of the stack.

push_tx(ctx)

@spec push_tx(BSV.Contract.t()) :: BSV.Contract.t()

Push the BIP-143 transaction preimage onto the stack.

When transaction context is available, computes the real preimage. Otherwise pushes 181 zero bytes as a placeholder.