Troubleshooting
Common errors
Here are some common errors that appear when compiling SmartPy contracts:
Error:
NameError: name 'sp' is not definedExplanation: SmartPy was not imported.
Resolution: Add
import smartpy as spat the beginning of the Python file.Error:
module 'smartpy' has no attribute 'Contract'Explanation: The SmartPy code is not inside a SmartPy module.
Resolution: Put smart contract code in a
.spyfile and add it to the scenario or inline it into the scenario file as a function decorated with@sp.module.Errors that refer to
sp.unknownorsp.int_or_natExplanation: SmartPy was unable to infer the type of a variable, parameter, or storage field. Because contracts must specify the type of their storage and parameters at deployment time, SmartPy must know the type of variables in storage and in entrypoints.
Resolution: Ensure that SmartPy can infer types by trying these solutions:
Ensure that the types of storage fields are clear. For example, if your contract stores a number, you may need to cast it to
sp.intorsp.natto clarify what type the number is. Errors that refer tosp.int_or_natmay mean that SmartPy can't tell if a variable is an integer or a nat.Similarly, ensure that the types of entrypoint parameters are clear by using type hints. Often, SmartPy can infer the type of a parameter by how it is used. For example, if a storage field is an integer and an entrypoint adds a parameter to that integer, the parameter must also be an integer. However, if SmartPy doesn't have a reference point, it may not be able to determine the type of a parameter. For example, if a storage field is a list and it gets initialized with an empty list, SmartPy would not have enough information to determine what type of elements the list contains.
Ensure that you are passing the correct parameter type. For example, if an entrypoint takes an integer as a parameter and you pass a nat, SmartPy throws the error
entrypoint expects parameter of type sp.unknown, but got sp.nat: mismatch between sp.int and sp.nat.
Errors that refer to
Expected type sp.record().layout()Explanation: Often this error means that an entrypoint expected parameters to be named fields in a record instead of a list.
Resolution: To pass multiple parameters to an entrypoint, pass them as a record. For example, if the entrypoint is defined as
def myEntrypoint(self, param1, param2), call it with the codecontract.myEntrypoint(param1 = 4, param2 = 3).Error:
Cannot convert expression to bool.Explanation: You cannot access information about a contract outside the test simulation. If you try to, SmartPy returns an expression that you can evaluate in the simulation later, not the value that you might expect.
For example, if a contract stores a number, you can't use it directly from the contract object as you might expect, as in this code:
smartpyb = contract.data.value # b is an expression, not a primitive value assert b > 9 # Exception: Cannot convert expression to bool.Resolution: Access contracts and expressions inside the simulation by using functions such as
scenario.verify, as in this example:smartpyscenario.verify(contract.data.value > 9)Error:
Missing variant 'x'orNew command outside of contractExplanation:
xis not a method or attribute of the specified object. These errors can appear if you use a method on the wrong object, such as if you callsp.verifyinstead ofscenario.verify.Resolution: Make sure that you are accessing the correct object.
Error:
[module name] is not defined.orname [function name] is not definedExplanation: SmartPy couldn't find the module or a function in a module.
Resolution: If you are using a library inside SmartPy contract code then import the module first, as in this example:
smartpy@sp.module def main(): import smartpy.stdlib.list_utils as lu class C(sp.Contract): def __init__(self): self.data = lu.replicate((3, 5))If you are using a library inside a test scenario then remember to add it to the scenario first, as in this example:
python@sp.add_test() def test(): scenario = sp.test_scenario("A Test") m = scenario.add_module("my/local/files/contracts.spy") contract = m.MyContract() scenario += contractAs a convenience, the SmartPy standard library can be accessed in test scenarios with
sp.stdlib, as in this example:pythonscenario = sp.test_scenario("my_test") scenario.verify(sp.stdlib.utils.mutez_to_nat(sp.mutez(1)) == sp.nat(1))