# Reference Manual - SmartPy.io

SmartPy is an intuitive and powerful smart contract development platform for Tezos.

The SmartPy language is available through a Python library for building and analyzing Tezos smart contracts.
It comes with various tools: a compiler that generates Michelson code, a simulation engine, a contract explorer, etc.

# Building Blocks

SmartPy is a Python library. SmartPy scripts are regular Python scripts that use SmartPy constructions.
This mechanism is useful because it brings very powerful meta-programming capabilities, as explained later.

## Expressions

Like most languages, SmartPy has expressions. For example `self.data.x` represents the contract storage field `x` and `2` represents the number 2, whereas `self.data.x + 2` represents their sum.

Inside a contract, when we write

            y = self.data.x + 2

we declare `y` as an alias the SmartPy expression `self.data.x + 2`.
This is not a command for SmartPy.

## Commands

Commands do something. For example,

            sp.verify(self.data.x > 2)

checks that the field `x` is larger than `2` and raises an error if it isn’t. This is performed at run time, i.e., in the blockchain, once translated into Michelson.

## Entry Points

An entry point is a method of a contract class that can be called from the outside. Entry points need to be marked with the `@sp.entry_point` decorator. For example, the following entry point checks that the argument given is larger than `2`:

        @sp.entry_point
        def check_big_enough(self, params):
            sp.verify(params > 2)

`sp.entry_point`

  Decorator to introduce an entry point.

See reference Store Value template for simple entry points examples.

`sp.entry_point` can also take optional parameters such as an alternative string `name`, bool `private`, `lazify` and `lazy_no_code` flags.

        @sp.entry_point(name = "another_name", private = True)
        def check_big_enough(self, params):
            sp.verify(params > 2)

We can restrict an entry point to only appear in SmartPy but not in the generated Michelson contract. This is useful to implement checks or initialization in SmartPy after origination in the test but before real blockchain origination. One can use the full SmartPy machinery such as `sp.verify`, etc.
See reference Private Entry Point template.

This is also useful to build custom UI through simulation by adding:

        @sp.entry_point(private = True)
        def set_y(self, params):
            self.data.y = params

### Return values

Entry points do not return values in Michelson.
SmartPy respects this constraint but allows other functions to return values.
These functions typically use `sp.result(value)` to return `value`.
See Lambdas for examples with `sp.global_lambda` and `sp.sub_entry_point`.

### Lazy and updatable entry points

Lazy and updatable entry points are similar to regular SmartPy entry points with two special abilities: they are loaded on-demand (this reduces gas usage) and can be updated with specific operators.

See reference Lazy entry points template.

#### Default behavior

Entry points can all be "lazified" by default by using the flag `"lazy-entry-points"` but it’s usually smarter to select the lazy entry points.
See example in Send back template.

#### Declaring a lazy entry point

We can ask SmartPy to "lazify" an entry point:

    @sp.entry_point(lazify = True)

Furthermore, a lazy entry point can be initially excluded from the big map:

    @sp.entry_point(lazify = True, lazy_no_code = True)

In this case, calling it will result in an error until it has been updated.

#### Updating entry points

In order to perform an update in a scenario, we first define the new entry point as a function, e.g.:

    def f(self, params):
        sp.verify(params == 42)

`sp.set_entry_point(name, entry_point)`

  Update the lazy entry point called `name` (which must be a constant string) with the code in `entry_point`.
  The code is stored as a lambda inside a big map that is part of the contract’s storage. Such an entry point can be updated (from inside any non-lazy entry point), e.g.:

    @sp.entry_point
    def update_ep(self, new_code):
        sp.verify(sp.sender == self.data.admin)
        sp.set_entry_point("ep", new_code)

`sp.utils.wrap_entry_point(name, entry_point)`

  A wrapper to prepare the a python function to be used as an update for entry point `name` (which must be a constant string).

    c.update_ep(sp.utils.wrap_entry_point("ep", f))

`sp.has_entry_point(name)`

  Return a boolean expression that indicates whether an entry point called `name` (which must be a constant string) is presently part of the big map.

## Contracts

A SmartPy contract consists of a state together with one or several entry points. It is a class definition that inherits from `sp.Contract`. The constructor (`__init__`) makes a call to `self.init` and initializes fields that make up the contract’s state.

    class Hello(sp.Contract):
        def __init__(self):
            self.init(x = 0)

        @sp.entry_point
        def set_x(newX):
            self.data.x = newX

        @sp.entry_point
        def check_largerthan_x(p):
            sp.verify(p > self.data.x)

`self.init(..)`

  Alias for `self.init_storage(arg = None, **kwargs)`

`self.init_storage(arg = None, **kwargs)`

  Set the storage of a contract with no initial storage. `arg` and `kwargs` cannot be both present. `kwargs` is a dictionary of fields that are added to the storage (or removed when value is `None`).
  There are two different ways to call `self.init_storage` in a contract:

  - on a single value `self.init_storage(arg)` where `arg` is a SmartPy expression;

  - on a list of fields with values, `self.init_storage(**kwargs)` where `kwargs` is a dictionary.

`self.update_initial_storage(arg = None, **kwargs)`

  Update the storage of a contract. `arg` and `kwargs` cannot be both present. `kwargs` is a dictionary of fields that are added to the storage (or removed when value is `None`).
  `self.update_initial_storage(e)` replaces the former storage while `self.update_initial_storage(**kwargs)` expects the former storage to be a record and adds, changes or removes (when value is `None`) former fields. This is very useful when we use complex inheritance patterns.

    class Hello(sp.Contract):
        def __init__(self):
            """ Alias for init_storage. """
            self.init(x = 0)

    class Hello(sp.Contract):
        def __init__(self):
            """ Initialize the storage to a record containing
                a single field x of value 0. """
            self.init_storage(x = 0)

    class Hello(sp.Contract):
        def __init__(self):
            """ It's allowed to call update_initial_storage even if no storage is defined. """
            self.update_initial_storage(x = 0)

    class Hello(sp.Contract):
        def __init__(self):
            self.init_storage(x = 0, y = 1)

    class Hello(sp.Contract):
        def __init__(self):
            """ Define x then add y. """
            self.init_storage(x = 0)
            self.update_initial_storage(y = 1)

    class Hello(sp.Contract):
        def __init__(self):
            """ Define x and t then remove x and add y. """
            self.init_storage(x = 0, t = 12)
            self.update_initial_storage(x = None, y = 1)

`self.init_type(t)`

  See Setting a type constraint in SmartPy.

## Types

Types are usually automatically infered and not explicitly needed. SmartPy types are all of the form `sp.T<TypeName>`.

## Meta-Programming

The functions described here are used to construct a smart contract. Smart contracts are executed once they are deployed in the Tezos blockchain (although they can be simulated). This is indeed meta-programming: we can write a program that writes a program, i.e., constructs a contract.

Note that in the example `self.data.x + 2`, the actual addition isn’t carried out until the contract has been deployed and the entry point is called.

## Constants vs Expressions

It is usually quite natural when an expression needs to be computed on-chain vs a constant that is readily available.
By default, SmartPy fully computes at compile time expressions that are put in the storage and doesn’t compute regular expressions that appear in smart contracts.

However, this behavior is not always desired or even possible.

Some specific expressions (such as `sp.make_signature`, see Signatures) need to be computed at compile time since there is no corresponding construction in Michelson. This is done automatically for mandatory ones.

This computation can be forced by using `sp.to_constant(..)`.

`sp.to_constant(e)`

  Force computation of `e` at compile time.

# Typing

## Type Inference

Just like in Python, most of the time there is no need to specify the type of an object in SmartPy. For a number of reasons (e.g., because SmartPy’s target language, Michelson, requires types), each SmartPy expression does however need a type. Therefore SmartPy uses type inference in order to determine each expressions type.

In practice, this means that information about an expression is gathered according to its usage: for example, when somewhere in your contract you write `self.data.x == "abc"`, SmartPy will automatically determine and remember that `self.data.x` is a string.

Note that SmartPy types are distinct from Python types: `self.data.x == "abc"` has the Python type `sp.Expr` (simply because it is a SmartPy expression), whereas it has the SmartPy type `sp.TBool` (see below).

While most of the time the user will not write many types explicitly it is beneficial to at least have a basic understanding of what they are. This also helps understanding error messages better.

## Primitive Data Types Overview

SmartPy has the following primitive types:

`sp.TUnit`

  A type with a single value, namely `sp.unit`.
  See Unit.

`sp.TBool`

  The type of boolean values, `True`, `False`, `sp.bool(True)` and `sp.bool(False)`.
  See Booleans.

`sp.TInt`

  The type of integer values, e.g. `-42` or `sp.int(-42)`.
  See Integers.

`sp.TNat`

  The type of non-negative integer values, e.g. `sp.nat(42)`.
  See Integers.

`sp.TIntOrNat`

  The type of integer values whose type is still undetermined between `sp.TInt` or `sp.TNat`, e.g. `42` or `sp.intOrNat(42)`.
  See Integers.

`sp.TString`

  The type of strings, e.g. `"abc"` or `sp.string("abc")`.
  See Strings.

`sp.TBytes`

  The type of serialized data, e.g. `sp.pack(42)`.
  See Bytes.

## Container Types

SmartPy has a few built-in data structures. Their types are:

`sp.TPair`

  The type of pairs, e.g. `(1, True)`.
  See Pairs.

`sp.TList`

  The type of lists, e.g. `[1, 2, 3]`.
  See Lists.

`sp.TSet`

  The type of sets, e.g. `{1, 2, 3}`.
  See Sets.

`sp.TMap`

  The type of maps, e.g. `{'A': 65, 'B': 66, 'C'; 67}`.
  See Maps.

`sp.TBigMap`

  The type of lazy maps.
  See Big Maps.

`sp.TOption`

  The type of optional values.
  See Options.

There is no array in SmartPy because they are missing in Michelson, we usually use maps instead. There are three helper functions: `sp.utils.vector(..)`, `sp.utils.matrix(..)` and `sp.utils.cube(..)` that take respectively a list, a list of lists and a list of lists of lists and return maps.

Convention. Container constructor names are uncapitalized and their types are capitalized. `sp.map(…​)` of type `sp.TMap(…​)`, `sp.big_map(…​)` of type `sp.TBigMap(…​)`, `sp.set(…​)` of type `sp.TSet(…​)`, `sp.list(…​)` of type `sp.TList`, `sp.pair(…​)` of type `sp.TPair(…​)`, etc.

## Tezos-specific data types

A few data types are important in the context of smart contracts:

