Helpers for implementing OP_PUSH_TX in BSV.Contract modules.
OP_PUSH_TX is a technique enabling true smart contracts on Bitcoin:
- Push the BIP-143 transaction preimage into the unlocking script
- In the locking script, verify it is the correct preimage using script-level
signature construction +
OP_CHECKSIG - 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
@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.
@spec check_tx!(BSV.Contract.t()) :: BSV.Contract.t()
Same as check_tx/1 but uses OP_CHECKSIGVERIFY.
@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.
@spec check_tx_opt!(BSV.Contract.t()) :: BSV.Contract.t()
Same as check_tx_opt/1 but uses OP_CHECKSIGVERIFY.
@spec get_lock_time(BSV.Contract.t()) :: BSV.Contract.t()
Get the 4-byte locktime from a preimage.
@spec get_outpoint(BSV.Contract.t()) :: BSV.Contract.t()
Get the 36-byte outpoint (txid + vout) from a preimage.
@spec get_outputs_hash(BSV.Contract.t()) :: BSV.Contract.t()
Get the 32-byte outputs hash from a preimage.
@spec get_prevouts_hash(BSV.Contract.t()) :: BSV.Contract.t()
Get the 32-byte prevouts hash from a preimage on top of the stack.
@spec get_satoshis(BSV.Contract.t()) :: BSV.Contract.t()
Get the 8-byte input satoshis as a ScriptNum from a preimage.
@spec get_script(BSV.Contract.t()) :: BSV.Contract.t()
Get the locking script from a preimage (with VarInt prefix trimmed).
@spec get_sequence(BSV.Contract.t()) :: BSV.Contract.t()
Get the 4-byte input sequence number from a preimage.
@spec get_sequence_hash(BSV.Contract.t()) :: BSV.Contract.t()
Get the 32-byte sequence hash from a preimage.
@spec get_sighash_type(BSV.Contract.t()) :: BSV.Contract.t()
Get the 4-byte sighash type from a preimage.
@spec get_version(BSV.Contract.t()) :: BSV.Contract.t()
Get the 4-byte tx version from a preimage on top of the stack.
@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.