templates.inlineMichelson

  1import smartpy as sp
  2
  3
  4@sp.module
  5def main():
  6    class C(sp.Contract):
  7        def __init__(self):
  8            self.data.value = 0
  9            self.data.s = ""
 10
 11        @sp.entrypoint
 12        def arith(self):
 13            assert sp.michelson("ADD", [int, int], [int], 1, 2) == 3
 14            assert sp.michelson("ADD", [int, int], [int], 1, -2) == -1
 15
 16            assert sp.michelson("SUB", [int, int], [int], 1, -2) == 3
 17            assert sp.michelson("SUB", [int, int], [int], 1, 2) == -1
 18
 19        @sp.entrypoint
 20        def prim0(self):
 21            assert sp.michelson("UNIT", [], [sp.unit]) == ()
 22
 23            assert sp.michelson("NONE unit", [], [sp.option[sp.unit]]) == None
 24
 25            assert sp.michelson(
 26                "PUSH int 2; PUSH int 1; PAIR", [], [sp.pair[int, int]]
 27            ) == (1, 2)
 28
 29            assert sp.len(sp.michelson("NIL unit", [], [list[sp.unit]])) == 0
 30
 31            assert sp.len(sp.michelson("EMPTY_SET unit", [], [set[sp.unit]])) == 0
 32
 33            assert (
 34                sp.len(sp.michelson("EMPTY_MAP unit unit", [], [map[sp.unit, sp.unit]]))
 35                == 0
 36            )
 37
 38            # assert sp.len(michelson("EMPTY_BIG_MAP unit unit", [], [bigmap[unit, unit]])) == 0)
 39
 40        @sp.entrypoint
 41        def overflow_add(self):
 42            _ = sp.michelson(
 43                "ADD",
 44                [sp.mutez, sp.mutez],
 45                [sp.mutez],
 46                sp.mutez(9223372036854775807),
 47                sp.mutez(1),
 48            )
 49
 50        @sp.entrypoint
 51        def overflow_mul(self):
 52            _ = sp.michelson(
 53                "MUL", [sp.mutez, sp.nat], [sp.mutez], sp.mutez(4611686018427387904), 2
 54            )
 55
 56        @sp.entrypoint
 57        def underflow(self):
 58            assert (
 59                sp.michelson(
 60                    "SUB_MUTEZ",
 61                    [sp.mutez, sp.mutez],
 62                    [sp.option[sp.mutez]],
 63                    sp.mutez(0),
 64                    sp.mutez(1),
 65                )
 66                == None
 67            )
 68
 69        @sp.entrypoint
 70        def concat1(self):
 71            assert (
 72                sp.michelson("CONCAT", [list[sp.string]], [sp.string], ["a", "b", "c"])
 73                == "abc"
 74            )
 75
 76        @sp.entrypoint
 77        def concat2(self):
 78            assert (
 79                sp.michelson("CONCAT", [sp.string, sp.string], [sp.string], "a", "b")
 80                == "ab"
 81            )
 82
 83        @sp.entrypoint
 84        def seq(self):
 85            assert (
 86                sp.michelson(
 87                    "DIP {SWAP}; ADD; MUL; DUP; MUL;",
 88                    [int, int, int],
 89                    [int],
 90                    15,
 91                    16,
 92                    17,
 93                )
 94                == 262144
 95            )
 96
 97        @sp.entrypoint
 98        def lambdas(self):
 99            assert (
100                sp.michelson(
101                    "PUSH (lambda int int) {DUP; ADD}; SWAP; EXEC;", [int], [int], 100
102                )
103                == 200
104            )
105
106            # f = michelson("PUSH (lambda (pair int int) int) {UNPAIR; PUSH int 10; MUL; ADD;}; SWAP; EXEC;", [int, int], [int])
107            # assert f(2,5) == 25
108            # TODO Why does this not fail during type checking?
109
110            assert (
111                sp.michelson(
112                    "PAIR; PUSH (lambda (pair int int) int) { UNPAIR; PUSH int 10; MUL; ADD;}; SWAP; EXEC;",
113                    [int, int],
114                    [int],
115                    2,
116                    5,
117                )
118                == 25
119            )
120
121            assert (
122                sp.michelson(
123                    "PAIR 3; PUSH (lambda (pair int int int) int) { UNPAIR 3; PUSH int 10; MUL; ADD; PUSH int 10; MUL; ADD;}; SWAP; EXEC;",
124                    [int, int, int],
125                    [int],
126                    2,
127                    5,
128                    7,
129                )
130                == 257
131            )
132
133            assert (
134                sp.michelson(
135                    "PUSH (lambda (pair int int int) int) { UNPAIR 3; PUSH int 10; MUL; ADD; PUSH int 10; MUL; ADD;}; PUSH int 2; APPLY; PUSH int 5; APPLY; PUSH int 7; EXEC;",
136                    [],
137                    [int],
138                )
139                == 257
140            )
141
142            # TODO lambda that traverses the SmartPy-Michelson barrier
143
144            assert (
145                sp.michelson(
146                    "LAMBDA_REC int int                { DUP; PUSH int 1; COMPARE; GE; IF { DROP 2; PUSH int 1; } { DUP; PUSH int 1; SWAP; SUB; DIG 2; SWAP; EXEC; MUL; }; }; SWAP; EXEC;",
147                    [int],
148                    [int],
149                    5,
150                )
151                == 120
152            )
153
154            assert (
155                sp.michelson(
156                    "PUSH (lambda int int) (Lambda_rec { DUP; PUSH int 1; COMPARE; GE; IF { DROP 2; PUSH int 1; } { DUP; PUSH int 1; SWAP; SUB; DIG 2; SWAP; EXEC; MUL; }; }); SWAP; EXEC;",
157                    [int],
158                    [int],
159                    5,
160                )
161                == 120
162            )
163
164        @sp.entrypoint
165        def test_operations(self):
166            op1 = sp.michelson("NONE key_hash; SET_DELEGATE;", [], [sp.operation])
167            sp.operations.push(op1)
168
169            c = sp.michelson(
170                "PUSH int 123; PUSH mutez 0; NONE key_hash; CREATE_CONTRACT { parameter int; storage int; code { UNPAIR; ADD; NIL operation; PAIR } }; PAIR",
171                [],
172                [sp.pair[sp.operation, sp.address]],
173            )
174            (op, address) = c
175            sp.operations.push(sp.fst(c))
176
177
178@sp.add_test()
179def test():
180    scenario = sp.test_scenario("Inline Michelson", main)
181    c = main.C()
182    scenario += c
183    c.prim0()
184    c.arith()
185    c.overflow_add(_valid=False, _exception="ADD: mutez overflow")
186    c.overflow_mul(_valid=False, _exception="MUL: mutez overflow")
187    c.underflow()
188    c.seq()
189    c.lambdas()
190    c.test_operations()