`sp.TMutez`

  The type of Tezos tokens, e.g. `sp.mutez(42000)` stands for 0.042 Tez, wheras `sp.tez(42)` stands for 42 Tez.
  See Mutez.

`sp.TTimestamp`

  A moment in time, e.g. `sp.timestamp(1571761674)`. The argument to `sp.timestamp` is in "epoch" format, i.e. seconds since 1970-01-01.
  See Timestamps.

`sp.TAddress`

  An address of a contract or account, e.g. `sp.address("tz1YtuZ4vhzzn7ssCt93Put8U9UJDdvCXci4")`.
  See Contracts and Addresses.

`sp.TContract(t)`

  A contract whose parameter is of type `t`.
  See Contracts and Addresses.

`sp.TKey`

  A public cryptographic key.
  See Keys.

`sp.TKeyHash`

  The hash of a public cryptographic key.
  See Key Hash.

`sp.TSignature`

  A cryptographic signature.
  See Signatures.

`sp.TChainId`

  The type of chain identifiers, i.e., small identifiers for the different main and test Tezos blockchains.
  See Chain Id.

`sp.TSecretKey`

  The type of secret keys. Secret keys cannot appear in smart contracts but Tests and Scenarios use them.
  See Secret Key.

`sp.TSaplingState(memo_size = None)`
`sp.TSaplingTransaction(memo_size = None)`

  Types for Sapling integration.
  See Sapling Integration.

`sp.TBls12_381_g1`
`sp.TBls12_381_g2`

  Points on the BLS12-381 curves G1 and G2, respectively.
  Written as raw bytes, using a big-endian point encoding, as specified `here`.

`sp.TBls12_381_fr`

  An element of the scalar field Fr, used for scalar multiplication on the BLS12-381 curves G1 and G2.
  Written as raw bytes, using a little-endian encoding.
  See BLS12-381.

## Record types, Variant types and layouts

In SmartPy, we can use custom data types called records and variants.
Records and variants are translated in Michelson into binary trees of `pair` and `or` with annotations corresponding to each field.
The geometry of these binary trees is described by a layout.

### Layouts

A layout is a Python expression listing all fields or constructors in a binary tree structure such as `("b", ("a", "c"))`.
There is no equivalent instruction in Michelson.
See reference Data Type Layouts template.

The SmartPy compiler recognizes a special format `"<source> as <target>"` to translate field names between SmartPy and Michelson. A specific case `"<source> as"` is also supported to generate annotation-less types.
See FA1.2 template.

### Record types

A record type represents a cartesian product of several types similar to a struct in `C` with a layout.
Please see the Records section.

`sp.TRecord(**fields)`

  A record type is introduced by enumerating the field names together with types, e.g., `sp.TRecord(x = sp.TInt, y = sp.TInt)`.
  A `sp.TRecord(**fields)` uses the default layout as determined by SmartPy (today a binary tree, it will change in the future).

`.layout(layout)`

  A record type, i.e. something of the form `sp.TRecord(…​)`, can be used to define a record type with a layout by doing:

        t = sp.TRecord(owner    = sp.TAddress,
                       operator = sp.TAddress,
                       token_id = sp.TString)
        t_with_layout = t.layout(("owner", ("operator", "token_id")))

`.right_comb()`

  Like `.layout(..)` but the geometry used is `(f1, (f2, .. (f_{k-1}, f_k)))))`, the list of fields is determined automatically and sorted alphabetically.

`.with_fields(**fields)`

  Add some fields to the `TRecord(..)` where `fields` is a Python (string, type)-dictionary of fields.

`.without_fields(fields)`

  Remove some fields from the `TRecord(..)` where `fields` is a Python list of fields.

### Variant types

A variant type represents a union of several choices, similar to a clean version of a struct with an enum/union pattern in `C`.
Please see Variants.

`sp.TVariant(**fields)`

  A variant type is introduced by enumerating the constructor names together with their inner types, e.g. `sp.TVariant(default_choice = sp.TInt, alternative_choice = sp.TString)`.
  A `sp.TVariant(**fields)` uses the default layout as determined by SmartPy (today a binary tree, it will change in the future).

`.layout(layout)`

  Similar to what happens for `TRecord`.

`.right_comb(layout)`

  Similar to what happens for `TRecord`.

## Setting a type constraint in SmartPy

This is usually not needed for small contracts or prototypes but gets useful typically when interacting with the outside world, implementing a given interface, etc.

`self.init_type(t)`

  Constrain the contract storage to be of type `t` (called in the `__init__` constructor).
  This is useful because it allows the user to make the storage type explicit or even to define storage-less contracts.
  In a test, if not determined in the `__init__` method, the storage can be initialized by calling `c.init_storage(expression)`.
  See reference Init Type Only template.
  This is not mandatory but is appreciated by many in practice.

        class MyContract(sp.Contract):
        def __init__(self):
            ## Possibly set the storage type
            self.init_type(sp.TRecord(a = sp.TInt, b = sp.TString))
            ## Possibly set the storage
            self.init(...)

`sp.set_type(expression, t)`

  Constrain `expression` to be of type `t`. This can only be used as a command inside a contract.
  There is no equivalent instruction in Michelson.
  A usual pattern for big contracts is to explicitly setting types in the first lines of entry points.
  This is usually not needed but is appreciated by many in practice.

        @sp.entry_point
        def my_entry_point(self, x, y, z):
            ## First set types
            sp.set_type(x, sp.TInt)
            sp.set_type(y, sp.TString)
            sp.set_type(z, sp.TList(sp.TInt))
            ## Then do the computations
            ...

`sp.set_result_type(t)`

  Wrap a block of commands and constrain its result type to `t`. This can only be used as a command inside a contract.
  There is no equivalent instruction in Michelson.
  This is e.g. useful for making types of failures explicit.

        @sp.global_lambda
        def oh_no(params):
            with sp.set_result_type(sp.TInt):
               sp.if params > 0:
                  sp.failwith("too big")
               sp.else:
                  sp.failwith("too small")

`sp.set_type_expr(expression, t)`

  Constrain `expression` to be of type `t`. This can only be used as an expression.
  There is no equivalent instruction in Michelson.

A few words of caution about the differences between `sp.set_type` and `sp.set_type_expr`:

    # Inside a contract:

        @sp.entry_point
        def my_entry_point(self, params):
            ...
            ## Warning: this is not taken into account (the expression is simply dropped).
            sp.set_type_expr(params, sp.TInt)
            ...

        @sp.entry_point
        def my_entry_point(self, params):
            ...
            ## This is taken into account (when we call params afterward).
            params = sp.set_type_expr(params, sp.TInt)
            ... params ...

        @sp.entry_point
        def my_entry_point(self, params):
            ...
            ## This is taken into account (sp.set_type is a command).
            sp.set_type(params, sp.TInt) ## This is taken into account.
            ...

    # Inside a test scenario:

        scenario += ...
        ## This is illegal (command outside of a contract).
        sp.set_type(..., ...)

        ## This is OK (usually useless nonetheless)
        x = sp.set_type_expr(..., ...)
        scenario += c.f(x)

Containers have built-in optional constraint arguments.

`sp.map(l = …​, tkey = …​, tvalue = …​)`

  Define a map of (optional) elements in `l` with optional key type `tkey` and optional value type `tvalue`.

`sp.big_map(l = …​, tkey = …​, tvalue = …​)`

  Define a big_map of (optional) elements in `l` with optional key type `tkey` and optional value type `tvalue`.

`sp.set(l = …​, t = …​)`

  Define a set of (optional) elements in `l` with optional element type `t`.

`sp.list(l = …​, t = …​)`

  Define a list of (optional) elements in `l` with optional element type `t`.

## Bounded types

SmartPy has the ability to limit any simple type’s values to a finite subset. For example, the type `sp.TBounded(["red", "green", "blue"])` has exactly three values: `sp.bounded("red")`, `sp.bounded("green")`, `sp.bounded("blue")`.

`sp.unbounded` expects a bounded value and returns its unbounded equivalent, e.g. it goes from `sp.bounded("red")` to just "red" (of type `sp.TString`).

Note that bounded types can be based on any simple type, e.g. `sp.TBounded([1,2,3])` possible as well.

There is no cost associated to bounded types and values when compiling to Michelson.

# Types and Operators

SmartPy expressions have the Python type `sp.Expr`. In this class many methods are overloaded so to provide convenient syntax: e.g. we can write `self.data.x + 2` for the SmartPy expression that represents the sum of the storage field `x` and 2.

The on-chain evaluation of an expression does not have any side effects except a possible failure (such as accessing a missing element in a map).

Any Python literal (string or integer) that is used in place of an `sp.Expr` is automatically converted. Thus we can write `self.data.x + 1` instead of `self.data.x + sp.int(1)`.

## BLS12-381

BLS12-381 is a paring-friendly elliptic curve.
SmartPy supports all associated Michelson types and constructions including in tests in the interpreter.
See reference BLS12 template.

### Types

`sp.TBls12_381_fr`

  An element of the scalar field Fr, used for scalar multiplication on the BLS12-381 curves G1 and G2.
  Written as raw bytes, using a little-endian encoding.
  See Michelson `bls12_381_fr`.

`sp.TBls12_381_g1`
`sp.TBls12_381_g2`

  Points on the BLS12-381 curves G1 and G2, respectively.
  Written as raw bytes, using a big-endian point encoding, as specified `here`.
  See Michelson `bls12_381_g1`, `bls12_381_g2`.

### Operations

`- e`

  Negate a curve point or field element.
  Supported types: `sp.TBls12_381_g1` | `sp.TBls12_381_g2` | `sp.TBls12_381_fr`
  See Michelson `NEG`.

`sp.to_int(n)`

  Convert a `sp.TBls12_381_fr` into an `sp.TInt`.
  See Michelson `INT`.

`n + m`

  Add two curve points or field elements.

  Adding `sp.TBls12_381_g1` with `sp.TBls12_381_g1` originates `sp.TBls12_381_g1`
  Adding `sp.TBls12_381_g2` with `sp.TBls12_381_g2` originates `sp.TBls12_381_g2`
  Adding `sp.TBls12_381_fr` with `sp.TBls12_381_fr` originates `sp.TBls12_381_fr`

  See Michelson `ADD`.

