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:
@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:
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:
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:
@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:
@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)