SmartPy Focus: Importing SmartPy and Python code
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.