Skip to content
On this page

Contracts

Instantiating and originating contracts

module.<Contract>(**args) → instance
Instantiate the contract.

Call the __init__ method of the contract's class.

For example:

python
def main():
    class MyContract(sp.Contract):
        def __init__(self):
            pass

    class MyContract2(sp.Contract):
        def __init__(self, x):
            self.data.x = x
            pass

    class MyContract3(sp.Contract):
        def __init__(self, x, y):
            self.data.x = x
            self.data.y = y


@sp.add_test()
def test():
    sc = sp.test_scenario(main, "A Test")
    c1 = main.MyContract()
    c2 = main.MyContract2(2)
    c3 = main.MyContract3(x=5, y=2)
scenario +=  c: instance → 
Originate the contract in the scenario.
python
@sp.add_test()
def test():
    # Create a test scenario
    sc = sp.test_scenario(main, "A Test")
    # Instantiate a contract
    c = main.MyContract()
    # Originate the contract
    sc += c

Instance methods

Calls to entrypoints

c.<entrypoint>(**args) → 

Call an entrypoint with the given arguments.

If the entrypoint accepts multiple arguments they must be named or given as a record.

Generic context arguments: see context.

Specific context arguments are:

ParameterTypeDescription
_amountsp.mutezThe simulated amount sent. It populates sp.amount.
_validsp.boolTells the interpreter if the transaction is expected to fail or not. True by default.
_showsp.boolShow or hide the transaction. True by default.
_exceptionany typeThe expected exception raised by the transaction. If present, valid must be False.

Examples:

python
# Call entrypoint
c.my_entrypoint(12)

c.my_entrypoint(a="a", b="b")
# equivalent to
c.my_entrypoint(sp.record(a="a", b="b"))

# Call entrypoint with context attributes.
c.my_entrypoint(13,
    _sender          = None, # sp.address
    _source          = None, # sp.address
    _chain_id        = None, # sp.chain_id
    _level           = None, # sp.nait
    _now             = None, # sp.timestamp
    _voting_powers   = None, # sp.map[sp.key_hash, sp.nat]
    _amount          = None, # sp.mutez
    _valid           = True, # sp.bool
    _show            = True, # sp.bool
    _exception       = None, # any
)

# Test that a contract fails with a given exception
c.my_entrypoint(x=5, _valid=False, _exception="Error: x < 12")

Other instance methods

c.get_source() → 

Returns the source code of the contract. See metadata.

c.get_offchain_views() → 

Returns the offchain views of the contract. See metadata.

c.get_generated_michelson() → 

Returns the michelson code the contract. See metadata.

Before the origination

Some methods can only be called before the contract's origination to specify origination informations.

c.set_initial_balance(balance: sp.tez) → 

Set the initial balance that will be used when originating the contract in the tests.

python
c.set_initial_balance(sp.tez(20))
c.data  x: any → 
Replace a field in the contract's storage.

This is mostly useful to initialize the metadata big map. See metadata.

Exceptions

sp.is_failing(expression) → 

Returns True when an expression (views, lambdas, ...) results in failure, and False when the expression succeeds.

Content of exceptions

sp.catch_exception(expression, [t]) → sp.option[t]

t is optional, just using sp.catch_exception(<expression>) will be valid in most situations.

This method is used to test failing conditions of expressions (views, lambdas, ...). It returns an sp.option of type t that will contain sp.Some(<exception>) when the expression fails or None if it succeeds.

Views

Views, both off-chain or on-chain, can now be called from test scenarios the same way as entrypoints. The example below shows how to do it.

Example

python
import smartpy as sp

@sp.module
def main():
    class MyContract(sp.Contract):
        def __init__(self, param):
            self.data = param

        @sp.offchain_view()
        def state(self, param):
            assert param < 5, "This is false: param > 5"
            return self.data * param

@sp.add_test()
def test():
    scenario = sp.test_scenario("Minimal", main)
    c1 = main.MyContract(1)
    scenario += c1

    """ Test views """

    # Display the offchain call result
    scenario.show(c1.state(1))

    # Assert the view result
    scenario.verify(c1.state(2) == 2)
    # Assert call failures
    scenario.verify(sp.is_failing(c1.state(6)));    # Expected to fail
    scenario.verify(~ sp.is_failing(c1.state(1)));   # Not expected to fail

    # Assert exception result
    # catch_exception returns an option:
    # - None if the call succeeds
    # - sp.Some(<exception>) if the call fails
    e = sp.catch_exception(c1.state(7), t = sp.string)
    scenario.verify(e == sp.Some("This is false: param > 5"))

Context

Context arguments are:

ParameterTypeAccessorDescription
_sendersp.address or sp.test_accountsp.senderThe simulated sender of the computation.
Specific to computation.
_sourcesp.address or sp.test_accountsp.sourceThe simulated source of the computation.
Specific to computation.
_chain_idsp.chain_idsp.chain_idThe simulated chain_id.
Preserved until changed.
_levelsp.natsp.levelThe simulated block level.
Preserved until changed.
_nowsp.timestampsp.nowThe simulated block timestamp.
Preserved until changed.
_voting_powerssp.map[sp.key_hash, sp.nat]sp.total_voting_power,
sp.voting_power
The simulated voting powers for the test.
Preserved until changed.

Data associated with contracts

When a variable c1 represents a contract in a scenario, we can access some associated data:

  • c1.data: Contract's storage.

  • c1.balance: Contract's balance.

  • c1.baker: Contract's pptional delegated baker.

  • c1.address: Contract's address within the scenario.

    Details

    In storage or similar circumstances, deployed contracts get addresses of the form:

    • KT1TezoooozzSmartPyzzSTATiCzzzwwBFA1
    • KT1Tezooo1zzSmartPyzzSTATiCzzzyfC8eF
    • KT1Tezooo2zzSmartPyzzSTATiCzzzwqqQ4H
    • KT1Tezooo3zzSmartPyzzSTATiCzzzseJjWC
    • KT1Tezooo4zzSmartPyzzSTATiCzzzyPVdv3
    • KT1Tezooo5zzSmartPyzzSTATiCzzzz48Z4p
    • KT1Tezooo6zzSmartPyzzSTATiCzzztY1196
    • KT1Tezooo7zzSmartPyzzSTATiCzzzvTbG1z
    • KT1Tezooo8zzSmartPyzzSTATiCzzzzp29d1
    • KT1Tezooo9zzSmartPyzzSTATiCzzztdBMLX
    • KT1Tezoo1ozzSmartPyzzSTATiCzzzw8CmuY
    • ...
  • c1.typed

    Retrieve its testing typed contract value.

    To access entrypoints, one can use field notation:

    • c1.typed.my_entrypoint: to access typed entrypoint my_entrypoint of contract c1.