Effects
You can control the effects of the different method kinds entrypoints, views, private functions and auxiliary functions by overwriting the default effect values in the method decorator.
For example, here is a declaration of an entrypoint that cannot raise an exception, assert anything or call any method that does either of those things:
@sp.entrypoint(with_exceptions=False)
def my_entrypoint(self):
pass
Changing the default effects
Possible effects are:
(with_storage="no-access")
: Prevents a method from reading or modifying a contract's storage.(with_storage="read-only")
: Allows a method to read but not modify a contract's storage. This is the default value for view methods.(with_storage="read-write")
: Allows a method to both read and modify a contract's storage. This is the default value for entrypoint methods. This effect is not allowed for view methods.(with_operations=True)
: Allows a method to emit operations, such as calls to other smart contracts or transfers of tez. Thewith_operations
parameter can be either True or False and has the default value of True for entrypoint methods. Thewith_operations=true
effect is not allowed for view methods.(with_exceptions=True)
: Allows a method to state assertions or raise exceptions. Thewith_exceptions
parameter can be either True or False and defaults to True for all method kinds.(with_mutez_overflow=True)
: Allows a method to perform calculations with mutez values that may overflow. Thewith_mutez_overflow
parameter can be either True or False and defaults to True for all method kinds.(with_mutez_underflow=True)
: Allows a method to perform calculations with mutez values that may underflow. Thewith_mutez_underflow
parameter can be either True or False and defaults to True for all method kinds.
Effects can also be combined, as in this example: @sp.private(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 private 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_operations
effect needs to be set to True.
@sp.private(with_operations=True)
def send_one_mutez_to_each(self, winners):
count = 0
for w in winners:
count += 1
sp.transfer((), sp.mutez(1), w)
return count