Overview
Modules
A part of a Python source code file can be marked a as SmartPy module. This is done as follows:
@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
Any class inheriting from sp.Contract
defines a SmartPy 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
Inside a module we can define auxiliary values and functions. These can then be used inside 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
Modules can also contain type abbreviations. A type abbreviation simply gives a name to a type. For example we can define t
to be a record type and then refer to it later in a contract:
@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)