[#miniscript-Type] = xref:miniscript.adoc[miniscript]::Type :relfileprefix: ../ :mrdocs: This type encapsulates the miniscript type system properties. == Synopsis Declared in `<script/miniscript.h>` [source,cpp,subs="verbatim,replacements,macros,-callouts"] ---- class Type; ---- == Description Every miniscript expression is one of 4 basic types, and additionally has a number of boolean type properties. The basic types are: * "B" Base: * Takes its inputs from the top of the stack. * When satisfied, pushes a nonzero value of up to 4 bytes onto the stack. * When dissatisfied, pushes a 0 onto the stack. * This is used for most expressions, and required for the top level one. * For example: older(n) = <n> OP_CHECKSEQUENCEVERIFY. * "V" Verify: * Takes its inputs from the top of the stack. * When satisfied, pushes nothing. * Cannot be dissatisfied. * This can be obtained by adding an OP_VERIFY to a B, modifying the last opcode of a B to its ‐VERIFY version (only for OP_CHECKSIG, OP_CHECKSIGVERIFY, OP_NUMEQUAL and OP_EQUAL), or by combining a V fragment under some conditions. * For example vc:pk_k(key) = <key> OP_CHECKSIGVERIFY * "K" Key: * Takes its inputs from the top of the stack. * Becomes a B when followed by OP_CHECKSIG. * Always pushes a public key onto the stack, for which a signature is to be provided to satisfy the expression. * For example pk_h(key) = OP_DUP OP_HASH160 <Hash160(key)> OP_EQUALVERIFY * "W" Wrapped: * Takes its input from one below the top of the stack. * When satisfied, pushes a nonzero value (like B) on top of the stack, or one below. * When dissatisfied, pushes 0 op top of the stack or one below. * Is always "OP_SWAP [B]" or "OP_TOALTSTACK [B]OP_FROMALTSTACK". * For example sc:pk_k(key) = OP_SWAP <key> OP_CHECKSIG There are type properties that help reasoning about correctness: * "z" Zero‐arg: * Is known to always consume exactly 0 stack elements. * For example after(n) = <n> OP_CHECKLOCKTIMEVERIFY * "o" One‐arg: * Is known to always consume exactly 1 stack element. * Conflicts with property 'z' * For example sha256(hash) = OP_SIZE 32 OP_EQUALVERIFY OP_SHA256 <hash> OP_EQUAL * "n" Nonzero: * For every way this expression can be satisfied, a satisfaction exists that never needs a zero top stack element. * Conflicts with property 'z' and with type 'W'. * "d" Dissatisfiable: * There is an easy way to construct a dissatisfaction for this expression. * Conflicts with type 'V'. * "u" Unit: * In case of satisfaction, an exact 1 is put on the stack (rather than just nonzero). * Conflicts with type 'V'. Additional type properties help reasoning about nonmalleability: * "e" Expression: * This implies property 'd', but the dissatisfaction is nonmalleable. * This generally requires 'e' for all subexpressions which are invoked for that dissatisfaction, and property 'f' for the unexecuted subexpressions in that case. * Conflicts with type 'V'. * "f" Forced: * Dissatisfactions (if any) for this expression always involve at least one signature. * Is always true for type 'V'. * "s" Safe: * Satisfactions for this expression always involve at least one signature. * "m" Nonmalleable: * For every way this expression can be satisfied (which may be none), a nonmalleable satisfaction exists. * This generally requires 'm' for all subexpressions, and 'e' for all subexpressions which are dissatisfied when satisfying the parent. One type property is an implementation detail: * "x" Expensive verify: * Expressions with this property have a script whose last opcode is not EQUAL, CHECKSIG, or CHECKMULTISIG. * Not having this property means that it can be converted to a V at no cost (by switching to the ‐VERIFY version of the last opcode). Five more type properties for representing timelock information. Spend paths in miniscripts containing conflicting timelocks and heightlocks cannot be spent together. This helps users detect if miniscript does not match the semantic behaviour the user expects. * "g" Whether the branch contains a relative time timelock * "h" Whether the branch contains a relative height timelock * "i" Whether the branch contains an absolute time timelock * "j" Whether the branch contains an absolute height timelock * "k" * Whether all satisfactions of this expression don't contain a mix of heightlock and timelock of the same type. * If the miniscript does not have the "k" property, the miniscript template will not match the user expectation of the corresponding spending policy. For each of these properties the subset rule holds: an expression with properties X, Y, and Z, is also valid in places where an X, a Y, a Z, an XY, ... is expected. == Member Functions [cols="1,4"] |=== | Name| Description | xref:miniscript/Type/If.adoc[`If`] | The empty type if x is false, itself otherwise. | xref:miniscript/Type/operator_bitand.adoc[`operator&`] | Compute the type with the intersection of properties. | xref:miniscript/Type/operator_bitor.adoc[`operator|`] | Compute the type with the union of properties. | xref:miniscript/Type/operator_lshift.adoc[`operator<<`] | Check whether the left hand's properties are superset of the right's (= left is a subtype of right). | xref:miniscript/Type/operator_eq.adoc[`operator==`] | Equality operator. | xref:miniscript/Type/operator_lt.adoc[`operator<`] | Comparison operator to enable use in sets/maps (total ordering incompatible with <<). |=== == Friends [cols="1,4"] |=== | Name| Description | `xref:miniscript/operator_mst.adoc[miniscript::operator""_mst]` | The only way to publicly construct a Type is using this literal operator. |=== [.small]#Created with https://www.mrdocs.com[MrDocs]#