Skip to content
On this page

Overview

Modules

SmartPy code is structured as one or more modules. Modules are defined using the @sp.module decorator. All code within a module is processed as SmartPy syntax. Example:

python
@sp.module
def main():
    class Calculator(sp.Contract):
        def __init__(self):
            self.data.result = 0

        @sp.entrypoint
        def multiply(self, x, y):
            self.data.result = x * y

This example defines a single SmartPy module called main (the name can be freely chosen), containing a single contract Calculator.

Because main is decorated with @sp.module, everything inside it is parsed as SmartPy syntax. The decorated function (main here) is never "executed". It is simply a way of structuring the source code.

Contracts

A SmartPy contract is defined as a Python class that inherits from sp.Contract. Each contract can have several entrypoints, each marked as sp.entrypoint.

Inside a contract the __init__ function can be used to initialise the storage by assigning to fields of self.data. Entrypoints can modify the storage. For example:

smartpy
class A(sp.Contract):
    def __init__(self):
        self.data.x = 0

    @sp.entrypoint
    def set_x(self, x):
        self.data.x = x

Inheritance

Contracts can inherit from each other, using the ordinary Python syntax:

smartpy
class A(sp.Contract):
    def __init__(self, x):
        self.data.x = x

class B(A):
    def __init__(self, x, y):
        A.__init__(self, x)
        self.data.y = y

Note that in SmartPy it is required that the superclass's __init__ function be called explicitly.

Auxiliary functions

Within a module, auxiliary functions can be defined and used across contracts:

python
@sp.module
def main():
    def add_one(x):
        return x + 1

    class C(sp.Contract):
        @sp.entrypoint
        def ep(self):
            assert add_one(42) == 43

Type abbreviations

Within a module, type abbreviations can be used to give names to complex types:

python
@sp.module
def main():
    t: type = sp.record(x=sp.int, y=sp.int)

    class C(sp.Contract):
        @sp.entrypoint
        def ep(self, x):
            sp.cast(x, t)