Built-in Types and Functions

Built-in Types

The listing below defines the built-in types in UPLC.

a ∈ Atomic type ::= integer
                  | bytestring
                  | string
                  | bool
                  | unit
                  | data
                  | πš‹πš•πšœπŸ·πŸΈ_𝟹𝟾𝟷_π™ΆπŸ·_πšŽπš•πšŽπš–πšŽπš—πš
                  | πš‹πš•πšœπŸ·πŸΈ_𝟹𝟾𝟷_π™ΆπŸΈ_πšŽπš•πšŽπš–πšŽπš—πš
                  | πš‹πš•πšœπŸ·πŸΈ_𝟹𝟾𝟷_πš–πš•πš›πšŽπšœπšžπš•πš

T ∈ Built-in type ::= a
                    | list(T)
                    | pair(T, T)

The following table shows the values and concrete syntaxes of the types and type operators:

Type 𝑇ValueConcrete Syntax 𝐂(𝑇)
integerβ„€-?[0-9]+
bytestringthe set of sequences of bytes or 8-bit characters#([0-9A-Fa-f][0-9A-Fa-f])*
stringthe set of sequences of Unicode characterssee below
bool{true, false}True | False
unit{()}()
datasee belowsee below
πš‹πš•πšœπŸ·πŸΈ_𝟹𝟾𝟷_π™ΆπŸ·_πšŽπš•πšŽπš–πšŽπš—πšπΊβ‚0x[0-9A-Fa-f]{96} (see below)
πš‹πš•πšœπŸ·πŸΈ_𝟹𝟾𝟷_π™ΆπŸΈ_πšŽπš•πšŽπš–πšŽπš—πšπΊβ‚‚0x[0-9A-Fa-f]{192} (see below)
πš‹πš•πšœπŸ·πŸΈ_𝟹𝟾𝟷_πš–πš•πš›πšŽπšœπšžπš•πšπ»see below

For the definitions of 𝐺₁, 𝐺₂ and 𝐻, refer to the Plutus Core Spec.

In the following, we use 𝑐(𝑇) ∈ 𝐂(𝑇) to denote a valid representation of a constant of type 𝑇.

Concrete Syntax for Strings

Strings are represented as sequences of Unicode characters enclosed in double quotes, and may include standard escape sequences. Surrogate characters in the range U+D800 - U+DFFF are replaced with the Unicode replacement character U+FFFD.

Concrete Syntax for Lists and Pairs

A list of type list(𝑑) is written as a syntactic list [𝑐₁, … ,𝑐ₙ], where each 𝑐ᡒ ∈ 𝐂(𝑑).

A pair of type pair(𝑑₁, 𝑑₂) is written as a syntactic pair (𝑐₁, 𝑐₂) where 𝑐₁ ∈ 𝐂(𝑑₁) and 𝑐₂ ∈ 𝐂(𝑑₂).

