Lambdas
The type of functions in SmartPy is sp.lambda_[t1, t2]
where t1
is the argument type and t2
the result type. It corresponds to the lambda
type in Michelson.
Lambdas can be defined either using Python's lambda x: ...
syntax or, when they have a name, using def f(x): ...
.
For example, the definition
f = lambda x: x + 1
is equivalent to:
def f(x):
return x + 1
Here f
has type sp.lambda_[sp.int,sp.int]
.
To call a lambda, simply pass it its argument in parentheses. For example, with the above definition:
assert f(1) == 2
Effects
Lambdas can be allowed to have so-called effects. These are specified by adding the @sp.effects(...)
decorator to a function definition.
Possible effects are:
@sp.effects(with_storage="read-only")
: Allows a lambda to read, but not modify a contract's storage.@sp.effects(with_storage="read-write")
: Allows a lambda to both read and modify a contract's storage.@sp.effects(with_operations=True)
: Allows a lambda to emit operations (e.g. transfers to other contracts). It can be eitherTrue
orFalse
.
Effects can also be combined, e.g. @sp.effects(with_storage="read-write", with_operations=True)
.
Example: Modifying storage
Here is a function that increments a counter every time it is called. It returns the updated value of the counter. Because the counter is kept in storage and modified, the read-write
storage effect needs to be declared.
@sp.effects(with_storage="read-write")
def fresh_id():
self.data.counter += 1
return self.data.counter
Example: Transfers from inside a lambda
Here is a function that sends one mutez to each contract in a given list. It returns the number of contracts called. Because sending (sp.transfer
) is an operation, the with_storage
effect needs to be declared.
@sp.effects(with_operations=True)
def send_one_mutez_to_each(winners):
count = 0
for w in winners:
count += 1
sp.transfer((), sp.mutez(1), w)
return count