SmartPy Focus: Importing SmartPy and Python code

SmartPy.io
3 min readOct 5, 2020

SmartPy is an intuitive and powerful smart contract development platform for Tezos. The SmartPy language is available through a Python library for building and analyzing Tezos smart contracts.

SmartPy scripts are usually rather self sufficient Python scripts: they start by importing smartpy.py with a statement import smartpy as sp, then proceed by defining one or several contract classes class MyContract(sp.Contract): and then add one or several tests.

This usually works very well in practice except that you may wish to import a standard implementation, share code in your project for different variations, split your tests and libraries, etc.

SmartPy is a real Python library so different strategies are possible.

This is documented in our reference manual.

Importing SmartPy and Python code

Import pure Python code

This is the most obvious task: if you have some Python code that you need to use, you can simply import it as you always do in Python.

Import a template

If you’re working on SmartPy.io (of with the SmartPy CLI with installed templates) and wish to import a template, we have a specific command called sp.import_template(template_name).

This is used in the Chainlink oracle template:

FA2 = sp.import_template("FA2.py")
class my_token(FA2.FA2):
...

Import some SmartPy script from a URL, a file, etc.

You can use sp.import_script_from_url(url) where url is a string of the form http://, https://, file://, file:, etc.

It is used in the same manner as sp.import_template.

Import some SmartPy script from the browser local storage

This can be done by using sp.import_script_from_local_storage(name). It is useful if you want to use the SmartPy.io/dev editor and use contracts that you have saved earlier.

It is also used in the same manner as sp.import_template.

Import some SmartPy script directly from a string

This can be done by using sp.import_script_from_script(name, script).

Edited on 20201010 with this paragraph.

Using imported code in practice

One of the key benefits of the SmartPy approach is that users remain in power: we try hard to avoid deciding too much when not necessary.

SmartPy is a Python library. It means that we can use real programming mechanism to organize our code.

Adding tests

You can do call

ttt = sp.import_template("tictactoe.py")

and ttt contains the tictactoe parsed and evaluated module.

Any element from the tictactoe.py template can be referenced to by prefixing by ttt.

A full example:

import smartpy as spttt = sp.import_template("tictactoe.py")@sp.add_test(name = "Other TicTacToe")
def test():
scenario = sp.test_scenario()
c1 = ttt.TicTacToe()
scenario += c1
scenario += c1.play(i = 0, j = 0, move = 1)

Inheriting classes to add new features

In the Chainlink Oracle template, we needed to add a proxy function. This was done by doing:

FA2 = sp.import_template("FA2.py")
class Link_token(FA2.FA2):
@sp.entry_point
def proxy(self, oracle, params):
...

Mixins

A class inherits small classes that bring identified features.
For example, the FA1.2 and FA2 templates now use “mixins”.

class FA2(
FA2_token_metadata,
FA2_mint,
FA2_administrator,
FA2_pause,
FA2_core):
def __init__(self, config, admin):
FA2_core.__init__(self, config,
paused = False,
administrator = admin)

If we wanted to define a FA2 without a mint entry point, we could write in the same template:

class FA2_no_mint(
FA2_token_metadata,
# FA2_mint,
FA2_administrator,
FA2_pause,
FA2_core):
def __init__(self, config, admin):
FA2_core.__init__(self, config,
paused = False,
administrator = admin)

If we want to do it in another file, we can do:

FA2 = sp.import_template("FA2.py")
class FA2_no_mint(
FA2.FA2_token_metadata,
# FA2_mint,
FA2.FA2_administrator,
FA2.FA2_pause,
FA2.FA2_core):
def __init__(self, config, admin):
FA2.FA2_core.__init__(self, config,
paused = False,
administrator = admin)

Ad-hoc edition of contracts

Please note that there are other mechanisms to define a FA2_no_mint, we can directly edit entry points.

FA2 = sp.import_template("FA2.py")
class FA2_no_mint(FA2.FA2):
def __init__(self, config, admin):
FA2.FA2.__init__(self, config, admin)
self.mint = None

We prefer the mixins approach as it is more standard in Python.

Getting involved

If you modify a template in a way that can be useful for everybody, especially making it more understandable or easier to extend, please do not hesitate to go to GitLab to post a merge-request or get in touch with us through Telegram or Twitter.

--

--

SmartPy.io

An intuitive and effective smart contracts language and development platform for Tezos. In Python.