Some valid constant expressions are:

  • (con (list integer) [11, 22, 33])
  • (con (pair bool string) (True, "Plutus"))
  • (con (list (pair bool (list bytestring))) [(True, []), (False, [#,#1F]), (True, [#123456, #AB, #ef2804])])

The data Type

We provide a built-in type, data, which permits the encoding of simple data structures for use as arguments to Plutus Core scripts. The Haskell definition of data can be found in PlutusCore.Data.

Concrete Syntax for data

The concrete syntax for 𝚍𝚊𝚝𝚊 is given by

𝑐(𝚍𝚊𝚝𝚊) ∢∢= (Constr 𝑐(πš’πš—πšπšŽπšπšŽπš›) 𝑐(πš•πš’πšœπš(𝚍𝚊𝚝𝚊)))
          | (Map 𝑐(πš•πš’πšœπš(πš™πšŠπš’πš›(𝚍𝚊𝚝𝚊,𝚍𝚊𝚝𝚊))))
          | (List 𝑐(πš•πš’πšœπš(𝚍𝚊𝚝𝚊)))
          | (I 𝑐(πš’πš—πšπšŽπšπšŽπš›))
          | (B 𝑐(πš‹πš’πšπšŽπšœπšπš›πš’πš—πš)).

Some valid data constants are:

  • (con data (Constr 1 [(I 2), (B #), (Map [])]))
  • (con data (Map [((I 0), (B #00)), ((I 1), (B #0F))]))
  • (con data (List [(I 0), (I 1), (B #7FFF), (List []])))
  • (con data (I -22))
  • (con data (B #001A))

Concrete syntax for BLS12-381 Types

The concrete syntaxes for πš‹πš•πšœπŸ·πŸΈ_𝟹𝟾𝟷_π™ΆπŸ·_πšŽπš•πšŽπš–πšŽπš—πš and πš‹πš•πšœπŸ·πŸΈ_𝟹𝟾𝟷_π™ΆπŸΈ_πšŽπš•πšŽπš–πšŽπš—πš are provided only for use in textual Plutus Core programs, for example for experimentation and testing. We do not support constants of any of the BLS12-381 types in serialised programs.

If you need to put πš‹πš•πšœπŸ·πŸΈ_𝟹𝟾𝟷_π™ΆπŸ·_πšŽπš•πšŽπš–πšŽπš—πš and πš‹πš•πšœπŸ·πŸΈ_𝟹𝟾𝟷_π™ΆπŸΈ_πšŽπš•πšŽπš–πšŽπš—πš in your script, you can instead use the appropriate uncompression function on a bytestring constant.

No concrete syntax is provided for values of type πš‹πš•πšœπŸ·πŸΈ_𝟹𝟾𝟷_πš–πš•πš›πšŽπšœπšžπš•πš. It is not possible to parse such values, and they will appear as (con bls12_381_mlresult <opaque>) if output by a program.

Built-in Functions

Plutus includes a set of built-in functions. Like in Haskell, these can be polymorphic, accepting both type and term arguments. However, Plutus distinguishes between two kinds of type arguments:

  • A built-in-polymorphic type argument (denoted as π‘Ž#, 𝑏# etc. in the spec) is limited to built-in types.
  • A fully-polymorphic type argument (denoted as βˆ— in the spec) represents arbitrary terms.

βˆ— can not be used as an argument to a type operator. For instance, list(βˆ—) is not allowed, whereas list(π‘Ž#) and pair(π‘Ž#, integer) are valid.

A term argument of type βˆ— can be any UPLC term. Multiple arguments of type βˆ— are independent and need not be related. All other term arguments must be UPLC constants of the appropriate types. For example, an argument of type pair(π‘Ž#, π‘Ž#) must be a pair constant, where both components are constants of the same built-in type.

A built-in function returns an application consisting of a head and zero or more arguments. Most built-in functions returns a single value, which corresponds to an application with zero argument. Each of the head and the arguments may be either a UPLC constant, or of type βˆ—. If it is of type βˆ—, it must be one of the arguments passed to the built-in function, unmodified.

Take built-in function ifThenElse as an example. It has signature [βˆ€βˆ—, πš‹πš˜πš˜πš•, βˆ—, βˆ—] β†’ βˆ—. Thus it takes three term arguments: a bool constant, followed by two arbitrary terms. Since its return type is βˆ—, the result must be either the second argument or the third argument.

As another example, built-in function mkCons has signature [βˆ€π‘Ž#, π‘Ž#, πš•πš’πšœπš(π‘Ž#)] β†’ πš•πš’πšœπš(π‘Ž#), indicating that it takes a constant of some type, and a list constant whose elements are of the same type. The result is a list constant of the same element type.

Type arguments are not passed explicitly when calling a built-in function. In UPLC, type instantiation is achieved via the force construct.

Because introducing built-in functions requires a hard fork, each built-in function is introduced in a specific major protocol version. For example, integerToByteString was introduced in major protocol version 9 (following the Chang hard fork). Moreover, not all built-in functions are available in every Plutus ledger language version (Plutus V1, V2, V3). Scripts using an unavailable built-in function will be rejected by the Cardano node. More details will be provided in Script Deserialization and Execution.

For the full list of UPLC built-in functions, their signatures, semantics, and supported Plutus ledger language versions and protocol versions, refer to the Plutus Core Spec, Section 4.3 (Built-in types and functions).