templates.test_with_storage

 1import smartpy as sp
 2
 3
 4@sp.module
 5def main():
 6    set_f_type: type = sp.lambda_(sp.int, sp.int, with_storage="read-write")
 7
 8    @sp.effects(with_storage="read-write")
 9    def set_f(x):
10        sp.cast(x, sp.int)
11        self.data.x = x
12        return x * 100
13
14    class Library(sp.Contract):
15        def __init__(self):
16            self.data.x = 0
17
18        @sp.onchain_view()
19        def get_set_f(self):
20            return set_f
21
22    # Same as Library, but different storage.
23    class Library2(sp.Contract):
24        def __init__(self):
25            self.data.y = "abc"
26
27        @sp.onchain_view()
28        def get_set_f(self):
29            return set_f
30
31    class Main(sp.Contract):
32        def __init__(self):
33            self.data.x = 0
34
35        @sp.entrypoint
36        def run(self, f, x):
37            sp.cast(f, set_f_type)
38            _ = f(x)
39
40        @sp.entrypoint
41        def save(self, f, x):
42            sp.cast(f, set_f_type)
43            self.data.x = f(x)
44
45    class Remote(sp.Contract):
46        @sp.entrypoint
47        def call(self, lib, main, x):
48            remote_set_f = sp.view("get_set_f", lib, (), set_f_type).unwrap_some()
49            main_run = sp.contract(
50                sp.record(f=set_f_type, x=sp.int), main, entrypoint="run"
51            ).unwrap_some()
52            sp.transfer(sp.record(f=remote_set_f, x=x), sp.mutez(0), main_run)
53
54
55@sp.add_test()
56def test():
57    s = sp.test_scenario("Effects", main)
58    lib = main.Library()
59    lib2 = main.Library2()
60    main_ = main.Main()
61    remote = main.Remote()
62    s += lib
63    s += lib2
64    s += main_
65    s += remote
66
67    # Using a storage-modifying lambda from another contract with the
68    # same storage:
69    main_.run(f=lib.get_set_f(), x=5)
70    s.verify(main_.data.x == 5)
71    s.verify(lib.data.x == 0)
72
73    # Same, but with Library2:
74    main_.run(f=lib2.get_set_f(), x=5)
75    s.verify(main_.data.x == 5)
76    s.verify(lib.data.x == 0)
77
78    # Same, but overwrite the storage immediately:
79    main_.save(f=lib.get_set_f(), x=5)
80    s.verify(main_.data.x == 500)
81    s.verify(lib.data.x == 0)
82
83    # Complicate things a little by doing it via a remote contract
84    # that doesn't have any state:
85    remote.call(lib=lib.address, main=main_.address, x=7)
86    s.verify(main_.data.x == 7)
87    s.verify(lib.data.x == 0)
88
89    # We can also define effectful lambdas outside contracts, but then
90    # we have to specify a tstorage:
91    def f(self, x):
92        self.data.x = 2 * x
93        sp.result(0)
94
95    my_f = sp.build_lambda(
96        f, with_storage="read-write", tstorage=sp.record(x=sp.int_or_nat)
97    )
98    main_.run(f=my_f, x=42)
99    s.verify(main_.data.x == 84)