`sp.mul(n, m)`

  Multiply a curve point or field element by a scalar field element.

  Multiplying `sp.TBls12_381_g1` with `sp.TBls12_381_fr` originates `sp.TBls12_381_g1`
  Multiplying `sp.TBls12_381_g2` with `sp.TBls12_381_fr` originates `sp.TBls12_381_g2`
  Multiplying `sp.TBls12_381_fr` with `sp.TBls12_381_fr` originates `sp.TBls12_381_fr`
  Multiplying `sp.TInt` with `sp.TBls12_381_fr` originates `sp.TBls12_381_fr`
  Multiplying `sp.TNat` with `sp.TBls12_381_fr` originates `sp.TBls12_381_fr`
  Multiplying `sp.TBls12_381_fr` with `sp.TInt` originates `sp.TBls12_381_fr`
  Multiplying `sp.TBls12_381_fr` with `sp.TNat` originates `sp.TBls12_381_fr`

  See Michelson `MUL`.

`sp.pairing_check(pairs)`

  Verify that the product of pairings of the given list of points is equal to 1 in Fq12. Returns true if the list is empty. Can be used to verify if two pairings P1 and P2 are equal by verifying P1 * P2^(-1) = 1.

  pairs must be of type `sp.TList(sp.TPair(sp.TBls12_381_g1, sp.TBls12_381_g2))`

  See Michelson `PAIRING_CHECK`.

## Booleans

The type of SmartPy booleans is `sp.TBool`.
The corresponding type in Michelson is `bool`.

SmartPy has the following logical operators:

Literals: `True, False`

  The usual way to input bool literals in SmartPy.

Literals: `sp.bool(b)`

  A literal of type `sp.TBool` when `b` is a Python bool literal (`True` or `False`).

`~ e`

  Return the negation of `e`, where `e` must be a boolean.
  See Michelson `NOT`.

`e1 | e2`

  Return `True` if `e1` is `True`, otherwise `e2`. Both `e1` and `e2` must be booleans.
  SmartPy uses a lazy version of Michelson `OR`.

`e1 & e2`

  Return `False` if `e1` is `False`, otherwise `e2`. Both `e1` and `e2` must be booleans.
  SmartPy uses a lazy version of Michelson `AND`.

`e1 ^ e2`

  Compute `e1` xor `e2`.
  See Michelson `XOR`.

Note that, unlike in Python, `&` and `|` do short-circuiting on SmartPy boolean expressions: for example, the evaluation of `(x==x) | (self.data.xs[2] == 0))` will not fail.

Also, please note that `not`, `and`, and `or` cannot be overloaded in Python. Hence, we cannot use them to construct SmartPy expressions and, as is customary for custom Python libraries, we use `~`, `&`, and `|` instead.

## Bytes

The type of byte arrays in SmartPy is `sp.TBytes`.
The corresponding type in Michelson is `bytes`.

See reference Strings and Bytes template.

Literals: `sp.bytes('0x…​')`

  Introduce a `sp.TBytes` in hexadecimal notation.

`e1 + e2`

  Concatenate two bytes.
  See Michelson `CONCAT`.

`sp.concat(l)`

  Concatenate a list `l` of `sp.TBytes`.
  See Michelson `CONCAT`.

`sp.len(e)`

  Return the length of `e`.
  See Michelson `SIZE`.

`sp.slice(expression, offset, length)`

  Slices `expression` from `offset` for `length` characters. `sp.slice(expression, offset, length)` is of type `sp.TOption(sp.TBytes)`.
  See Michelson `SLICE`.

`sp.pack(x)`

  Serialize a piece of data `x` to its optimized binary representation. Return an object of type `sp.TBytes`.
  See Michelson `PACK`.

`sp.unpack(x, t = …​)`

  Parse the serialized data from its optimized binary representation. There is an optional argument `t` to fix the type. `sp.unpack(e, t)` is of type `sp.TOption(t)`.
  See Michelson `UNPACK`.

`sp.blake2b(value)`
`sp.sha512(value)`
`sp.sha256(value)`

  The functions `sp.blake2b`, `sp.sha512`, `sp.sha256` take a `sp.TBytes` value and return the corresponding hash as a new `sp.TBytes` value.
  See Michelson `BLAKE2B`, `SHA256`, and `SHA512`.
  See reference Hash Functions template.

`sp.keccak(value)`
`sp.sha3(value)`

  Introduced in Edo, the functions `sp.keccak`, `sp.sha3` take a `sp.TBytes` value and return the corresponding hash as a new `sp.TBytes` value.
  See Michelson `KECCAK` and `SHA3`.
  Not supported yet in the interpreter.

`sp.utils.bytes_of_string(s)`

  Encode a constant string as `sp.TBytes`.

## Chain Id

The type of chain identifiers in SmartPy is `sp.TChainId`.
The corresponding type in Michelson is `chain_id`.

`sp.chain_id`

  The id of the network currently evaluating the transaction.
  See Michelson `CHAIN_ID`.

Literals: `sp.chain_id_cst("0x9caecab9")`

  Introducing a chain id by its hexadecimal representation.

Example: Chain Id

Please note that chain ids are non comparable. Equality can be verified by using `sp.verify_equal`.

## Comparable Types

Comparison operators `==`, `!=`, `<`, `<=`, `>`, `>=`

  The comparison operators `==`, `!=`, `<`, `<=`, `>`, `>=` behave just like in python. They return a boolean. They are defined on SmartPy comparable types which extend Michelson’s.
  See Michelson `EQ`, `NEQ`, `LT`, `LE`, `GE`, `GT`, and `COMPARE`.

`sp.min(x, y)`
`sp.max(x, y)`

  `sp.min(x, y)` and `sp.max(x, y)` return the minimum and maximum of `x` and `y`, respectively.

## Contracts and Addresses

Following Michelson, there are two ways to point to other contracts in SmartPy: typed `sp.TContract(t)` for contracts with an entry point of type `t` and untyped `sp.address`.
The corresponding types in Michelson are `contract` and `address`.

See reference On Chain Contract Calls - Collatz and FA1.2 templates.

Literals: `sp.address("tz…​ or KT…​")`

  Literals for addresses.

`sp.self`

  The current contract of type `sp.TContract(t)` for some type `t`.
  See Michelson `SELF`.

`sp.self_entry_point(entry_point = '')`

  The optional entry point named `entry_point` of the current contract; of type `sp.TContract(t)` where `t` is the type of the entry point’s parameters. If `entry_point` is empty, use current entry point.

`sp.to_address(contract)`

  Compute the address, of type `sp.TAddress`, of a contract of type `sp.TContract(t)` for some type `t`.
  See Michelson `ADDRESS`.

`sp.self_address`

  Alias for `sp.to_address(sp.self)`.
  This is the proper way to get a contract’s own address.
  In tests, a contract’s address is accessible through the `address` field.

`sp.self_entry_point_address(entry_point = "")`

  Alias for `sp.to_address(sp.self_entry_point(entry_point))`.
  This is the proper way to get a contract’s own address of an entry point.

`sp.sender`

  The address that called the current entry point.
  See Michelson `SENDER`.

`sp.source`

  The address that initiated the current transaction.
  It may or may not be equal to `sp.sender`.
  See Michelson `SOURCE`.

`sp.contract(t, address, entry_point = "")`

  Cast an address of type `sp.TAddress` to an optional typed contract of type `sp.TContract(t)`.

  - When optional parameter `entry_point` is empty or unspecified, it returns `sp.some(c)`, where `c` is a contract handle of type `sp.TContract(t)`, if `address`, of type `sp.TAddress`, points to a contract that expects a parameter of type `t`. Otherwise it returns `sp.none`.

  - When `entry_point` is not empty, it returns the specific entry point specified by the string `entry_point` of the contract. `t` must match the entry point’s expected parameter type. Otherwise, it returns `sp.none`.
    Due to restrictions of Michelson, it only works properly for contracts with multiple entry points.
    See Michelson `CONTRACT`.

`sp.transfer(arg, amount, destination)`

  Call the `destination` contract with argument `arg` while sending the specified `amount` to it. Note that `destination` must be of type `sp.TContract(t)`. The type of `arg` must be `t`, i.e. the argument sent to the destination must be consistent with what it expects.
  See Michelson `TRANSFER_TOKENS`.

`sp.send(destination, amount, message = None)`

  Send the specified `amount` to the `destination` contract. Will fail with optional error `message` if `destination` (of type `sp.TAddress`) does not resolve to a contract that expects a `sp.TUnit` argument (e.g. an account that does not result in any actions).
  Abbreviation for: `sp.transfer(sp.unit, amount, sp.contract(sp.TUnit, destination).open_some(message = message))`
  See Michelson `TRANSFER_TOKENS`.

`sp.implicit_account(key_hash)`

  See Key Hash for description.
  See Michelson `IMPLICIT_ACCOUNT`.

Example: Suppose we have an address `a` of a contract with an entry point `"foo"` that expects an integer. To call it, we first obtain a handle to the entry point:

      c = sp.contract(sp.TInt, a, entry_point = "foo").open_some()

The call to `open_some()` asserts that the address resolved successfully and that the referenced entry point indeed expects an integer. Now that we have our handle `c`, we can call the contract e.g. with the argument `-42` while sending along 0 tokens:

      sp.transfer(-42, sp.mutez(0), c)

`sp.create_contract(contract, storage = None, amount = tez(0), baker = None)`

  Create a new contract from stored SmartPy contract with optional storage, amount and baker.
  See Michelson `CREATE_CONTRACT`.
  See reference Create Contract template.

## Voting Power

`voting_powers` must be included in `.run(…​)` as described in Registering and Displaying Calls to Entry Points.

`sp.total_voting_power`

  Return the total voting power of all contracts.
  The total voting power coincides with the sum of the rolls count of every contract in the voting listings.
  The voting listings is calculated at the beginning of every voting period.
  See Michelson `TOTAL_VOTING_POWER`.

`sp.voting_power(key_hash)`

  Return the voting power of a specific delegate.
  See Key Hash.

## Level

`sp.level`

  Like `sp.now` but for the level of the transaction. It is of type `sp.TNat`.

## Integers

There are two main types of integers in SmartPy: signed integers `sp.TInt` and non negative ones `sp.TNat`.
The corresponding types in Michelson are `int` and `nat`.

SmartPy also uses a third definition `sp.TIntOrNat` which stands for integers that are not yet determined as `sp.TInt` or `sp.TNat`.

Literals: `1, 2, 0, -5, etc.`

  Literal of type `sp.TIntOrNat` when non negative and `sp.TInt` otherwise. The usual way to input literals in SmartPy, thanks to type inference.

Literals: `sp.int(i)`

  A literal of type `sp.TInt` when `i` is a Python integer literal.

Literals: `sp.nat(n)`

  A literal of type `sp.TNat` when `n` is a non negative Python integer literal.

