BSV.VM (BSV v2.1.0) View Source

Pure Elixir Bitcoin Script VM.

Bitcoin Script is a Forth-like scripting language used to define the locking mechanism for a transaction output.

Transaction outputs each contain a "locking script" which lock a number of satoshis. Transaction inputs contain an "unlocking script" which unlock the satoshis contained in a previous output. Both the unlocking script and previous locking script are concatenated in the following order:

unlocking_script <> locking_script

The entire script is evaluated and when if the end result contains a truthy value on the top of the stack, it is a valid script. Otherwise it is invalid. This is known as a predicate - an equation that evaluates to true or false.

Link to this section Summary

Types

Transaction context.

t()

VM struct

Functions

Evaluates the given script and returns a VM state.

As eval/2 but returns the VM struct or raises an error.

Initiates a new VM struct

If the top stack element is not false it is made true. Otherwise it is made false.

Adds 1 onto the top stack element.

Subtracks 1 from the top stack element.

Divides the top stack element by 2. DISABLED

Removes the top two items from the stack.

Duplicates the top two items on the stack.

Multiplies the top stack element by 2. DISABLED

Copies two items two spaces back to the top of the stack.

Moves the 5th and 6th items to top of stack.

Swaps the top two pairs of items.

Duplicates the top three items on the stack.

Makes positive the numeric value of the top stack element.

The top two stack elements are added and replaced on the stack with the result.

Calculates the bitwise AND of the top two elements of the stack. Both elements must be the same length.

Converts the binary value into a numeric value.

Checks the top two stack elements are both truthy and replaces them with the boolean result.

Checks if either of the top two stack elements are truthy and replaces them with the boolean result.

Concatenates the top two stack items into one binary.

The top stack element is the number of public keys. The next n elements are the public keys. The next element is the number of signatures and the next n elements are the signatures.

Verifies the signature in the second top stack element against the current transaction sighash using the pubkey on top of the stack. Replaces them with the boolean result.

Counts the stack lenth and puts the result on the top of the stack.

The top stack element is divided from the second, and both are replaced on the stack with the result.

Removes the top item from the stack.

Duplicates the top item on the stack.

If the preceding OP_IF or OP_NOTIF was not executed, the the following statements are executed. If the preceding OP_IF or OP_NOTIF was executed, the following statements are not.

Ends the current IF/ELSE block. All blocks must end or the script is invalid.

Compares the equality of the top two stack items and replaces them with the boolean result.

Removes the top of the alt stack and puts it into the stack.

Compares numeric value of the top two stack elements, and both are replaced on the stack with the result. Is true if the second element is greater than the first.

Compares numeric value of the top two stack elements, and both are replaced on the stack with the result. Is true if the second element is greater than or equal to the first.

The top element on the stack is hashed using SHA256 then RIPEMD160.

The top element on the stack is hashed using SHA256 then SHA256 again.

Removes the top of the stack. If the top value is truthy, statements between OP_IF and OP_ELSE are executed. Otherwise statements between OP_ELSE and OP_ENDIF are executed.

Duplicates the top stack item if it is truthy.

Flips all bits on the top element of the stack.

Compares numeric value of the top two stack elements, and both are replaced on the stack with the result. Is true if the second element is less than the first.

Compares numeric value of the top two stack elements, and both are replaced on the stack with the result. Is true if the second element is less than or equal to the first.

The second from top element numeric value is bitshifted to the left by the number of bits in the top element numeric value. Both elements are replaced on the stack with the result.

Compares numeric value of the top two stack elements, and both are replaced with the greater value.

Compares numeric value of the top two stack elements, and both are replaced with the smaller value.

The top stack element is divided from the second, and both are replaced on the stack with the remainder.

The top two stack elements are multiplied and replaced on the stack with the result.

Negates the numeric value of the top stack element.

Removes the second to top item from the stack.

No op. Does nothing and returns the vm.

If the top stack element is false it is made true. Otherwise it is made false.

Removes the top of the stack. If the top value is false, statements between OP_NOTIF and OP_ELSE are executed. Otherwise statements between OP_ELSE and OP_ENDIF are executed.

Converts the second from top stack item into a binary of the length given in the top stack item.

Compares the equality of the numeric value of the top two stack items and replaces them with the boolean result.

