Global constants โ
The feature documentation can be found here.
Global constants are placeholders that reference valid Micheline
stored in a global table of constants. The Micheline
replaces the placeholder before the contract gets parsed and type-checked.
This feature allows contracts to reuse existing code stored as constants, resulting in contracts of reduced size.
See reference Constants template.
WARNING
Note that using the sp.unpack operation to construct a lambda or sp.create_contract instruction that contains a constant reference is not possible.
Using a constant as a value โ
sp.constant("expr...",ย tย =ย <type>)
Where expr...
is the hash
of the constant that points to some Micheline
code stored on-chain, and t
is an optional argument that explicitly informs the compiler about the constant type after it gets expanded.
# The storage field `x` will be set to the value stored as constant `expr...`
self.data.x = sp.constant("expr...", t = sp.TNat)
Constants in test scenarios โ
<scenario>.prepare_constant_value(<some_value>,ย hashย =ย <"expr...">)
Where <scenario>
is a test scenario, <some_value>
is the value that the constant will point to, and hash
is an optional argument that, if specified, will override the real hash of the constant.
@sp.add_test(name = "Testing with constants")
def test():
# Create a scenario
scenario = sp.test_scenario()
# Create a constant from a value
constant = scenario.prepare_constant_value(100)
# Print the constant
scenario.show(constant)
Result โ
Complete example โ
The code below uses a constant expruDpiV1FEzeYhWAQBVeCSEYMQbnUovq9Cbddqy6xLMeEe1zkGRA
to look up a string value.
import smartpy as sp
class Constants(sp.Contract):
def __init__(self, storage, constant1, constant2):
self.constant1 = constant1
self.constant2 = constant2
self.init(storage)
@sp.entrypoint
def ep(self, x):
# Compute the new value from values stored as constants
self.data = self.constant1(x) + self.constant2
@sp.add_test(name = "Test constants")
def test():
# Create a scenario
scenario = sp.test_scenario()
# Create some lambda
def some_lambda(x):
sp.result(x * 10)
# Create 2 constants from their values
constant1 = scenario.prepare_constant_value(some_lambda)
constant2 = scenario.prepare_constant_value(100)
# Print the constants
scenario.show(constant1)
scenario.show(constant2)
# Create contract
contract = Constants(0, constant1 = constant1, constant2 = constant2)
scenario += contract
# Call the contract
contract.ep(10)
sp.add_compilation_target(
"constants_compilation",
Constants(
0,
constant1 = sp.constant("c1", t = sp.TLambda(sp.TNat, sp.TNat)),
constant2 = sp.constant("c2", t = sp.TNat)
)
)