`e1 + e2`, `e1 - e2`, `- e`, `e1 * e2`, `e1 % e2`, `e1 // e2`, `e1 << e2`, `e1 >> e2`

  The usual arithmetic operators `+`, `-`, `*`, `%`, `//`, `<<`, `>>` behave just like in Python.
  See Michelson `ADD`, `SUB`, `NEG`, `MUL`, `EDIV`, `LSL` and `LSR`.

`e1 | e2`

  Compute bitwise `e1` or `e2` for `e1` and `e2` of type `sp.TNat`. Result is also of type `sp.TNat`.
  See Michelson `OR`.

`e1 & e2`

  Compute bitwise `e1` and `e2` for `e1` and `e2` of type `sp.TNat`. Result is also of type `sp.TNat`.
  See Michelson `AND`.

`e1 ^ e2`

  Compute bitwise `e1` xor `e2` for `e1` and `e2` of type `sp.TNat`. Result is also of type `sp.TNat`.
  See Michelson `XOR`.

In SmartPy, type inference of arithmetic operators imposes that both sides have the same type. This constraint can be relaxed by explicitly using `sp.to_int`.

### Int vs Nat

`abs(i)`

  Return the absolute value of `i`. `abs` converts an `sp.TInt` into a `sp.TNat`.
  See Michelson `ABS`.

`sp.to_int(n)`

  Convert a `sp.TNat` into an `sp.TInt`.
  See Michelson `INT`.

`sp.is_nat(i)`

  Convert a `sp.TInt` into an `sp.TOption(sp.TNat)`. `sp.is_nat(i) == sp.some(n)` when `i` is a non negative `sp.TInt` and `sp.none` otherwise.
  See Michelson `ISNAT`.

`sp.as_nat(i, message = None)`

  Convert an `sp.TInt` into a `sp.TNat` and fails if not possible with the optional `message`, i.e., when `i` is negative. It is implemented as `sp.as_nat(i) = sp.is_nat(i).open_some(message = message)`.

### Division

`e1 / e2`

  The `/` operator performs truncated integer division when applied to SmartPy expression, just like `//` does. This is different to Python 3 (where `/` doesn’t truncate and yields a float when applied to integers).

`sp.ediv(num, den)`

  Perform Euclidian division.
  See Michelson `EDIV`.

## Keys

### Public Key

The type of public keys in SmartPy is `sp.TKey`.
The corresponding type in Michelson is `key`.

Literals: `sp.key('tz…​')`

  A literal key is of the form `sp.key(s)` where `s` is a Python string.

`sp.hash_key(key)`

  See Key Hash.

`sp.check_signature(k, s, b)`

  See Signatures.

### Key Hash

The type of key hashes in SmartPy is `sp.TKeyHash`.
The corresponding type in Michelson is `key_hash`.

See reference Baking Swap template.

Literals: `sp.key_hash('tz…​')`

  A literal key hash is of the form `sp.key_hash(s)` where `s` is a Python string `'tz…​'`.

`sp.hash_key(key)`

  Compute the base58check of `key` (which must be of type `sp.TKey`).
  It returns a `sp.TKeyHash` value.
  See Michelson `HASH_KEY`.

`sp.set_delegate(baker)`

  Set or unset an optional `baker` of type `sp.TOption(sp.TKeyHash)`.
  See Michelson `SET_DELEGATE`.
  In tests, a contract’s baker is accessible through the `baker` field.

`sp.implicit_account(key_hash)`

  Return the implicit account of type `sp.TContract(sp.TUnit)` from a `sp.TKeyHash`.
  See Michelson `IMPLICIT_ACCOUNT`.

`sp.voting_power(key_hash)`

  Return the voting power of a given key hash.
  This voting power coincides with the weight of the key hash in the voting listings (i.e., the rolls count) which is calculated at the beginning of every voting period.
  See Michelson `VOTING_POWER`.
  See [Other Operations] for `sp.total_voting_power`.

### Secret Key

The type of secret keys in SmartPy is `sp.TSecretKey`.
There is no corresponding type in Michelson.

Secret keys are used in tests.
See Cryptography in Test Scenarios and Signatures.

## Lambdas

The type of functions in SmartPy is `sp.TLambda(t1, t2)` where `t1` is the parameter type and `t2` the result type.
The corresponding type in Michelson is `lambda`.

See reference Lambdas template.

`sp.build_lambda(f)`

  Define a SmartPy lambda from a Python function or lambda.
  For example, `sp.build_lambda(lambda x: x + 3)` represents a function that takes an argument `x` and returns `x + 3`.
  This function is usually useless as it is called automatically by SmartPy in most contexts.
  See Michelson `LAMBDA`.