Checks the numeric value of the top two stack items are not equal and replaces them with the boolean result.

Calculates the bitwise OR of the top two elements of the stack. Both elements must be the same length.

Copies the second to top stack item to the top.

Removes the top stack item and uses it as an index length, then copies the nth item on the stack to the top.

Generic pushdata. Pushes any given binary or integer to the stack.

Unused. Makes transaction invalid.

Returns the vm and no further statements are evaluated.

The top element on the stack is hashed using RIPEMD160.

Removes the top stack item and uses it as an index length, then moves the nth item on the stack to the top.

Rotates the top three items on the stack, effictively moving the 3rd item to the top of the stack.

The second from top element numeric value is bitshifted to the right by the number of bits in the top element numeric value. Both elements are replaced on the stack with the result.

The top element on the stack is hashed using SHA1.

The top element on the stack is hashed using SHA256.

Pushes the byte length of the top element of the stack, without popping it.

Splits the second from top stack item by the index given in the top stack item.

The top stack element is subtracted from the second, and both are replaced on the stack with the result.

Rotates the top two items on the stack, effectively moving the 2nd item to the top of the stack.

Removes the top of the stack and puts it into the alt stack.

Copies the top item on the stack and inserts it before the second to top item.

Puts the version of the protocol under which this transaction will be evaluated onto the stack. DISABLED

Removes the top of the stack. If the top value is equal to the version of the protocol under which the transaction is evaluated, statements between OP_IF and OP_ELSE are executed. Otherwise statements between OP_ELSE and OP_ENDIF are executed. DISABLED

Mmarks the script as invalid unless the stack is truthy. Removes the top of the stack.

Removes the top of the stack. If the top value is not equal to the version of the protocol under which the transaction is evaluated, statements between OP_IF and OP_ELSE are executed. Otherwise statements between OP_ELSE and OP_ENDIF are executed. DISABLED

The top (max) and second (min) numeric values on the stack define a range and the third element is checked to see if it is within the range. All three elements are replaced on the stack with the boolean result.

Calculates the bitwise XOR of the top two elements of the stack. Both elements must be the same length.

Determines if the Script VM is truthy or falsey.

Link to this section Types

Specs

ctx() :: {BSV.Tx.t(), non_neg_integer(), BSV.TxOut.t()}

Transaction context.

A tuple containing a BSV.Tx.t/0, BSV.TxIn.vin/0 and BSV.TxOut.t/0. If not present, then op_checksig/1 and op_checkmultisig/1 will raise errors and the script will fail.

Specs

t() :: %BSV.VM{
  alt_stack: list(),
  ctx: ctx() | nil,
  error: nil | String.t(),
  if_stack: list(),
  op_return: list(),
  opts: map(),
  stack: list()
}

VM struct

Link to this section Functions

Specs

eval(t(), BSV.Script.t() | list()) :: {:ok, t()} | {:error, t()}

Evaluates the given script and returns a VM state.

Specs

eval!(t(), BSV.Script.t() | list()) :: t()

As eval/2 but returns the VM struct or raises an error.

Specs

init(keyword()) :: t()

Initiates a new VM struct

Specs

op_0notequal(t()) :: t()

If the top stack element is not false it is made true. Otherwise it is made false.

Specs

op_1add(t()) :: t()

Adds 1 onto the top stack element.

Specs

op_1sub(t()) :: t()

Subtracks 1 from the top stack element.

Specs

op_2div(t()) :: t()

Divides the top stack element by 2. DISABLED

Specs

op_2drop(t()) :: t()

Removes the top two items from the stack.

Specs

op_2dup(t()) :: t()

Duplicates the top two items on the stack.

Specs

op_2mul(t()) :: t()

Multiplies the top stack element by 2. DISABLED

Specs

op_2over(t()) :: t()

Copies two items two spaces back to the top of the stack.

Specs

op_2rot(t()) :: t()

Moves the 5th and 6th items to top of stack.

Specs

op_2swap(t()) :: t()

Swaps the top two pairs of items.

Specs

op_3dup(t()) :: t()

Duplicates the top three items on the stack.

Specs

op_abs(t()) :: t()

Makes positive the numeric value of the top stack element.

Specs

op_add(t()) :: t()

The top two stack elements are added and replaced on the stack with the result.

