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()