SmartPy - inadvertent meta-programmation with control statements
Control statements in SmartPy may inadvertent lead to a wrong meta-programmation. See code example below
It is recommended to carefully review SmartPy code containing control statements and to implement appropriate test cases to cover expected working of control statements.
Code example for an sp.if control statement written in SmartPy. Can also be viewed in SmartPy IDE.
# Store Value - Example for illustrative purposes only.
import smartpy as sp
class StoreValue(sp.Contract):
def __init__(self, value):
self.init(storedValue = value, magic_one = True)
@sp.entry_point
def set(self):
magic_data = 0
sp.if self.data.magic_one:
magic_data = 1
sp.else:
magic_data = 2
self.data.storedValue = magic_data
if "templates" not in __name__:
@sp.add_test(name = "StoreValue")
def test():
c1 = StoreValue(12)
scenario = sp.test_scenario()
scenario.h1("Store Value")
scenario += c1
scenario = c1.set()
sp.add_compilation_target("storeValue", StoreValue(12))
Solution 1 with direct modification. See directly in SmartPy IDE.
# Store Value - Example for illustrative purposes only.
import smartpy as sp
class StoreValue(sp.Contract):
def __init__(self, value):
self.init(storedValue = value, magic_one = True)
@sp.entry_point
def set(self):
sp.if self.data.magic_one:
self.data.storedValue = 1
sp.else:
self.data.storedValue = 2
if "templates" not in __name__:
@sp.add_test(name = "StoreValue")
def test():
c1 = StoreValue(12)
scenario = sp.test_scenario()
scenario.h1("Store Value")
scenario += c1
scenario = c1.set()
sp.add_compilation_target("storeValue", StoreValue(12))
Solution 2 using locals. See directly in SmartPy IDE.
# Store Value - Example for illustrative purposes only.
import smartpy as sp
class StoreValue(sp.Contract):
def __init__(self, value):
self.init(storedValue = value, magic_one = True)
@sp.entry_point
def set(self):
storedValue = sp.local("storedValue", self.data.storedValue)
sp.if self.data.magic_one:
storedValue.value = 1
sp.else:
storedValue.value = 2
self.data.storedValue = storedValue.value
if "templates" not in __name__:
@sp.add_test(name = "StoreValue")
def test():
c1 = StoreValue(12)
scenario = sp.test_scenario()
scenario.h1("Store Value")
scenario += c1
scenario = c1.set()
sp.add_compilation_target("storeValue", StoreValue(12))