Specs

op_and(t()) :: t()

Calculates the bitwise AND of the top two elements of the stack. Both elements must be the same length.

Specs

op_bin2num(t()) :: t()

Converts the binary value into a numeric value.

Specs

op_booland(t()) :: t()

Checks the top two stack elements are both truthy and replaces them with the boolean result.

Specs

op_boolor(t()) :: t()

Checks if either of the top two stack elements are truthy and replaces them with the boolean result.

Specs

op_cat(t()) :: t()

Concatenates the top two stack items into one binary.

Specs

op_checkmultisig(t()) :: t()

The top stack element is the number of public keys. The next n elements are the public keys. The next element is the number of signatures and the next n elements are the signatures.

Each signature is itereated over and each public key is checked if it verifies the signature against the current transactions sighash. Once a public key is checked it is not checked again, so signatures must be pushed onto the stack in the same order as the corresponding public keys.

Link to this function

op_checkmultisigverify(vm)

View Source

Specs

op_checkmultisigverify(t()) :: t()

Runs op_checkmultisig/1 and op_verify/1.

Specs

op_checksig(t()) :: t()

Verifies the signature in the second top stack element against the current transaction sighash using the pubkey on top of the stack. Replaces them with the boolean result.

Specs

op_checksigverify(t()) :: t()

Runs op_checksig/1 and op_verify/1.

Specs

op_depth(t()) :: t()

Counts the stack lenth and puts the result on the top of the stack.

Specs

op_div(t()) :: t()

The top stack element is divided from the second, and both are replaced on the stack with the result.

Specs

op_drop(t()) :: t()

Removes the top item from the stack.

Specs

op_dup(t()) :: t()

Duplicates the top item on the stack.

Specs

op_else(t()) :: t()

If the preceding OP_IF or OP_NOTIF was not executed, the the following statements are executed. If the preceding OP_IF or OP_NOTIF was executed, the following statements are not.

Specs

op_endif(t()) :: t()

Ends the current IF/ELSE block. All blocks must end or the script is invalid.

Specs

op_equal(t()) :: t()

Compares the equality of the top two stack items and replaces them with the boolean result.

Specs

op_equalverify(t()) :: t()

Runs op_equal/1 and op_verify/1.

Specs

op_fromaltstack(t()) :: t()

Removes the top of the alt stack and puts it into the stack.

Specs

op_greaterthan(t()) :: t()

Compares numeric value of the top two stack elements, and both are replaced on the stack with the result. Is true if the second element is greater than the first.

Link to this function

op_greaterthanorequal(vm)

View Source

Specs

op_greaterthanorequal(t()) :: t()

Compares numeric value of the top two stack elements, and both are replaced on the stack with the result. Is true if the second element is greater than or equal to the first.

Specs

op_hash160(t()) :: t()

The top element on the stack is hashed using SHA256 then RIPEMD160.

Specs

op_hash256(t()) :: t()

The top element on the stack is hashed using SHA256 then SHA256 again.

Specs

op_if(t()) :: t()

Removes the top of the stack. If the top value is truthy, statements between OP_IF and OP_ELSE are executed. Otherwise statements between OP_ELSE and OP_ENDIF are executed.

Specs

op_ifdup(t()) :: t()

Duplicates the top stack item if it is truthy.

Specs

op_invert(t()) :: t()

Flips all bits on the top element of the stack.

Specs

op_lessthan(t()) :: t()

Compares numeric value of the top two stack elements, and both are replaced on the stack with the result. Is true if the second element is less than the first.

Specs

op_lessthanorequal(t()) :: t()

Compares numeric value of the top two stack elements, and both are replaced on the stack with the result. Is true if the second element is less than or equal to the first.

Specs

op_lshift(t()) :: t()

The second from top element numeric value is bitshifted to the left by the number of bits in the top element numeric value. Both elements are replaced on the stack with the result.

Specs

op_max(t()) :: t()

Compares numeric value of the top two stack elements, and both are replaced with the greater value.

Specs

op_min(t()) :: t()

Compares numeric value of the top two stack elements, and both are replaced with the smaller value.

Specs

op_mod(t()) :: t()

The top stack element is divided from the second, and both are replaced on the stack with the remainder.

Specs

op_mul(t()) :: t()

