---
title: The Scilla Standard Library
---

::: {#stdlib} The Scilla standard library contains five libraries:
`BoolUtils.scilla`, `IntUtils.scilla`, `ListUtils.scilla`, `NatUtils.scilla` and
`PairUtils.scilla`. As the names suggests these contracts implement utility
operations for the `Bool`, `IntX`, `List`, `Nat` and `Pair` types, respectively.
:::

To use functions from the standard library in a contract, the relevant library
file must be imported using the `import` declaration. The following code snippet
shows how to import the functions from the `ListUtils` and `IntUtils` libraries:

```ocaml
import ListUtils IntUtils
```

The `import` declaration must occur immediately before the contract\'s own
library declaration, e.g.:

```ocaml
import ListUtils IntUtils

library WalletLib
... (* The declarations of the contract's own library values and functions *)

contract Wallet ( ... )
... (* The transitions and procedures of the contract *)
```

Below, we present the functions defined in each of the library.

## BoolUtils

- `andb : Bool -> Bool -> Bool`: Computes the logical AND of two `Bool` values.
- `orb : Bool -> Bool -> Bool`: Computes the logical OR of two `Bool` values.
- `negb : Bool -> Bool`: Computes the logical negation of a `Bool` value.
- `bool_to_string : Bool -> String`: Transforms a `Bool` value into a `String`
  value. `True` is transformed into `"True"`, and `False` is transformed into
  `"False"`.

## IntUtils

- `intX_eq : IntX -> IntX -> Bool`: Equality operator specialised for each
  `IntX` type.

```ocaml
let int_list_eq = @list_eq Int64 in

let one = Int64 1 in
let two = Int64 2 in
let ten = Int64 10 in
let eleven = Int64 11 in

let nil = Nil {Int64} in
let l1 = Cons {Int64} eleven nil in
let l2 = Cons {Int64} ten l1 in
let l3 = Cons {Int64} two l2 in
let l4 = Cons {Int64} one l3 in

let f = int64_eq in
(* See if [2,10,11] = [1,2,10,11] *)
int_list_eq f l3 l4
```

- `uintX_eq : UintX -> UintX -> Bool`: Equality operator specialised for each
  `UintX` type.
- `intX_lt : IntX -> IntX -> Bool`: Less-than operator specialised for each
  `IntX` type.
- `uintX_lt : UintX -> UintX -> Bool`: Less-than operator specialised for each
  `UintX` type.
- `intX_neq : IntX -> IntX -> Bool`: Not-equal operator specialised for each
  `IntX` type.
- `uintX_neq : UintX -> UintX -> Bool`: Not-equal operator specialised for each
  `UintX` type.
- `intX_le : IntX -> IntX -> Bool`: Less-than-or-equal operator specialised for
  each `IntX` type.
- `uintX_le : UintX -> UintX -> Bool`: Less-than-or-equal operator specialised
  for each `UintX` type.
- `intX_gt : IntX -> IntX -> Bool`: Greater-than operator specialised for each
  `IntX` type.
- `uintX_gt : UintX -> UintX -> Bool`: Greater-than operator specialised for
  each `UintX` type.
- `intX_ge : IntX -> IntX -> Bool`: Greater-than-or-equal operator specialised
  for each `IntX` type.
- `uintX_ge : UintX -> UintX -> Bool`: Greater-than-or-equal operator
  specialised for each `UintX` type.

## ListUtils

- `list_map : ('A -> 'B) -> List 'A -> : List 'B`.

  | Apply `f : 'A -> 'B` to every element of `l : List 'A`, constructing a list
  (of type `List 'B`) of the results.

  ```ocaml
  (* Library *)
  let f =
    fun (a : Int32) =>
      builtin sha256hash a

  (* Contract transition *)
  (* Assume input is the list [ 1 ; 2 ; 3 ] *)
  (* Apply f to all values in input *)
  hash_list_int32 = @list_map Int32 ByStr32;
  hashed_list = hash_list_int32 f input;
  (* hashed_list is now [ sha256hash 1 ; sha256hash 2 ; sha256hash 3 ] *)
  ```

- `list_filter : ('A -> Bool) -> List 'A -> List 'A`.

  | Filter out elements on the list based on the predicate `f : 'A -> Bool`. If
  an element satisfies `f`, it will be in the resultant list, otherwise it is
  removed. The order of the elements is preserved.

  ```ocaml
  (*Library*)
  let f =
    fun (a : Int32) =>
      let ten = Int32 10 in
      builtin lt a ten

  (* Contract transition *)
  (* Assume input is the list [ 1 ; 42 ; 2 ; 11 ; 12 ] *)
  less_ten_int32 = @list_filter Int32;
  less_ten_list = less_ten_int32 f l
  (* less_ten_list is now  [ 1 ; 2 ]*)
  ```

- `list_head : (List 'A) -> (Option 'A)`.

  | Return the head element of a list `l : List 'A` as an optional value. If `l`
  is not empty with the first element `h`, the result is `Some h`. If `l` is
  empty, then the result is `None`.

- `list_tail : (List 'A) -> (Option List 'A)`.

  | Return the tail of a list `l : List 'A` as an optional value. If `l` is a
  non-empty list of the form `Cons h t`, then the result is `Some t`. If `l` is
  empty, then the result is `None`.

- `list_foldl_while : ('B -> 'A -> Option 'B) -> 'B -> List 'A -> 'B`

  | Given a function `f : 'B -> 'A -> Option 'B`, accumulator `z : 'B` and list
  `ls : List 'A` execute a left fold when our given function returns
  `Some x : Option 'B` using `f z x : 'B` or list is empty but in the case of
  `None : Option 'B` terminate early, returning `z`.

```ocaml
(* assume zero = 0, one = 1, negb is in scope and ls = [10,12,9,7]
 given a max and list with elements a_0, a_1, ..., a_m
 find largest n s.t. sum of i from 0 to (n-1) a_i <= max *)
let prefix_step = fun (len_limit : Pair Uint32 Uint32) => fun (x : Uint32) =>
  match len_limit with
  | Pair len limit => let limit_lt_x = builtin lt limit x in
    let x_leq_limit = negb limit_lt_x in
    match x_leq_limit with
    | True => let len_succ = builtin add len one in let l_sub_x = builtin sub limit x in
      let res = Pair {Uint32 Uint32} len_succ l_sub_x in
      Some {(Pair Uint32 Uint32)} res
    | False => None {(Pair Uint32 Uint32)}
    end
  end in
let fold_while = @list_foldl_while Uint32 (Pair Uint32 Uint32) in
let max = Uint32 31 in
let init = Pair {Uint32 Uint32} zero max in
let prefix_length = fold_while prefix_step init ls in
match prefix_length with
| Pair length _ => length
end
```

- `list_append : (List 'A -> List 'A -> List 'A)`.

  | Append the first list to the front of the second list, keeping the order of
  the elements in both lists. Note that `list_append` has linear time complexity
  in the length of the first argument list.

- `list_reverse : (List 'A -> List 'A)`.

  | Return the reverse of the input list. Note that `list_reverse` has linear
  time complexity in the length of the argument list.

- `list_flatten : (List List 'A) -> List 'A`.

  | Construct a list of all the elements in a list of lists. Each element (which
  has type `List 'A`) of the input list (which has type `List List 'A`) are all
  concatenated together, keeping the order of the input list. Note that
  `list_flatten` has linear time complexity in the total number of elements in
  all of the lists.

- `list_length : List 'A -> Uint32`

  | Count the number of elements in a list. Note that `list_length` has linear
  time complexity in the number of elements in the list.

- `list_eq : ('A -> 'A -> Bool) -> List 'A -> List 'A -> Bool`.

  | Compare two lists element by element, using a predicate function
  `f : 'A -> 'A -> Bool`. If `f` returns `True` for every pair of elements, then
  `list_eq` returns `True`. If `f` returns `False` for at least one pair of
  elements, or if the lists have different lengths, then `list_eq` returns
  `False`.

- `list_mem : ('A -> 'A -> Bool) -> 'A -> List 'A -> Bool`.

  | Checks whether an element `a : 'A` is an element in the list `l : List'A`.
  `f : 'A -> 'A -> Bool` should be provided for equality comparison.

  ```ocaml
  (* Library *)
  let f =
    fun (a : Int32) =>
    fun (b : Int32) =>
      builtin eq a b

  (* Contract transition *)
  (* Assume input is the list [ 1 ; 2 ; 3 ; 4 ] *)
  keynumber = Int32 5;
  list_mem_int32 = @list_mem Int32;
  check_result = list_mem_int32 f keynumber input;
  (* check_result is now False *)
  ```

- `list_forall : ('A -> Bool) -> List 'A -> Bool`.

  | Check whether all elements of list `l : List 'A` satisfy the predicate
  `f : 'A -> Bool`. `list_forall` returns `True` if all elements satisfy `f`,
  and `False` if at least one element does not satisfy `f`.

- `list_exists : ('A -> Bool) -> List 'A -> Bool`.

  | Check whether at least one element of list `l : List 'A` satisfies the
  predicate `f : 'A -> Bool`. `list_exists` returns `True` if at least one
  element satisfies `f`, and `False` if none of the elements satisfy `f`.

- `list_sort : ('A -> 'A -> Bool) -> List 'A -> List 'A`.

  | Sort the input list `l : List 'A` using insertion sort. The comparison
  function `flt : 'A -> 'A -> Bool` provided must return `True` if its first
  argument is less than its second argument. `list_sort` has quadratic time
  complexity.

  ```ocaml
  let int_sort = @list_sort Uint64 in

  let flt =
    fun (a : Uint64) =>
    fun (b : Uint64) =>
      builtin lt a b

  let zero = Uint64 0 in
  let one = Uint64 1 in
  let two = Uint64 2 in
  let three = Uint64 3 in
  let four = Uint64 4 in

  (* l6 = [ 3 ; 2 ; 1 ; 2 ; 3 ; 4 ; 2 ] *)
  let l6 =
    let nil = Nil {Uint64} in
    let l0 = Cons {Uint64} two nil in
    let l1 = Cons {Uint64} four l0 in
    let l2 = Cons {Uint64} three l1 in
    let l3 = Cons {Uint64} two l2 in
    let l4 = Cons {Uint64} one l3 in
    let l5 = Cons {Uint64} two l4 in
    Cons {Uint64} three l5

  (* res1 = [ 1 ; 2 ; 2 ; 2 ; 3 ; 3 ; 4 ] *)
  let res1 = int_sort flt l6
  ```

- `list_find : ('A -> Bool) -> List 'A -> Option 'A`.

  | Return the first element in a list `l : List 'A` satisfying the predicate
  `f : 'A -> Bool`. If at least one element in the list satisfies the predicate,
  and the first one of those elements is `x`, then the result is `Some x`. If no
  element satisfies the predicate, the result is `None`.

- `list_zip : List 'A -> List 'B -> List (Pair 'A 'B)`.

  | Combine two lists element by element, resulting in a list of pairs. If the
  lists have different lengths, the trailing elements of the longest list are
  ignored.

- `list_zip_with : ('A -> 'B -> 'C) -> List 'A -> List 'B -> List 'C )`.

  | Combine two lists element by element using a combining function
  `f : 'A -> 'B -> 'C`. The result of `list_zip_with` is a list of the results
  of applying `f` to the elements of the two lists. If the lists have different
  lengths, the trailing elements of the longest list are ignored.

- `list_unzip : List (Pair 'A 'B) -> Pair (List 'A) (List 'B)`.

  | Split a list of pairs into a pair of lists consisting of the elements of the
  pairs of the original list.

- `list_nth : Uint32 -> List 'A -> Option 'A`.

  | Return the element number `n` from a list. If the list has at least `n`
  elements, and the element number `n` is `x`, `list_nth` returns `Some x`. If
  the list has fewer than `n` elements, `list_nth` returns `None`.

## NatUtils

- `nat_prev : Nat -> Option Nat`: Return the Peano number one less than the
  current one. If the current number is `Zero`, the result is `None`. If the
  current number is `Succ x`, then the result is `Some x`.
- `nat_fold_while : ('T -> Nat -> Option 'T) -> 'T -> Nat -> 'T`: Takes
  arguments `f : 'T -> Nat -> Option 'T`, `` z : `T `` and `m : Nat`. This is
  `nat_fold` with early termination. Continues recursing so long as `f` returns
  `Some y` with new accumulator `y`. Once `f` returns `None`, the recursion
  terminates.
- `is_some_zero : Nat -> Bool`: Zero check for Peano numbers.
- `nat_eq : Nat -> Nat -> Bool`: Equality check specialised for the `Nat` type.
- `nat_to_int : Nat -> Uint32`: Convert a Peano number to its equivalent
  `Uint32` integer.
- `uintX_to_nat : UintX -> Nat`: Convert a `UintX` integer to its equivalent
  Peano number. The integer must be small enough to fit into a `Uint32`. If it
  is not, then an overflow error will occur.
- `intX_to_nat : IntX -> Nat`: Convert an `IntX` integer to its equivalent Peano
  number. The integer must be non-negative, and must be small enough to fit into
  a `Uint32`. If it is not, then an underflow or overflow error will occur.

## PairUtils

- `fst : Pair 'A 'B -> 'A`: Extract the first element of a Pair.

```ocaml
let fst_strings = @fst String String in
let nick_name = "toby" in
let dog = "dog" in
let tobias = Pair {String String} nick_name dog in
fst_strings tobias
```

- `snd : Pair 'A 'B -> 'B`: Extract the second element of a Pair.

## Conversions

This library provides conversions b/w Scilla types, particularly between
integers and byte strings.

To enable specifying the encoding of integer arguments to these functions, a
type is defined for endianness.

```ocaml
type IntegerEncoding =
  | LittleEndian
  | BigEndian
```

The functions below, along with their primary result, also return
`next_pos : Uint32` which indicates the position from which any further data
extraction from the input `ByStr` value can proceed. This is useful when
deserializing a byte stream. In other words, `next_pos` indicates where this
function stopped reading bytes from the input byte string.

- `substr_safe : ByStr -> Uint32 -> Uint32 -> Option ByStr` While Scilla
  provides a builtin to extract substrings of byte strings (`ByStr`), it is not
  exception safe. When provided incorrect arguments, it throws exceptions. This
  library function is provided as an exception safe function to extract, from a
  string `s : ByStr`, a substring starting at position `pos : Uint32` and of
  length `len : Uint32`. It returns `Some ByStr` on success and `None` on
  failure.
- `extract_uint32 : IntegerEncoding -> ByStr -> Uint32 -> Option (Pair Uint32 Uint32)`
  Extracts a `Uint32` value from `bs : ByStr`, starting at position
  `pos : Uint32`. On success, `Some extracted_uint32_value next_pos` is
  returned. `None` otherwise.
- `extract_uint64 : IntegerEncoding -> ByStr -> Uint32 -> Option (Pair Uint64 Uint32)`
  Extracts a `Uint64` value from `bs : ByStr`, starting at position
  `pos : Uint32`. On success, `Some extracted_uint64_value next_pos` is
  returned. `None` otherwise.
- `extract_uint128 : IntegerEncoding -> ByStr -> Uint32 -> Option (Pair Uint128 Uint32)`
  Extracts a Uint128 value from `bs : ByStr`, starting at position
  `pos : Uint32`. On success, `Some extracted_uint128_value next_pos` is
  returned. `None` otherwise.
- `extract_uint256 : IntegerEncoding -> ByStr -> Uint32 -> Option (Pair Uint256 Uint32)`
  Extracts a `Uint256` value from `bs : ByStr`, starting at position
  `pos : Uint32`. On success, `Some extracted_uint256_value next_pos` is
  returned. `None` otherwise.
- `extract_bystr1 : ByStr -> Uint32 -> Option (Pair ByStr1 Uint32)` Extracts a
  `ByStr1` value from `bs : ByStr`, starting at position `pos : Uint32`. On
  success, `Some extracted_bystr1_value next_pos` is returned. `None` otherwise.
- `extract_bystr2 : ByStr -> Uint32 -> Option (Pair ByStr2 Uint32)` Extracts a
  `ByStr2` value from `bs : ByStr`, starting at position `pos : Uint32`. On
  success, `Some extracted_bystr2_value next_pos` is returned. `None` otherwise.
- `extract_bystr20 : ByStr -> Uint32 -> Option (Pair ByStr20 Uint32)` Extracts a
  `ByStr2` value from `bs : ByStr`, starting at position `pos : Uint32`. On
  success, `Some extracted_bystr20_value next_pos` is returned. `None`
  otherwise.
- `extract_bystr32 : ByStr -> Uint32 -> Option (Pair ByStr32 Uint32)` Extracts a
  `ByStr2` value from `bs : ByStr`, starting at position `pos : Uint32`. On
  success, `Some extracted_bystr32_value next_pos` is returned. `None`
  otherwise.
- `append_uint32 : IntegerEncoding -> ByStr -> Uint32 -> ByStr` Serialize a
  `Uint32` value (with the specified encoding) and append it to the provided
  `ByStr` and return the result `ByStr`.
- `append_uint64 : IntegerEncoding -> ByStr -> Uint32 -> ByStr` Serialize a
  `Uint64` value (with the specified encoding) and append it to the provided
  `ByStr` and return the result `ByStr`.
- `append_uint128 : IntegerEncoding -> ByStr -> Uint32 -> ByStr` Serialize a
  `Uint128` value (with the specified encoding) and append it to the provided
  `ByStr` and return the result `ByStr`.
- `append_uint256 : IntegerEncoding -> ByStr -> Uint32 -> ByStr` Serialize a
  `Uint256` value (with the specified encoding) and append it to the provided
  `ByStr` and return the result `ByStr`.

## Polynetwork Support Library

This library provides utility functions used in building the Zilliqa Polynetwork
bridge. These functions are migrated from
[Polynetwork\'s ethereum support](https://github.com/polynetwork/eth-contracts/tree/master/contracts/core/cross_chain_manager),
with the contract itself separately deployed.