`sp.global_lambda`

  Decorator to introduce a lambda that is also a global variable.
  This is used for pure functions that are expected to be used more than once and that do not change the global state nor create operations.
  Values are returned by using `sp.result(value)`.
  See reference WorldCalculator template.

    class MyContract(sp.Contract):
        ...

        @sp.global_lambda
        def square_root(x):
            sp.verify(x >= 0)
            y = sp.local('y', x)
            sp.while y.value * y.value > x:
                y.value = (x // y.value + y.value) // 2
            sp.verify((y.value * y.value <= x) & (x < (y.value + 1) * (y.value + 1)))
            sp.result(y.value)

        @sp.entry_point
        def h(self, params):
            self.data.result = self.square_root(params)

See Michelson `LAMBDA`.

`sp.sub_entry_point`

  Like `sp.global_lambda` but for functions that can change the global state or create operations.
  Values are returned by using `sp.result(value)`.
  See reference Sub entry point template.

    class MyContract(sp.Contract):
        def __init__(self):
            self.init(x = 2, y = "aaa", z = 0)

        @sp.sub_entry_point
        def a(self, params):
            sp.set_delegate(sp.none)
            self.data.x += 1
            sp.result(params  * self.data.x)

        @sp.entry_point
        def f(self, params):
            self.data.z = self.a(5) + self.a(10)

        @sp.entry_point
        def g(self, params):
            self.data.z = self.a(6)

See Michelson `LAMBDA`.

`f(x)`

  Call a lambda.
  If `f` is of type `sp.TLambda(t1, t2)` and `x` is of type `t1` then `f(x)` is of type `t2`.
  See Michelson `EXEC`.

`f.apply(x)`

  Partially apply a lambda.
  If `f` is of type `sp.TLambda(sp.TPair(tp1, tp2), target)` and `x` is of type `tp1` then `f.apply(x)` is of type `sp.TLambda(tp2, target)`.
  See Michelson `APPLY`.

## Lists

The type of lists over type `t` is `sp.TList(t)`.
All elements need to be of the same type.
The corresponding type in Michelson is `list`.

See reference Lists template.

Literals: `sp.list(l = …​, t = …​)` and standard Python lists

  Define a list of (optional) elements in `l` whose optional type is `t`.
  See Michelson `NIL`.
  Standard Python lists are also accepted, e.g., `[1, 2, 3]`, `["aa", "bb", "cc"]`.

`myList.push(element)`

  Push an element on top of a list.
  See Michelson `CONS`.

`sp.len(myList)`

  Return the length of list `myList`.
  See Michelson `SIZE`.

`sp.concat(myList)`

  Concatenate a list `myList` of `sp.TString` or `sp.TBytes`.
  See Michelson `CONCAT`.

`sp.range(x, y, step = 1)`

  A list from `x` (inclusive) to `y` (exclusive). Useful in conjunction with `sp.for` loops.

`myList.rev()`

  Reverse a list.

`sp.for …​ in …​:`

  Iterate on a list.
  See Michelson `ITER` and `MAP`.
  To iterate on `sp.TMap(key, value)` or `sp.TSet(elem)`, we first convert to an `sp.TList(..)` with `e.items()`, `e.keys()`, `e.values()` or `e.elements()`.

        @sp.entry_point
        def sum(self, params):
            self.data.result = 0
            sp.for x in params:
                self.data.result += x

`sp.match_cons(l)`

  Match a list and expose its head and tail if any.
  See reference Lists template.

        with sp.match_cons(params) as x1:
            self.data.head = x1.head
            self.data.tail = x1.tail
        sp.else:
            self.data.head = "abc"

Please note that there is no way to perform random access on a list.

## Maps and Big Maps

### Maps

Maps in SmartPy are of type `sp.TMap(key, value)`.
The corresponding type in Michelson is `map`.

See reference Lists and Maps template.

Literals: `sp.map(l = …​, tkey = …​, tvalue = …​)`

  Define a map of (optional) elements in `l` (a Python dictionary) with optional key type `tkey` and optional value type `tvalue`.
  See Michelson `EMPTY_MAP` and `PUSH`.

Literals: standard Python dictionaries

  Standard Python dictionaries are also accepted, e.g., `{0 : "aa", 12 : "bb" }`.
  See Michelson `EMPTY_MAP` and `PUSH`.

`my_map[key] = value`

  Set or replace an element in a map.
  See Michelson `UPDATE`.

`del my_map[key]`

  Delete an element from a map.
  See Michelson `UPDATE`.

`my_map[key]`

  Look up an entry in a map. It fails if the entry is not found. `key` must have the type of its keys.
  See Michelson `GET`.

`my_map.get(key, default_value = None)`

  Same as `e[key]`. If `default_value` is specified and there is no entry for `key` in `my_map`, returns `default_value` instead of failing.
  See Michelson `GET`.

`my_map.contains(key)`

  Check whether the map `my_map` contains the `key`.
  See Michelson `MEM`.

`sp.len(my_map)`

  Return the size of the map `my_map`.
  See Michelson `SIZE`.

`my_map.items()`

  Return the sorted list of key-value entries in a map (not a big_map). Each entry is rendered as record with the two fields `key` and `value`.

`my_map.keys()`

  Return the sorted list of keys of a map (not a big map).

`my_map.values()`

  Return the list of values of a map (not a big_map), sorted by keys.

`sp.update_map(my_map, key, value)`

  Return a new copy of map `my_map` where `key` has optional value `value` (`sp.none` to delete).

`sp.get_and_update(my_map, key, value)`

  Return two elements: the previous optional value (`sp.none` if missing`) and a new map as `sp.update_map` would do.
  It is typically used in the following way.

    (previous_value, new_map) = sp.get_and_update(self.data.m, 1, sp.some("one"))

### Big Maps

Big maps, of type `sp.TBigMap(key, value)`, are lazy datastructures that are only serialized and deserialized on demand.
The corresponding type in Michelson is `big_map`.
We cannot iterate on big maps or compute their sizes.

See reference Lists template.

Literals: `sp.big_map(l = …​, tkey = …​, tvalue = …​)`

  Define a big_map of (optional) elements in `l` with optional key type `tkey` and optional value type `tvalue`.
  See Michelson `EMPTY_BIG_MAP`.

`my_big_map[key] = value`

  Set or replace an element in a big map.
  See Michelson `UPDATE`.

`del my_big_map[key]`

  Delete an element from a big map.
  See Michelson `UPDATE`.

`my_big_map[key]`

  Look up an entry in a big map. Fails if the entry is not found. `key` must have the type of its keys.
  See Michelson `GET`.

`my_big_map.get(key, default_value = None)`

  Same as `my_big_map[key]`. If `default_value` is specified and there is no entry for `key` in `my_big_map`, returns `default_value` instead of failing.
  See Michelson `GET`.

`my_big_map.contains(key)`

  Check whether the big map `my_big_map` contains the `key`.
  See Michelson `MEM`.

`sp.update_map(my_big_map, key, value)`

  Return a new copy of big map `my_big_map` where `key` has optional value `value` (`sp.none` to delete).

`sp.get_and_update(my_big_map, key, value)`

  Return two elements: the previous optional value (`sp.none` if missing`) and a new map as `sp.update_map` would do.
  It is typically used in the following way.

    (previous_value, new_map) = sp.get_and_update(self.data.m, 1, sp.some("one"))

## Mutez

The type of amounts in SmartPy is `sp.TMutez`.
The corresponding type in Michelson is `mutez`.

Literals: `sp.tez(…​)` and `sp.mutez(…​)`

  `sp.tez(10)` and `sp.mutez(500)` represent respectively 10 tez and 500 mutez.

`sp.amount`

  The amount of the current transaction.
  See Michelson `AMOUNT`.

`sp.balance`

  The balance of the current contract.
  See Michelson `BALANCE`.
  Due to the unintuitive semantics in Michelson, we suggest that developers do not rely on balance too much. See Tezos Agora post.
  In tests, a contract’s balance is accessible through the `balance` field.

`e1 + e2` and `e1 - e2`

  Usual arithmetic operators on `sp.TMutez`.
  See Michelson `ADD` and `SUB`.

`sp.split_tokens(amount, quantity, totalQuantity)`

  Compute `amount * quantity / totalQuantity` where `amount` is of type `sp.TMutez`, and `quantity` and `totalQuantity` are of type `sp.TNat`.

`sp.ediv(num, den)`

  Perform Euclidian division.
  See Michelson `EDIV`.

## Never

An empty type `sp.TNever`.

`sp.never(expression)`

  Terminate a never branch.
  See reference Never template.

## Options

Optional values in SmartPy are of type `sp.TOption(t)`.
The corresponding type in Michelson is `option`.
They represent values of type `t` or nothing.

Optional values are useful for accomodating missing data: e.g. if your contract has an optional expiry date, you can add a field `expiryDate = sp.none` to the constructor. Then, if you want to set the expiry date, you write `expiryDate = sp.some(sp.timestamp(1571761674))`. Conversely, if you want to unset it again, you write `expiryDate = sp.none`. SmartPy automatically infers the type `sp.TOption(sp.TTimestamp)` for `x`, so you don’t have to make it explicit.

`sp.some(e)`

  Define an optional value containing an element `e`.
  See Michelson `SOME`.

`sp.none`

  Define an optional value not containing any element.
  See Michelson `NONE`.

`e.is_some()`

  Check that an optional value contains an element, i.e., checks whether it is of the form `sp.some(…​)`.
  See Michelson `IF_NONE`.

`e.open_some(message = None)`

  If `e` is equal to `sp.some(x)`, return `x`; otherwise fail. `message` is the optional error raised in case of error.
  See Michelson `IF_NONE`.

## Pairs

Pairs in SmartPy are of type `sp.TPair(t1, t2)`.

`sp.pair(e1, e2)`

  Define a pair of two elements.
  See Michelson `PAIR`.

`sp.fst(..)`
`sp.snd(..)`

  `sp.fst(..)` and `sp.snd(..)` are used to access elements in pairs.
  See Michelson `CAR` and `CDR`.

Furthermore, pairs can be matched using the following command:

`sp.match_pair(x)`

  If `x` is a SmartPy pair (i.e. a value of type `sp.TPair(t,u)`), this returns a Python pair of its components. This is typically used as follows:

    x1, x2 = sp.match_pair(p)

## Records

Records in SmartPy are of type `sp.TRecord(**kargs)` where `kargs` is a Python `dict` of SmartPy types indexed by strings.
They generalize the Michelson type `pair`.

Literals: `sp.record(field1 = value1, field2 = value2, .., )`

  Introduce a record.

Field access

  If `x` is a record and `a` one of its fields, we can obtain the field’s value by writing `x.a`.

Furthermore, records can be matched using the following command:

`sp.match_record(x, *fields)`

  If `x` is a SmartPy record (i.e. a value of type `sp.TRecord(…​)`), this returns a Python tuple of selected record fields. The list of fields can be all the record’s fields or just some of them. This is typically used as follows:

    fld1, fld2, fld3 = sp.match_record(x, "fld1", "fld2", "fld3" )

`sp.modify_record(x, name = None)`

  A variant of this command allows modifying a record that is held in the contract storage or in a local variable:

    with sp.modify_record(self.data, "data") as data:
       ...
       data.x = 12
       data.y += 1

This command tells the SmartPy compiler to open the record, handle its fields independently and recreate the record afterwards in a linear way.
This command is mostly useful when dealing with tickets.

See reference Modify and Tickets templates for examples.

## Sapling Integration

Sapling is a new feature in Michelson. SmartPy.io is compatible with Sapling in different ways: types, michelson implementation, compiler, and a fake implementation for test scenarios.
See reference Sapling and Sapling2 templates.

There are two types for Sapling: `sp.TSaplingState(memo_size)` for states and `sp.TSaplingTransaction(memo_size)` for transactions where `memo_size` is a constant integer between `0` and `65535` and corresponds to potentially included data in transaction. The `memo_size` parameter is optional in types `sp.TSaplingState` and `sp.TSaplingTransaction` as it may be computed through type inference.

SmartPy doesn’t generate proper literals for Sapling types but an ad-hoc, fake, test implementation is provided for test scenarios. This is not a proper Sapling transaction but it is enough to test contracts (see reference templates).

Literals: `sp.sapling_test_transaction(source, target, amount, memo_size)`

  This is a fake / test version.

`source`

  `source` is a Python string, empty string for minting tokens.

`target`

  `target` is a Python string, empty string for burning tokens.

`amount`

  `amount` is a non-negative Python integer.

`memo_size`

  `memo_size` is a non-negative Python integer between `0` and `65535`.

Two operations
`sp.sapling_empty_state(memo_size)`

  Building an empty `sp.TSaplingState` with a default `memo_size` (Expected length for message of Sapling transaction)

`memo_size`

  `memo_size` is a uint16 value and represents the expected message length of the sapling transaction. (must be between 0 and 65535)

`sp.sapling_verify_update(transaction)`

  When `state` is a `sp.TSaplingState(memo_size)` and `transaction` a `sp.TSaplingTransaction(memo_size)`, `sp.sapling_verify_update(state, transaction)` applies the transaction to the state, validates it and returns `sp.none` if it fails and `sp.some(x)` where `x` is of type `sp.TPair(sp.TInt, sp.TSaplingState(memo_size))`.

## Sets

Sets in SmartPy are of type `sp.TSet(element)`.
The corresponding type in Michelson is `set`.

See reference Lists template.

Literals: `sp.set(l = …​, t = …​)`

  Define a set of (optional) elements in `l` with optional element type `t`.
  See Michelson `EMPTY_SET`.

Literals: standard Python sets

  Sets can also be defined using regular Python syntax `{1, 2, 3}`. This only works with non-SmartPy specific expressions. For SmartPy expressions, we must use `sp.set([e1, e2, …​, en])`.

`mySet.elements()`

  Return the sorted list of elements in a set.

`mySet.contains(element)`

  Check whether the set `mySet` contains the `element`.
  See Michelson `MEM`.

`mySet.add(element)`

  Add an element to a set.
  See Michelson `UPDATE`.

`mySet.remove(element)`

  Remove an element from a set.
  See Michelson `UPDATE`.

## Signatures

The type of signatures in SmartPy is `sp.TSignature`.
The corresponding type in Michelson is `signature`.

See reference Signatures and State Channels templates.

`sp.check_signature(k, s, b)`

  Determine whether the signature `s` (a `sp.TSignature` value) has been produced by signing `b` (a `sp.TBytes` value) with the private key corresponding to `k` (a `sp.TKey` public key value).
  See Michelson `CHECK_SIGNATURE`.

`sp.make_signature(secret_key, message, message_format = 'Raw')`

  Forge a signature compatible with `sp.check_signature(…​)`; the `message` is a `TBytes` value (usually the result of an `sp.pack` call), the `message_format` can also be `"Hex"` in which case the message will be interpreted as an hexadecimal string.

  `sp.make_signature` is not available for compilation to Michelson (a smart contract cannot manipulate secret keys). It can only be used in Tests and Scenarios.

## Strings

The type of SmartPy strings is `sp.TString`.
The corresponding type in Michelson is `string`.

See reference Strings and Bytes template.

Literal strings `"…​"` and `'…​'`

  Strings in SmartPy are introduced by simply using regular Python strings of the form `"…​"` or `'…​'`, or by using `sp.string(s)` where `s` is a Python string.

Literals: `sp.string(s)`

  Alternative way to introduce SmartPy string literals when `s` is a python string.

`e1 + e2`

  Concatenates two strings.
  See Michelson `CONCAT`.

`sp.concat(l)`

  Concatenates a list `l` of strings.
  See Michelson `CONCAT`.

`sp.len(e)`

  Return the length of `e`.
  See Michelson `SIZE`.

`sp.slice(expression, offset, length)`

  Slices `expression` from `offset` for `length` characters. `sp.slice(expression, offset, length)` is of type `sp.TOption(sp.TString)`.
  See Michelson `SLICE`.

## Tickets

Tickets of content type `t` have type `sp.TTicket(t)`.
The corresponding type in Michelson is `ticket cty`.
See reference Tickets template.

The following operations are supported:

`sp.ticket(content, amount)`

  Create a ticket with `content` and `amount`. If `content` is of type `t`, the return type is `sp.TTicket(t)`. The `amount` has to be of type `sp.TNat`.
  See Michelson `TICKET`.

### High Level Functions

`sp.read_ticket(ticket)`

  Read the data of a `ticket` and return a Python object with four fields `ticketer`, `content`, `amount`, and `copy`.

    read_ticket = sp.read_ticket(ticket)

The output `read_ticket` object is not a SmartPy expression and cannot be passed as an expression to regular SmartPy functions. However, it can be passed to regular Python functions thanks to meta-programming.
It is an error to access `ticket` again after this command, but `read_ticket.copy` must be used instead. If `ticket` is of type `sp.TTicket(t)`, then `read_ticket.ticketer` is of type `sp.TAddress`, `read_ticket.content` of type `t`, and `read_ticket.amount` of type `sp.TNat`.
See Michelson `READ_TICKET`.

`sp.split_ticket(ticket, q1, q2)`

  Split `ticket` into two tickets of amounts `q1` and `q2`. These two amounts must sum up to `ticket`'s value, otherwise `sp.none` is returned. If `ticket` is of type `sp.TTicket(t)`, this returns a value of type `sp.TOption(sp.TPair(sp.TTicket(t), sp.TTicket(t)))`.
  See Michelson `SPLIT_TICKET`.

`sp.join_tickets(ticket1, ticket2)`

  Return a new ticket with the sum of the amounts in `ticket1` and `ticket2`. The two tickets must have the same contents, or an error is raised. Both tickets must have the same type `sp.TTicket(t)`, which is also the return type.
  See Michelson `JOIN_TICKETS`.

### Low Level Functions

`sp.read_ticket_raw(ticket)`

  Like `sp.read_ticket(ticket)` when the output is two elements, similar to Michelson `READ_TICKET`.

`sp.split_ticket_raw(ticket, q1, q2)`

  Like `sp.split_ticket(ticket, q1, q2)` when the output is two elements, similar to Michelson `SPLIT_TICKET`.

`sp.join_tickets_raw(tickets)`

  Like `sp.join_tickets(ticket1, ticket2)` where `tickets` is a pair of tickets, similar to Michelson `JOIN_TICKETS`.

### Testing Tickets

`sp.test_ticket(ticketer, content, amount)`

  Create a new ticket issued by the locally defined contract `ticketer`. This is meant to be used for testing purposes in scenarios.

## Timestamps

The type of timestamps in SmartPy is `sp.TTimestamp`.
The corresponding type in Michelson is `timestamp`.

See reference Timestamps template.

Literals: `sp.timestamp(…​)`

  A literal timestamp is defined by doing `sp.timestamp(i)` where `i` is an integer representing the number of seconds since epoch (January 1st 1970).

`sp.now`

  The minimal injection time on the stack for the current block/priority. For all reasonable purposes, this is a technical detail and `sp.now` should be understood as the timestamp of the block whose validation triggered the execution.
  See Michelson `NOW`.

`sp.timestamp_from_utc(year, month, day, hours, minutes, seconds)`

  Compute a constant timestamp corresponding to an UTC datetime.

`sp.timestamp_from_utc_now()`

  Compute a constant timestamp corresponding to now. This is fixed at contract or test evaluation time.

`e.add_seconds(seconds)`

  Return a timestamp with `seconds` added to `e`, where `e` must be a `sp.TTimestamp` and `seconds` a `sp.TInt`.
  See Michelson `ADD`.

`e.add_minutes(minutes)`

  Return a timestamp with `minutes` added to `e`, where `e` must be a `sp.TTimestamp` and `minutes` a `sp.TInt`.
  See Michelson `ADD`.

`e.add_hours(hours)`

  Return a timestamp with `hours` added to `e`, where `e` must be a `sp.TTimestamp` and `hours` a `sp.TInt`.
  See Michelson `ADD`.

`e.add_days(days)`

  Return a timestamp with `days` added to `e`, where `e` must be a `sp.TTimestamp` and `days` a `sp.TInt`.
  See Michelson `ADD`.

`e1 - e2`

  Return the difference in seconds between two timestamps.
  See Michelson `SUB`.

## Unit

The type of unit values in SmartPy is `sp.TUnit`.
The corresponding type in Michelson is `unit`.
It is the return type of commands and the input types of entry points with empty parameters.

`sp.unit`

  There is only a single value of type `sp.TUnit` which is `sp.unit`.
  See Michelson `UNIT`.

## Variants

Variants in SmartPy are of type `sp.TVariant(**kargs)` where `kargs` is a Python `dict` of SmartPy types indexed by strings.
They generalize the Michelson type `or`.
They are used to define sum-types, similar to enums in other languages with the extra feature that these enums contain values.

See reference Variant template.

`sp.variant('constructor', value)`

  Introduce a variant.
  See Michelson `LEFT` and `RIGHT`.

`sp.left(value)`

  Introduce a left/right variant.
  See Michelson `LEFT`.

`sp.right(value)`

  Introduce a left/right variant.
  See Michelson `RIGHT`.

`e.is_variant(v)`

  For a variant, checks whether it is `sp.variant(v, …​)`.
  See Michelson `IF_LEFT`.

`e.is_left(v)`

  For a left/right variant, checks whether it is `sp.left(…​)`.
  See Michelson `IF_LEFT`.

`e.is_right(v)`

  For a left/right variant, checks whether it is `sp.right(…​)`.
  See Michelson `IF_LEFT`.

`e.open_variant(v)`

  If `e` is equal to `sp.variant(v, x)`, return `x`. Otherwise fail.
  See Michelson `IF_LEFT`.

# Commands

## Assignment

`lhs = rhs`

  Evaluate `rhs` and assign it to `lhs`. Both `lhs` and `rhs` must be SmartPy expressions. Doesn’t work if `lhs` is a Python variable.

`lhs.set(rhs)`

  Alternative syntax for assignment. Useful when the left-hand-side is a single Python variable, e.g. one referencing a SmartPy local variable (see below).

## Local variables

Local SmartPy variables can be defined as follows: `x = sp.local("x", 0)`

The first argument to `sp.local` is a string that will be used in error messages. It is advisable to use the same name that is used on the left of `=`.

Local variable values can be accessed to and updated with the `.value` field: `x.value = 1`, `x.value = 2 * x.value + 5`, etc.

This is mostly useful in loops.

Note that local SmartPy variables are different to Python variables. The latter cannot be updated during contract execution.

As an example, here is how we can commute a square root.

        @sp.entry_point
        def squareRoot(self, x):
            sp.verify(x >= 0)
            y = sp.local('y', x)
            sp.while y.value * y.value > x:
                y.value = (x // y.value + y.value) // 2
            sp.verify((y.value * y.value <= x) & (x < (y.value + 1) * (y.value + 1)))
            self.data.value = y.value

`sp.compute(expression)`

  This is defined as a local variable immediately created and returned with its value.

    def compute(expression):
        return local("compute_%i" % (get_line_no()), expression).value

It’s used to evaluate an expression and remember its value.

When we evaluate this code:

        x = sp.compute(self.data.a)
        self.data.a += 1
        y = sp.compute(self.data.a)

Then `y` contains a value equals to the value of `x` plus one.

## Control and Syntactic Sugar

Since Python doesn’t allow its control statements to be overloaded, certain language constructs are desugared by a pre-processor: `sp.if`, `sp.else`, `sp.for`, `sp.while` are SmartPy commands. (The desugared version has `sp.if_` etc. instead.)

`sp.if …​:`
`sp.else:`

  A `if` condition that is evaluated on-chain.

`sp.for …​ in …​:`

  A `for` loop that is evaluated on-chain.

            sp.for x in params:
                self.data.result += x

`sp.while …​:`

  A `while` loop that is evaluated on-chain.

            sp.while 1 < y:
                self.data.value += 1
                y.set(y // 2)

See Michelson `LOOP`.

`sp.for` / `sp.if` / `sp.else`
See Michelson `ITER`, `MAP`, and `IF`.

If we use e.g. `sp.if` instead of a plain `if`, the result will be a SmartPy conditional instead of a Python one. SmartPy conditionals are executed once the contract has been constructed and has been deployed or is being simulated. On the other hand, Python conditionals are executed immediately. Therefore the condition after the `if` cannot depend on the state of the contract. When in doubt, always use the `sp.` prefix inside a smart contract.

## Checking a Condition

`sp.verify(condition, message = …​)`

  Check that the boolean expression `condition` evaluates to `True` and raises an error if it doesn’t. This is useful to prevent an entry point from proceding if certain conditions are not met (e.g. in a contract that manages accounts a client cannot withdraw more money than they deposited).

  An optional parameter `message` is raised if condition is not met. When `message` is not present, an exception of the form `WrongCondition: …​` is raised.

  See Michelson `FAILWITH`.

`sp.verify_equal(v1, v2, message = …​)`

  It serves the same purpose by checking equality between `v1` and `v2`. This works on both comparable and non-comparable types.

## Raising Exceptions

Once an exception is raised, it cannot be caught.
String error messages may take a lot of space in smart contracts so we try to be cautious there.

`sp.failwith(message)`

  Abort the current transaction and raises a `message` of arbitrary type. This cannot be caught.
  See Michelson `FAILWITH`.

Besides `sp.verify` and `sp.verify_equal`, exceptions can also be raised by other constructions:

Accessing fields `my_map[x]`

  The exception raised is now a pair containing the `(x, my_map)`.

Opening variants

  This may fail with `sp.unit`.

Dividing by zero

  A message is shown.

Variable step in a range which is 0

  A message is shown.

# Flags

Several aspects of scenarios and the compilation of contracts can be controlled by the use of flags.
SmartPy supports two sorts of flags: boolean flags and flags with arguments.

## Boolean Flags

Flag | Role | Default value
disable-dup-check | Remove the `DUP` protection on tickets. | False
dump-michel | Dump Michel intermediate language | False
erase-comments | Remove compiler comments | False
erase-var-annots | Remove annotations (with `RENAME`) after `SENDER`, `BALANCE`, etc. | False
initial-cast | Add an initial `CAST` to remove annotations first in the compiler | False
pairn | Use `PAIR n` instruction | True
simplify | Allow simplification after compilation | True
simplify-via-michel | Use Michel intermediate language | False
single-entry-point-annotation | Emit parameter annotations for single entry point contracts | True
warn-unused | Exceptions for unused entry point parameters | True
decompile | Decompile after compilation (for test purposes) | False

## Other Flags

Flag | Role | Values | Default value
protocol | Protocol used in the scenario | delphi, edo, florence, granada | Florence
lazy-entry-points | Use big maps to store entry points | none, single, multiple | none
exceptions | Control exception generation in the compiler | full-debug, debug-message, verify-or-line, default-line, line, default-unit, unit | verify-or-line
default_variant_layout | Select default layout for variants | tree, comb | tree
default_record_layout | Select default layout for records | tree, comb | tree

Protocol and default layout flags are initial which means that they must be set either in the command line or in the first steps in scenarios.

## Adding Flags in a Scenario

`self.add_flag(flag, *args)`

  Add a `flag` where `flag` is a string constant and `args` are potential arguments.
  For example, you can write `self.add_flag("lazy-entry-points", "single")` or `self.add_flag("erase-comments")` or `self.add_flag("no-erase-comments")`.

To enable Edo specific compilation, use `self.add_flag("protocol", "edo")` or `self.add_flag("protocol", "delphi")` for Delphi.
`"florence"` is the current default. Choices are currently `"delphi"`, `"edo"`, `"florence"` (default) and `"granada"`.

## Erasing comments

A flag to remove comments that do not come from types in the generated Michelson.
See reference Exception Optimization Levels template.

This is done by calling `self.add_flag("erase-comments")` in the contract.

## Exception Optimization Levels

Exception reporting is determined for a contract by setting `self.exception_optimization_level = <level>`.
See reference Exception Optimization template.

Different levels are:

"full-debug"

  This is extremely costly in terms of size and gas. Useful for debugging purposes. Type of failure, line number, some parameters.

"debug-message"

  This is still very costly in terms of size and gas.

"verify-or-line"

  This is the default. Puts messages for `sp.verify` and `sp.failwith`, and line numbers for other failures.

"default-line"

  Puts messages for `sp.verify` with custom messages and `sp.failwith`, and line numbers for other failures.

"line"

  Only puts line numbers everywhere.

"default-unit"

  Puts messages for `sp.verify` with custom messages, and `sp.failwith`, and unit for other failures.

"unit"

  Always puts unit.

# New features in Florence

## Florence flags

`self.add_flag("protocol", "florence")` - Enables Florence features.

## Order of Evaluation of Contract Calls

In Florence, contract calls are switching to the DFS ordering.

# New expected features in Granada (protocol 10)

We’re supposing that baking accounts could go in Granada.

## Granada protocol

`self.add_flag("protocol", "granada")` - Enables Granada features.

## Baking Accounts

### New types

`sp.TBakerHash`

  The b58check hash of the baker account (prefixed “SG1”).
  `baker_hash`.

Literals: `sp.baker_hash('SG1…​')`

  A literal baker hash is of the form `sp.baker_hash(h)` where `h` is a Python string `'SG1…​'`.

# Utils

An helper class that contains various helper functions.

## Methods

`sp.utils.same_underlying_address(addr1, addr2)`

  It returns a boolean that informs if an address `A%foo` has the same underlying address as `A`.

      sp.verify(
        sp.utils.same_underlying_address(
          sp.address("KT1Tezooo1zzSmartPyzzSTATiCzzzyfC8eF%foo"),
          sp.address("KT1Tezooo1zzSmartPyzzSTATiCzzzyfC8eF")
        ),
        message = "Not the same underlying address"
      )

`sp.utils.mutez_to_nat(…​)`

  Convert a `TMutez` value to `TNat`.

`sp.utils.nat_to_mutez(n)` and `sp.utils.nat_to_tez(n)`

  Convert a `TNat` value to `TMutez`.

# Experimental Features

## Views

`sp.utils.view(t, message = None)`

  Decorator `sp.utils.view` to introduce an entry point that happens to be a view.
  A view is an entry point that

  1. Doesn’t change the storage;

  2. Calls a callback `sp.TContract(t)`.

        @sp.utils.view(sp.TNat)
        def getBalance(self, params):
            sp.result(self.data.balances[params].balance)

This code is a simpler version of the equivalent:

        @sp.entry_point
        def getBalance(self, params):
            __s3 = sp.local("__s3", self.data.balances[sp.fst(params)].balance)
            sp.set_type(sp.snd(params), sp.TContract(sp.TNat))
            sp.transfer(__s3.value, sp.tez(0), sp.snd(params))

## Importing SmartPy and Python code

Importing regular Python code can be done in any template with the regular Python `import`.

Importing SmartPy code that uses the syntactic sugar is also doable but needs specific functions.

`sp.io.import_template(template_name)`

  Import a template.
  It only works in https://SmartPy.io, not with the CLI.

      FA2 = sp.import_template("FA2.py")
      class my_token(FA2.FA2):
          ...

`sp.io.import_script_from_url(url, name = None)`

  Same functionality but instead of using a template from within SmartPy.io; import any file. The `url` is a string of the form `http://`, `https://`, `file://`, `file:`, etc. The module obtained name is the optional `name` parameter, with default equal to `url`.

`sp.io.import_stored_contract(name)`

  Same functionality but instead of importing a file from a `url`, import a script saved in the browser local storage.
  It only works in https://SmartPy.io, not with the CLI.

`sp.io.import_script_from_script(name, script)`

  Import some script where both `name` and `script` are strings.

## Metadata support

Helper function for TZip 16 Standard.
See reference Metadata template.

`sp.utils.metadata_of_url(url)`

  Initialize some metadata field in a storage with a constant `url` string.
  Simple alias for `sp.big_map({"" : sp.utils.bytes_of_string(url)})`.

`self.init_metadata(name, expression)`

  Generate a JSON metadata document for string `name` containing an arbitraty constant Python `expression` converted into JSON.

`sp.offchain_view(pure = False, doc = None)`

  Decorator to introduce an offchain view. Two optional parameters: `pure` (default is `False`) to declare purity of view (dependent only on storage and parameters) and `doc` to set its documentation. If `doc` is `None`, the documentation is the docstring of the method.

        @sp.offchain_view(pure = True)
        def get_x(self, params):
            """blah blah ' fdsfds " """
            sp.result(sp.record(a = self.data.x, b = 12 + params))

## Debugging contracts

`sp.trace(expression)`

  Compute an expression and print its value to std::out (or the console in a web-browser).

`scenario.simulation`

  Graphical user interface and step by step simulation in a web-browser.

## Returning and Binding data

This is an advanced topic and need not be looked at for regular SmartPy developers.

In a block, we can write `sp.result(expr)` to compute `expr` and prepare the local result. This data can be bound by using `sp.bind_block()`.
See reference Bind template. In this example, we define a block `b`, computes some value and return it.

        def f(self, params)
            b = sp.bind_block()
            with b:
                sp.if params > 12:
                    sp.result(self.data.x + params)
                else:
                    sp.result(self.data.x + 2)
            return b.value

## Michelson Code Inlining

See reference Inline Michelson template.

`sp.michelson(code, types_in, types_out)`

  Inline arbitrary Michelson code. `types_in` and `types_out` are lists of types, and `code` is some Michelson code using the micheline syntax. Currently, in practice, only singleton `types_out` are supported.

        self.data.x = sp.michelson("ADD;", [sp.TInt, sp.TInt], [sp.TInt])(15, 16)
        self.data.y = sp.michelson("DUP; DIG 2; ADD; MUL;", [sp.TInt, sp.TInt], [sp.TInt])(15, 16)

`sp.lambda_michelson(code, source = None, target = None)`

  Special case of `sp.michelson` where the code represents a lambda.
  `sp.lambda_michelson(code, t1, t2)` is of type `sp.TLambda(t1, t2)`.

        self.data.f = sp.lambda_michelson("DUP; PUSH int 2; ADD; MUL;", sp.TNat, sp.TInt)

# Tests and Scenarios

This has been introduced by the following Medium Post.

## General Framework

Scenarios describe a sequence of actions: originating contracts, computing expressions, calling entry points, etc.

They are directly used in SmartPy tests.

SmartPy currently supports two uses for scenarios: tests and compilation targets.

## Adding a Test

`sp.add_test(name, shortname=None, profile=False, is_default=True)`

  Adding a test.

`sp.test_scenario()`

  Define a scenario.

Tests are added by :

      @sp.add_test(name = "First test")
      def test():
        scenario = sp.test_scenario()
        c1 = MyContract()
        scenario += c1
        scenario += c1.my_entrypoint(...)
        ...

Besides `name`, `sp.add_test` accepts several parameters.

`shortname=None`

  Optional parameter. Short names need to be unique. Used in smartpy-cli outputs.

`profile=False`

  Computes and pretty-prints profiling data.

`is_default=True`

  Determines if the test is performed by default when evaluating all tests. Can be typically used in conjonction with `sp.in_browser` in templates to improve speed in browser.
  See reference FA2 template.

## Test Example

      @sp.add_test(name = "First test")
      def test():
          # We define a test scenario, called scenario,
          # together with some outputs and checks
          scenario = sp.test_scenario()
          # We first define a contract and add it to the scenario
          c1 = MyContract(12, 123)
          scenario += c1
          # And send messages to some entry points of c1
          scenario += c1.my_entrypoint(12)
          scenario += c1.my_entrypoint(13)
          scenario += c1.my_entrypoint(14)
          scenario += c1.my_entrypoint(50)
          scenario += c1.my_entrypoint(50)
          scenario += c1.my_entrypoint(50).run(valid = False) # this is expected to fail
          # Finally, we check the final storage of c1
          scenario.verify(c1.data.myParameter1 == 151)
          # and its balance
          scenario.verify(c1.balance == sp.tez(0))

## Inside a Scenario

### Registering and displaying contracts

      scenario += c1
      # This is identical to doing
      scenario.register(c1, show = True)

      # To only register the smart contract but not show it
      scenario.register(c1)

### Contract Methods

Additionaly to entry points, contracts have two additional methods that can be called once, before origination.

`c.set_initial_balance(expression)`

  Set the initial balance of a contract.

### Test Accounts

Test accounts can be defined by calling `sp.test_account(seed)` where `seed` is a string. A test account `account` contains some fields: `account.address`, `account.public_key_hash`, `account.public_key`, and `account.secret_key`.
See Cryptography in Test Scenarios.

      admin = sp.test_account("Administrator")
      alice = sp.test_account("Alice")
      bob   = sp.test_account("Robert")

They can be used for several purposes: getting addresses with `account.address`, in `sender` or `source` parameters or for checking or creating signatures.

### Registering and Displaying Calls to Entry Points

      c1.my_entrypoint(12)
      c1.my_entrypoint(...).run(sender = ..., source = ...,
      amount = ..., now = ..., level = ..., valid = ..., exception = ..., show = ..., chain_id = ..., voting_powers = ...)

The `run` method and its parameters are all optional.

`sender`

  the simulated sender of the transaction. It populates `sp.sender`. It can be either built by a `sp.test_account(…​)` or an expression of type `sp.TAddress`.

`source`

  the simulated source of the transaction. It populates `sp.source`. It can be either built by a `sp.test_account(…​)` or an expression of type `sp.TAddress`.

`amount`

  the amount sent. Example: `amount = sp.tez(10)` or `amount = sp.mutez(10000)`. It populates `sp.amount`.

`now`

  the timestamp of the transaction. Example: `sp.timestamp(1571761674)`. It populates `sp.now`.

`level`

  the level of the transaction. Example: `1234`. It populates `sp.level`.

`show`

  show or hide the transaction. `True` by default.

`valid`

  the expected validity of the transaction. `True` by default. If the validity of a transaction doesn’t match its expected validity, SmartPy shows an alert.

`exception`

  the expected exception raised by the transaction. If present, `valid` must be `False`.

`chain_id`

  the simulated chain_id for the test. Example: `sp.chain_id_cst("0x9caecab9")`.

`voting_powers`

  the simulated voting powers for the test. Example: `voting_powers = { sp.key_hash("tz1…​") : 10 }`.

### Adding Document Information

      scenario.h1("a title")
      scenario.h2("a subtitle")
      scenario.h3(..)
      scenario.h4(..)
      scenario.p("Some text")

### Showing Expressions

To compute expressions, we use `scenario.show(expression, html = True, stripStrings = False)`.

      scenario.show(expression, html = True, stripStrings = False)
      # html: True by default, False to export not in html but like in source code.
      # stripStrings: False by default, True to remove quotes around strings.

      scenario.show(c1.data.myParameter1 * 12)
      scenario.show(c1.data)

### Computing Expressions

To compute expressions, we use `scenario.compute`.

      x = scenario.compute(c1.data.myParameter1 * 12)

The variable `x` can now be used in the sequel of the scenario and its value is fixed.

### Accessing Data associated to Contracts

When `c` is a contract in a scenario, we can access some associated data:

`c.data`

  Retrieve its storage.

`c.balance`

  Retrieve its balance.

`c.baker`

  Retrieve its optional delegated baker.

`c.address`

  Retrieve its address within the scenario.
  In storage or similar circumstances, contracts get addresses of the form: `"KT1TezoooozzSmartPyzzSTATiCzzzwwBFA1"`, `"KT1Tezooo1zzSmartPyzzSTATiCzzzyfC8eF"`, `"KT1Tezooo2zzSmartPyzzSTATiCzzzwqqQ4H"`, `"KT1Tezooo3zzSmartPyzzSTATiCzzzseJjWC"`, `"KT1Tezooo4zzSmartPyzzSTATiCzzzyPVdv3"`, `"KT1Tezooo5zzSmartPyzzSTATiCzzzz48Z4p"`, `"KT1Tezooo6zzSmartPyzzSTATiCzzztY1196"`, `"KT1Tezooo7zzSmartPyzzSTATiCzzzvTbG1z"`, `"KT1Tezooo8zzSmartPyzzSTATiCzzzzp29d1"`, `"KT1Tezooo9zzSmartPyzzSTATiCzzztdBMLX"`, `"KT1Tezoo1ozzSmartPyzzSTATiCzzzw8CmuY"`, etc.

`c.typed`

  Retrieve its testing typed contract value.
  To access entry points, one can use field notation, e.g., `c.typed.my_entry_point` to access typed entry point `my_entry_point` of `c`.
  See reference FA1.2 template.

### Dynamic Contracts

See reference Create Contract template.

Internally, SmartPy uses two types of contracts: static ones and dynamic ones. Static contracts appear explicitly in the scenarios. Dynamic ones are created in other contracts executed in the scenario (with `sp.create_contract`).

`my_dynamic_contract = scenario.dynamic_contract(contractId, tcontract, tparameter)`

  Declare that a dynamic contract of dynamic `id` (an integer) is created with the corresponding storage and full parameter types.
  The first dynamically created `contractId` is `0`, then '1', etc.
  Return a dynamic contract that contains regular fields `data`, `balance`, `baker`, `address` and `typed` and a `call` method.

Dynamic contracts addresses are of the form: `"KT1TezoooozzSmartPyzzDYNAMiCzzpLu4LU"`, `"KT1Tezooo1zzSmartPyzzDYNAMiCzztcr8AZ"`, `"KT1Tezooo2zzSmartPyzzDYNAMiCzzxyHfG9"`, `"KT1Tezooo3zzSmartPyzzDYNAMiCzzvqsJQk"`, `"KT1Tezooo4zzSmartPyzzDYNAMiCzzywTMhC"`, `"KT1Tezooo5zzSmartPyzzDYNAMiCzzvwBH3X"`, `"KT1Tezooo6zzSmartPyzzDYNAMiCzzvyu5w3"`, `"KT1Tezooo7zzSmartPyzzDYNAMiCzztDqbVQ"`, `"KT1Tezooo8zzSmartPyzzDYNAMiCzzq2URWu"`, `"KT1Tezooo9zzSmartPyzzDYNAMiCzzwMosaF"`, `"KT1Tezoo1ozzSmartPyzzDYNAMiCzzzknqsi"`, etc.

`my_dynamic_contract.call(entry_point, parameter)`

  Send the `parameter` to the dynamic contract `dync’s `entry_point`.
  We can use `.run(…​)` on the generated call as described in Registering and Displaying Calls to Entry Points.

### Checking Assertions

To verify conditions, we use `scenario.verify`. To verify an equality condition, we can also use `scenario.verify_equal` which works on both comparable and non-comparable types.

      scenario.verify(c1.data.myParameter == 51)

      scenario.verify_equal(c1.data.myList, [2, 3, 5, 7])

### Interactive Testing

To test interactively a contract, we use `scenario.simulation`. It also provides a step-by-step mode that is very usefull to understand some computation.

      scenario.simulation(c1)

## Cryptography in Test Scenarios

Some constructions are only available in tests, not in smart contracts.

`sp.test_account(seed)`

  The class `alice = sp.test_account("Alice")`
  Create a deterministic key-pair from a “seed” string.

  - `alice.address`
    Get the public-key-hash as a `TAddress`.

  - `alice.public_key_hash`
    Get the public-key-hash as a `TKeyHash`.

  - `alice.public_key`
    Get the full public-key as a `TKey`.

  - `alice.secret_key`
    Get the secret-key as a `TString`.

`sp.make_signature(secret_key, message, message_format = 'Raw')`

  See Signatures.

`sp.test_account` methods and `sp.make_signature` are not available for compilation to Michelson (a smart contract cannot manipulate secret keys).

## Test without Explicit Scenarios

`sp.add_simulation_target(contract, name="Simulation", shortname=None, profile=False, is_default=True)`

  As a convenience, one can call `sp.add_simulation_target(contract, …​)` instead of `@sp.add_test …​`.
  `sp.add_simulation_target` optional parameters are:

`name="Simulation"`

  Optional parameter with default value =`"Simulation"`.

`shortname=None`

  Optional parameter. Short names need to be unique. Used in smartpy-cli outputs.

`profile=False`

  Computes and pretty-prints profiling data.

`is_default=True`

  Determines if the test is performed by default when evaluating all tests. Can be typically used in conjonction with `sp.in_browser` in templates to improve speed in browser.
  See reference FA2 template.

# Compilation Targets

## Adding a Compilation Target

We can also add compilation targets by doing

`sp.add_compilation_target(name, contract, storage=None)`

  Define a `contract` with `name` with optional `storage`.
  Compilation targets also use scenarios behind the scene.

`sp.add_expression_compilation_target(name, expression)`

  Define an `expression` called `name`.
  Compilation targets also use scenarios behind the scene.

## Compilation Target Examples

    # A contract with an empty (unit) storage
    sp.add_compilation_target("min_comp", MyContract())

    # A contract with a simple int storage
    sp.add_compilation_target("min_comp_int", MyContract(x = 1))

    # An expression
    sp.add_expression_compilation_target("x", 42)

    # Another expression
    sp.add_expression_compilation_target("y", ("a", [1, 2, 3]))

# Scenario-based Custom Targets

## Custom targets

A custom target is similar to a test or a compilation target but associated with another custom `kind` (a free form string).

`@sp.add_target(name, kind)`

  Introduce a custom target.

    @sp.add_target(name = "orig", kind = "origination")
    def origin():
        scenario = sp.test_scenario()
        c1 = MyContract(x=12)
        scenario += c1

# Command Line Interface

The command line interface is called smartpy-cli and has been introduced by the following Medium Post.

## Installation

See installation instructions.

## Check version

This command tells which CLI version is installed.

    ~/smartpy-cli/SmartPy.sh --version

## Dependencies

smartpy-cli depends on `python3` and `node.js`.

## Execution

### Executing a SmartPy Script with its tests

SmartPy.sh test

  Perform tests defined in a `script.py` (see Tests and Scenarios).

    ~/smartpy-cli/SmartPy.sh test <script.py> <output-directory>

This includes many outputs: types, generated michelson code, pretty-printed scenario, etc.

### Compiling SmartPy Contracts or Expressions

SmartPy.sh compile

  Compute the Compilation Targets defined in a `script.py`.
  Warning: the interface changed.

    ~/smartpy-cli/SmartPy.sh compile <script.py> <output-directory>

Example:

    ~/smartpy-cli/SmartPy.sh compile welcome.py /tmp/welcome

### Deploying a contract

    # Using Micheline format (.tz)

    ~/smartpy-cli/SmartPy.sh originate-contract --code code.tz --storage storage.tz --rpc https://florencenet.smartpy.io

    # Using Michelson format (.json)

    ~/smartpy-cli/SmartPy.sh originate-contract --code code.json --storage storage.json --rpc https://florencenet.smartpy.io

    # By default, the originator will use a faucet account.
    # But you can provide your own private key as an argument

    ~/smartpy-cli/SmartPy.sh originate-contract --code code.json --storage storage.json --rpc https://florencenet.smartpy.io --private-key edsk...

### Custom Targets

SmartPy.sh kind <kind>

  Similar to tests. Perform scenarios defined in a `script.py` introduced by the custom target.

    ~/smartpy-cli/SmartPy.sh kind <kind> <script.py> <output-directory>

### CLI optional arguments

`SmartPy.sh` takes several optional arguments.

`--purge`

  Empty the output directory before writting to it.

`--html`

  Add some `.html` outputs such as a `log.html` which mimicks the output panel.

`--protocol <delphi|edo|florence|granada>`

  Select a Tezos protocol.
  Default is `florence`.

`--<flag> arguments`

  Set some `<flag>` with `arguments`.

`--<flag>`

  Activate some boolean `<flag>`.

`--no-<flag>`

  Deactivate some boolean `<flag>`.

`--mockup`

  Run in mockup (experimental, needs installed source).

`--sandbox`

  Run in sandbox (experimental, needs installed source).