The top two stack elements are multiplied and replaced on the stack with the result.

Specs

op_negate(t()) :: t()

Negates the numeric value of the top stack element.

Specs

op_nip(t()) :: t()

Removes the second to top item from the stack.

Specs

op_nop(t()) :: t()

No op. Does nothing and returns the vm.

Specs

op_not(t()) :: t()

If the top stack element is false it is made true. Otherwise it is made false.

Specs

op_notif(t()) :: t()

Removes the top of the stack. If the top value is false, statements between OP_NOTIF and OP_ELSE are executed. Otherwise statements between OP_ELSE and OP_ENDIF are executed.

Specs

op_num2bin(t()) :: t()

Converts the second from top stack item into a binary of the length given in the top stack item.

Specs

op_numequal(t()) :: t()

Compares the equality of the numeric value of the top two stack items and replaces them with the boolean result.

Specs

op_numequalverify(t()) :: t()

Runs op_numequal/1 and op_verify/1.

Specs

op_numnotequal(t()) :: t()

Checks the numeric value of the top two stack items are not equal and replaces them with the boolean result.

Specs

op_or(t()) :: t()

Calculates the bitwise OR of the top two elements of the stack. Both elements must be the same length.

Specs

op_over(t()) :: t()

Copies the second to top stack item to the top.

Specs

op_pick(t()) :: t()

Removes the top stack item and uses it as an index length, then copies the nth item on the stack to the top.

Specs

op_pushdata(t(), binary() | number()) :: t()

Generic pushdata. Pushes any given binary or integer to the stack.

Specs

op_reserved(t()) :: t()

Unused. Makes transaction invalid.

Specs

op_return(t(), list()) :: t()

Returns the vm and no further statements are evaluated.

Specs

op_ripemd160(t()) :: t()

The top element on the stack is hashed using RIPEMD160.

Specs

op_roll(t()) :: t()

Removes the top stack item and uses it as an index length, then moves the nth item on the stack to the top.

Specs

op_rot(t()) :: t()

Rotates the top three items on the stack, effictively moving the 3rd item to the top of the stack.

Specs

op_rshift(t()) :: t()

The second from top element numeric value is bitshifted to the right by the number of bits in the top element numeric value. Both elements are replaced on the stack with the result.

Specs

op_sha1(t()) :: t()

The top element on the stack is hashed using SHA1.

Specs

op_sha256(t()) :: t()

The top element on the stack is hashed using SHA256.

Specs

op_size(t()) :: t()

Pushes the byte length of the top element of the stack, without popping it.

Specs

op_split(t()) :: t()

Splits the second from top stack item by the index given in the top stack item.

Specs

op_sub(t()) :: t()

The top stack element is subtracted from the second, and both are replaced on the stack with the result.

Specs

op_swap(t()) :: t()

Rotates the top two items on the stack, effectively moving the 2nd item to the top of the stack.

Specs

op_toaltstack(t()) :: t()

Removes the top of the stack and puts it into the alt stack.

Specs

op_tuck(t()) :: t()

Copies the top item on the stack and inserts it before the second to top item.

Specs

op_ver(t()) :: t()

Puts the version of the protocol under which this transaction will be evaluated onto the stack. DISABLED

Specs

op_verif(t()) :: t()

Removes the top of the stack. If the top value is equal to the version of the protocol under which the transaction is evaluated, statements between OP_IF and OP_ELSE are executed. Otherwise statements between OP_ELSE and OP_ENDIF are executed. DISABLED

Specs

op_verify(t()) :: t()

Mmarks the script as invalid unless the stack is truthy. Removes the top of the stack.

Specs

op_vernotif(t()) :: t()

Removes the top of the stack. If the top value is not equal to the version of the protocol under which the transaction is evaluated, statements between OP_IF and OP_ELSE are executed. Otherwise statements between OP_ELSE and OP_ENDIF are executed. DISABLED

Specs

op_within(t()) :: t()

The top (max) and second (min) numeric values on the stack define a range and the third element is checked to see if it is within the range. All three elements are replaced on the stack with the boolean result.

Specs

op_xor(t()) :: t()

Calculates the bitwise XOR of the top two elements of the stack. Both elements must be the same length.

Specs

valid?(t()) :: boolean()

Determines if the Script VM is truthy or falsey.