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 π | Value | Concrete Syntax π(π) |
---|---|---|
integer | β€ | -?[0-9]+ |
bytestring | the set of sequences of bytes or 8-bit characters | #([0-9A-Fa-f][0-9A-Fa-f])* |
string | the set of sequences of Unicode characters | see below |
bool | {true, false} | True | False |
unit | {()} | () |
data | see below | see 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).