@tezos-x/octez.js-michel-codec 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +174 -0
- package/dist/lib/base58.js +255 -0
- package/dist/lib/binary.js +1272 -0
- package/dist/lib/errors.js +90 -0
- package/dist/lib/formatters.js +60 -0
- package/dist/lib/global-constants.js +12 -0
- package/dist/lib/macros.js +548 -0
- package/dist/lib/micheline-emitter.js +132 -0
- package/dist/lib/micheline-parser.js +403 -0
- package/dist/lib/micheline.js +5 -0
- package/dist/lib/michelson-contract.js +93 -0
- package/dist/lib/michelson-typecheck.js +1752 -0
- package/dist/lib/michelson-types.js +83 -0
- package/dist/lib/michelson-validator.js +835 -0
- package/dist/lib/octez.js-michel-codec.js +38 -0
- package/dist/lib/scan.js +128 -0
- package/dist/lib/utils.js +321 -0
- package/dist/lib/version.js +8 -0
- package/dist/octez.js-michel-codec.es6.js +5790 -0
- package/dist/octez.js-michel-codec.es6.js.map +1 -0
- package/dist/octez.js-michel-codec.umd.js +5854 -0
- package/dist/octez.js-michel-codec.umd.js.map +1 -0
- package/dist/types/base58.d.ts +13 -0
- package/dist/types/binary.d.ts +127 -0
- package/dist/types/errors.d.ts +57 -0
- package/dist/types/formatters.d.ts +6 -0
- package/dist/types/global-constants.d.ts +3 -0
- package/dist/types/macros.d.ts +13 -0
- package/dist/types/micheline-emitter.d.ts +17 -0
- package/dist/types/micheline-parser.d.ts +130 -0
- package/dist/types/micheline.d.ts +44 -0
- package/dist/types/michelson-contract.d.ts +24 -0
- package/dist/types/michelson-typecheck.d.ts +38 -0
- package/dist/types/michelson-types.d.ts +147 -0
- package/dist/types/michelson-validator.d.ts +66 -0
- package/dist/types/octez.js-michel-codec.d.ts +16 -0
- package/dist/types/scan.d.ts +26 -0
- package/dist/types/utils.d.ts +77 -0
- package/dist/types/version.d.ts +4 -0
- package/package.json +94 -0
- package/signature.json +315 -0
|
@@ -0,0 +1,1752 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.MichelsonInstructionError = void 0;
|
|
15
|
+
exports.assertTypeAnnotationsValid = assertTypeAnnotationsValid;
|
|
16
|
+
exports.contractSection = contractSection;
|
|
17
|
+
exports.contractViews = contractViews;
|
|
18
|
+
exports.contractEntryPoint = contractEntryPoint;
|
|
19
|
+
exports.contractEntryPoints = contractEntryPoints;
|
|
20
|
+
exports.assertContractValid = assertContractValid;
|
|
21
|
+
exports.assertDataValid = assertDataValid;
|
|
22
|
+
exports.functionType = functionType;
|
|
23
|
+
exports.assertTypesEqual = assertTypesEqual;
|
|
24
|
+
exports.isTypeAnnotationsValid = isTypeAnnotationsValid;
|
|
25
|
+
exports.isContractValid = isContractValid;
|
|
26
|
+
exports.isDataValid = isDataValid;
|
|
27
|
+
exports.isTypeEqual = isTypeEqual;
|
|
28
|
+
const michelson_types_1 = require("./michelson-types");
|
|
29
|
+
const utils_1 = require("./utils");
|
|
30
|
+
const base58_1 = require("./base58");
|
|
31
|
+
const binary_1 = require("./binary");
|
|
32
|
+
const michelson_validator_1 = require("./michelson-validator");
|
|
33
|
+
class MichelsonInstructionError extends utils_1.MichelsonError {
|
|
34
|
+
/**
|
|
35
|
+
* @param val Value of a type node caused the error
|
|
36
|
+
* @param stackState Current stack state
|
|
37
|
+
* @param message An error message
|
|
38
|
+
*/
|
|
39
|
+
constructor(val, stackState, message) {
|
|
40
|
+
super(val, message);
|
|
41
|
+
this.val = val;
|
|
42
|
+
this.stackState = stackState;
|
|
43
|
+
this.message = message;
|
|
44
|
+
this.name = 'MichelsonInstructionError';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.MichelsonInstructionError = MichelsonInstructionError;
|
|
48
|
+
// 'sequence as a pair' edo syntax helpers
|
|
49
|
+
function typeID(t) {
|
|
50
|
+
return Array.isArray(t) ? 'pair' : t.prim;
|
|
51
|
+
}
|
|
52
|
+
function typeArgs(t) {
|
|
53
|
+
return ('prim' in t ? t.args : t);
|
|
54
|
+
}
|
|
55
|
+
function assertScalarTypesEqual(a, b, field = false) {
|
|
56
|
+
if (typeID(a) !== typeID(b)) {
|
|
57
|
+
throw new utils_1.MichelsonTypeError(a, `types mismatch: ${typeID(a)} != ${typeID(b)}`, undefined);
|
|
58
|
+
}
|
|
59
|
+
const ann = [(0, utils_1.unpackAnnotations)(a), (0, utils_1.unpackAnnotations)(b)];
|
|
60
|
+
if (ann[0].t && ann[1].t && ann[0].t[0] !== ann[1].t[0]) {
|
|
61
|
+
throw new utils_1.MichelsonTypeError(a, `${typeID(a)}: type names mismatch: ${ann[0].t[0]} != ${ann[1].t[0]}`, undefined);
|
|
62
|
+
}
|
|
63
|
+
if (field && ann[0].f && ann[1].f && ann[0].f[0] !== ann[1].f[0]) {
|
|
64
|
+
throw new utils_1.MichelsonTypeError(a, `${typeID(a)}: field names mismatch: ${ann[0].f[0]} != ${ann[1].f}`, undefined);
|
|
65
|
+
}
|
|
66
|
+
if ((0, utils_1.isPairType)(a)) {
|
|
67
|
+
const aArgs = (0, utils_1.unpackComb)('pair', a);
|
|
68
|
+
const bArgs = (0, utils_1.unpackComb)('pair', b);
|
|
69
|
+
assertScalarTypesEqual(aArgs.args[0], bArgs.args[0], true);
|
|
70
|
+
assertScalarTypesEqual(aArgs.args[1], bArgs.args[1], true);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
switch (a.prim) {
|
|
74
|
+
case 'option':
|
|
75
|
+
case 'list':
|
|
76
|
+
case 'contract':
|
|
77
|
+
case 'set':
|
|
78
|
+
case 'ticket':
|
|
79
|
+
assertScalarTypesEqual(a.args[0], b.args[0]);
|
|
80
|
+
break;
|
|
81
|
+
case 'or':
|
|
82
|
+
assertScalarTypesEqual(a.args[0], b.args[0], true);
|
|
83
|
+
assertScalarTypesEqual(a.args[1], b.args[1], true);
|
|
84
|
+
break;
|
|
85
|
+
case 'lambda':
|
|
86
|
+
case 'map':
|
|
87
|
+
case 'big_map':
|
|
88
|
+
assertScalarTypesEqual(a.args[0], b.args[0]);
|
|
89
|
+
assertScalarTypesEqual(a.args[1], b.args[1]);
|
|
90
|
+
break;
|
|
91
|
+
case 'sapling_state':
|
|
92
|
+
case 'sapling_transaction':
|
|
93
|
+
if (parseInt(a.args[0].int, 10) !== parseInt(b.args[0].int, 10)) {
|
|
94
|
+
throw new utils_1.MichelsonTypeError(a, `${typeID(a)}: type argument mismatch: ${a.args[0].int} != ${b.args[0].int}`, undefined);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function assertStacksEqual(a, b) {
|
|
99
|
+
if (a.length !== b.length) {
|
|
100
|
+
throw new utils_1.MichelsonTypeError(a, `stack length mismatch: ${a.length} != ${b.length}`, undefined);
|
|
101
|
+
}
|
|
102
|
+
for (let i = 0; i < a.length; i++) {
|
|
103
|
+
assertScalarTypesEqual(a[i], b[i]);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function assertTypeAnnotationsValid(t, field = false) {
|
|
107
|
+
var _a, _b, _c;
|
|
108
|
+
if (!Array.isArray(t)) {
|
|
109
|
+
const ann = (0, utils_1.unpackAnnotations)(t);
|
|
110
|
+
if ((((_a = ann.t) === null || _a === void 0 ? void 0 : _a.length) || 0) > 1) {
|
|
111
|
+
throw new utils_1.MichelsonTypeError(t, `${t.prim}: at most one type annotation allowed: ${t.annots}`, undefined);
|
|
112
|
+
}
|
|
113
|
+
if (field) {
|
|
114
|
+
if ((((_b = ann.f) === null || _b === void 0 ? void 0 : _b.length) || 0) > 1) {
|
|
115
|
+
throw new utils_1.MichelsonTypeError(t, `${t.prim}: at most one field annotation allowed: ${t.annots}`, undefined);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
if ((((_c = ann.f) === null || _c === void 0 ? void 0 : _c.length) || 0) > 0) {
|
|
120
|
+
throw new utils_1.MichelsonTypeError(t, `${t.prim}: field annotations aren't allowed: ${t.annots}`, undefined);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if ((0, utils_1.isPairType)(t)) {
|
|
125
|
+
const args = typeArgs(t);
|
|
126
|
+
for (const a of args) {
|
|
127
|
+
assertTypeAnnotationsValid(a, true);
|
|
128
|
+
}
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
switch (t.prim) {
|
|
132
|
+
case 'option':
|
|
133
|
+
case 'list':
|
|
134
|
+
case 'contract':
|
|
135
|
+
case 'set':
|
|
136
|
+
assertTypeAnnotationsValid(t.args[0]);
|
|
137
|
+
break;
|
|
138
|
+
case 'or':
|
|
139
|
+
for (const a of t.args) {
|
|
140
|
+
assertTypeAnnotationsValid(a, true);
|
|
141
|
+
}
|
|
142
|
+
break;
|
|
143
|
+
case 'lambda':
|
|
144
|
+
case 'map':
|
|
145
|
+
case 'big_map':
|
|
146
|
+
assertTypeAnnotationsValid(t.args[0]);
|
|
147
|
+
assertTypeAnnotationsValid(t.args[1]);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Data integrity check
|
|
151
|
+
function _compareMichelsonData(t, a, b) {
|
|
152
|
+
if ((0, utils_1.isPairType)(t)) {
|
|
153
|
+
if ((0, utils_1.isPairData)(a) && (0, utils_1.isPairData)(b)) {
|
|
154
|
+
(0, michelson_validator_1.assertDataListIfAny)(a);
|
|
155
|
+
(0, michelson_validator_1.assertDataListIfAny)(b);
|
|
156
|
+
const tComb = (0, utils_1.unpackComb)('pair', t);
|
|
157
|
+
const aComb = (0, utils_1.unpackComb)('Pair', a);
|
|
158
|
+
const bComb = (0, utils_1.unpackComb)('Pair', b);
|
|
159
|
+
const x = _compareMichelsonData(tComb.args[0], aComb.args[0], bComb.args[0]);
|
|
160
|
+
if (x !== 0) {
|
|
161
|
+
return x;
|
|
162
|
+
}
|
|
163
|
+
return _compareMichelsonData(tComb.args[0], aComb.args[1], bComb.args[1]);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
switch (t.prim) {
|
|
168
|
+
case 'int':
|
|
169
|
+
case 'nat':
|
|
170
|
+
case 'mutez':
|
|
171
|
+
if ('int' in a && 'int' in b) {
|
|
172
|
+
return new utils_1.LongInteger(a.int).cmp(new utils_1.LongInteger(b.int));
|
|
173
|
+
}
|
|
174
|
+
break;
|
|
175
|
+
case 'string':
|
|
176
|
+
if ('string' in a && 'string' in b) {
|
|
177
|
+
const x = a.string.localeCompare(b.string);
|
|
178
|
+
return x < 0 ? -1 : x > 0 ? 1 : 0;
|
|
179
|
+
}
|
|
180
|
+
break;
|
|
181
|
+
case 'bytes':
|
|
182
|
+
if ('bytes' in a && 'bytes' in b) {
|
|
183
|
+
const aa = (0, utils_1.parseBytes)(a.bytes);
|
|
184
|
+
const bb = (0, utils_1.parseBytes)(b.bytes);
|
|
185
|
+
if (aa !== null && bb !== null) {
|
|
186
|
+
return (0, utils_1.compareBytes)(aa, bb);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
break;
|
|
190
|
+
case 'bool':
|
|
191
|
+
if ('prim' in a &&
|
|
192
|
+
'prim' in b &&
|
|
193
|
+
(a.prim === 'True' || a.prim === 'False') &&
|
|
194
|
+
(b.prim === 'True' || b.prim === 'False')) {
|
|
195
|
+
return a.prim === b.prim ? 0 : a.prim === 'False' ? -1 : 1;
|
|
196
|
+
}
|
|
197
|
+
break;
|
|
198
|
+
case 'key':
|
|
199
|
+
case 'key_hash':
|
|
200
|
+
case 'address':
|
|
201
|
+
case 'signature':
|
|
202
|
+
case 'chain_id':
|
|
203
|
+
if (('string' in a || 'bytes' in a) && ('string' in b || 'bytes' in b)) {
|
|
204
|
+
return (0, utils_1.compareBytes)('string' in a ? (0, base58_1.decodeBase58Check)(a.string) : (0, utils_1.parseBytes)(a.bytes) || [], 'string' in b ? (0, base58_1.decodeBase58Check)(b.string) : (0, utils_1.parseBytes)(b.bytes) || []);
|
|
205
|
+
}
|
|
206
|
+
break;
|
|
207
|
+
case 'timestamp':
|
|
208
|
+
if (('string' in a || 'int' in a) && ('string' in b || 'int' in b)) {
|
|
209
|
+
const aa = (0, utils_1.parseDate)(a);
|
|
210
|
+
const bb = (0, utils_1.parseDate)(b);
|
|
211
|
+
if (aa !== null && bb !== null) {
|
|
212
|
+
const x = aa.valueOf() - bb.valueOf();
|
|
213
|
+
return x < 0 ? -1 : x > 0 ? 1 : 0;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
break;
|
|
217
|
+
case 'unit':
|
|
218
|
+
if ('prim' in a && 'prim' in b && a.prim === 'Unit' && b.prim === 'Unit') {
|
|
219
|
+
return 0;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// Unlikely, types are expected to be verified before the function call
|
|
224
|
+
throw new utils_1.MichelsonTypeError(t, `${typeID(t)}: not comparable values: ${JSON.stringify(a)}, ${JSON.stringify(b)}`, undefined);
|
|
225
|
+
}
|
|
226
|
+
// Simplified version of assertMichelsonInstruction() for previously validated data
|
|
227
|
+
function isFunction(d) {
|
|
228
|
+
if (!Array.isArray(d)) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
for (const v of d) {
|
|
232
|
+
if (!((Array.isArray(v) && isFunction(v)) || ('prim' in v && (0, michelson_validator_1.isInstruction)(v)))) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
function assertDataValidInternal(d, t, ctx) {
|
|
239
|
+
if ((0, utils_1.isPairType)(t)) {
|
|
240
|
+
if ((0, utils_1.isPairData)(d)) {
|
|
241
|
+
(0, michelson_validator_1.assertDataListIfAny)(d);
|
|
242
|
+
const dc = (0, utils_1.unpackComb)('Pair', d);
|
|
243
|
+
const tc = (0, utils_1.unpackComb)('pair', t);
|
|
244
|
+
assertDataValidInternal(dc.args[0], tc.args[0], ctx);
|
|
245
|
+
assertDataValidInternal(dc.args[1], tc.args[1], ctx);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
throw new utils_1.MichelsonTypeError(t, `pair expected: ${JSON.stringify(d)}`, d);
|
|
249
|
+
}
|
|
250
|
+
switch (t.prim) {
|
|
251
|
+
// Atomic literals
|
|
252
|
+
case 'int':
|
|
253
|
+
if ('int' in d && (0, utils_1.isDecimal)(d.int)) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
throw new utils_1.MichelsonTypeError(t, `integer value expected: ${JSON.stringify(d)}`, d);
|
|
257
|
+
case 'nat':
|
|
258
|
+
case 'mutez':
|
|
259
|
+
if ('int' in d && (0, utils_1.isNatural)(d.int)) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
throw new utils_1.MichelsonTypeError(t, `natural value expected: ${JSON.stringify(d)}`, d);
|
|
263
|
+
case 'string':
|
|
264
|
+
if ('string' in d) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
throw new utils_1.MichelsonTypeError(t, `string value expected: ${JSON.stringify(d)}`, d);
|
|
268
|
+
case 'bytes':
|
|
269
|
+
case 'bls12_381_g1':
|
|
270
|
+
case 'bls12_381_g2':
|
|
271
|
+
if ('bytes' in d && (0, utils_1.parseBytes)(d.bytes) !== null) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
throw new utils_1.MichelsonTypeError(t, `bytes value expected: ${JSON.stringify(d)}`, d);
|
|
275
|
+
case 'bool':
|
|
276
|
+
if ('prim' in d && (d.prim === 'True' || d.prim === 'False')) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
throw new utils_1.MichelsonTypeError(t, `boolean value expected: ${JSON.stringify(d)}`, d);
|
|
280
|
+
case 'key_hash':
|
|
281
|
+
if ('string' in d &&
|
|
282
|
+
(0, utils_1.checkDecodeTezosID)(d.string, 'ED25519PublicKeyHash', 'SECP256K1PublicKeyHash', 'P256PublicKeyHash') !== null) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
else if ('bytes' in d) {
|
|
286
|
+
try {
|
|
287
|
+
(0, binary_1.decodePublicKeyHashBytes)(d);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
catch (err) {
|
|
291
|
+
// ignore message
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
throw new utils_1.MichelsonTypeError(t, `key hash expected: ${JSON.stringify(d)}`, d);
|
|
295
|
+
case 'timestamp':
|
|
296
|
+
if (('string' in d || 'int' in d) && (0, utils_1.parseDate)(d) !== null) {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
throw new utils_1.MichelsonTypeError(t, `timestamp expected: ${JSON.stringify(d)}`, d);
|
|
300
|
+
case 'address':
|
|
301
|
+
if ('string' in d) {
|
|
302
|
+
let address = d.string;
|
|
303
|
+
const ep = d.string.indexOf('%');
|
|
304
|
+
if (ep >= 0) {
|
|
305
|
+
// trim entry point
|
|
306
|
+
address = d.string.slice(0, ep);
|
|
307
|
+
}
|
|
308
|
+
if ((0, utils_1.checkDecodeTezosID)(address, 'ED25519PublicKeyHash', 'SECP256K1PublicKeyHash', 'P256PublicKeyHash', 'ContractHash', 'RollupAddress') !== null) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
else if ('bytes' in d) {
|
|
313
|
+
try {
|
|
314
|
+
(0, binary_1.decodeAddressBytes)(d);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
catch (err) {
|
|
318
|
+
// ignore message
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
throw new utils_1.MichelsonTypeError(t, `address expected: ${JSON.stringify(d)}`, d);
|
|
322
|
+
case 'key':
|
|
323
|
+
if ('string' in d &&
|
|
324
|
+
(0, utils_1.checkDecodeTezosID)(d.string, 'ED25519PublicKey', 'SECP256K1PublicKey', 'P256PublicKey') !==
|
|
325
|
+
null) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
else if ('bytes' in d) {
|
|
329
|
+
try {
|
|
330
|
+
(0, binary_1.decodePublicKeyBytes)(d);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
catch (err) {
|
|
334
|
+
// ignore message
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
throw new utils_1.MichelsonTypeError(t, `public key expected: ${JSON.stringify(d)}`, d);
|
|
338
|
+
case 'unit':
|
|
339
|
+
if ('prim' in d && d.prim === 'Unit') {
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
throw new utils_1.MichelsonTypeError(t, `unit value expected: ${JSON.stringify(d)}`, d);
|
|
343
|
+
case 'signature':
|
|
344
|
+
if ('bytes' in d ||
|
|
345
|
+
('string' in d &&
|
|
346
|
+
(0, utils_1.checkDecodeTezosID)(d.string, 'ED25519Signature', 'SECP256K1Signature', 'P256Signature', 'GenericSignature') !== null)) {
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
throw new utils_1.MichelsonTypeError(t, `signature expected: ${JSON.stringify(d)}`, d);
|
|
350
|
+
case 'chain_id':
|
|
351
|
+
if ('bytes' in d || 'string' in d) {
|
|
352
|
+
const x = 'string' in d ? (0, base58_1.decodeBase58Check)(d.string) : (0, utils_1.parseBytes)(d.bytes);
|
|
353
|
+
if (x !== null) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
throw new utils_1.MichelsonTypeError(t, `chain id expected: ${JSON.stringify(d)}`, d);
|
|
358
|
+
// Complex types
|
|
359
|
+
case 'option':
|
|
360
|
+
if ('prim' in d) {
|
|
361
|
+
if (d.prim === 'None') {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
else if (d.prim === 'Some') {
|
|
365
|
+
assertDataValidInternal(d.args[0], t.args[0], ctx);
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
throw new utils_1.MichelsonTypeError(t, `option expected: ${JSON.stringify(d)}`, d);
|
|
370
|
+
case 'list':
|
|
371
|
+
case 'set':
|
|
372
|
+
if ((0, michelson_validator_1.assertDataListIfAny)(d)) {
|
|
373
|
+
//let prev: MichelsonData | undefined;
|
|
374
|
+
for (const v of d) {
|
|
375
|
+
assertDataValidInternal(v, t.args[0], ctx);
|
|
376
|
+
}
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
throw new utils_1.MichelsonTypeError(t, `${t.prim} expected: ${JSON.stringify(d)}`, d);
|
|
380
|
+
case 'or':
|
|
381
|
+
if ('prim' in d) {
|
|
382
|
+
if (d.prim === 'Left') {
|
|
383
|
+
assertDataValidInternal(d.args[0], t.args[0], ctx);
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
else if (d.prim === 'Right') {
|
|
387
|
+
assertDataValidInternal(d.args[0], t.args[1], ctx);
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
throw new utils_1.MichelsonTypeError(t, `union (or) expected: ${JSON.stringify(d)}`, d);
|
|
392
|
+
case 'lambda':
|
|
393
|
+
if (isFunction(d)) {
|
|
394
|
+
const ret = functionTypeInternal(d, [t.args[0]], ctx);
|
|
395
|
+
if ('failed' in ret) {
|
|
396
|
+
throw new utils_1.MichelsonTypeError(t, `function is failed with error type: ${ret.failed}`, d);
|
|
397
|
+
}
|
|
398
|
+
if (ret.length !== 1) {
|
|
399
|
+
throw new utils_1.MichelsonTypeError(t, 'function must return a value', d);
|
|
400
|
+
}
|
|
401
|
+
assertScalarTypesEqual(t.args[1], ret[0]);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
throw new utils_1.MichelsonTypeError(t, `function expected: ${JSON.stringify(d)}`, d);
|
|
405
|
+
case 'map':
|
|
406
|
+
case 'big_map':
|
|
407
|
+
if (Array.isArray(d)) {
|
|
408
|
+
//let prev: MichelsonMapElt | undefined;
|
|
409
|
+
for (const v of d) {
|
|
410
|
+
if (!('prim' in v) || v.prim !== 'Elt') {
|
|
411
|
+
throw new utils_1.MichelsonTypeError(t, `map elements expected: ${JSON.stringify(d)}`, d);
|
|
412
|
+
}
|
|
413
|
+
assertDataValidInternal(v.args[0], t.args[0], ctx);
|
|
414
|
+
assertDataValidInternal(v.args[1], t.args[1], ctx);
|
|
415
|
+
}
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
throw new utils_1.MichelsonTypeError(t, `${t.prim} expected: ${JSON.stringify(d)}`, d);
|
|
419
|
+
case 'bls12_381_fr':
|
|
420
|
+
if (('int' in d && (0, utils_1.isDecimal)(d.int)) || ('bytes' in d && (0, utils_1.parseBytes)(d.bytes) !== null)) {
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
throw new utils_1.MichelsonTypeError(t, `BLS12-381 element expected: ${JSON.stringify(d)}`, d);
|
|
424
|
+
case 'sapling_state':
|
|
425
|
+
if (Array.isArray(d)) {
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
throw new utils_1.MichelsonTypeError(t, `sapling state expected: ${JSON.stringify(d)}`, d);
|
|
429
|
+
case 'ticket':
|
|
430
|
+
if ('prim' in d && d.prim === 'Ticket') {
|
|
431
|
+
assertDataValidInternal(d.args[0], { prim: 'address' }, ctx);
|
|
432
|
+
assertTypesEqual(d.args[1], t.args[0]);
|
|
433
|
+
assertDataValidInternal(d.args[2], t.args[0], ctx);
|
|
434
|
+
assertDataValidInternal(d.args[3], { prim: 'nat' }, ctx);
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
else if ((0, utils_1.isPairData)(d)) {
|
|
438
|
+
// backward compatibility
|
|
439
|
+
assertDataValidInternal(d, {
|
|
440
|
+
prim: 'pair',
|
|
441
|
+
args: [{ prim: 'address' }, t.args[0], { prim: 'nat' }],
|
|
442
|
+
}, ctx);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
throw new utils_1.MichelsonTypeError(t, `ticket expected: ${JSON.stringify(d)}`, d);
|
|
446
|
+
default:
|
|
447
|
+
throw new utils_1.MichelsonTypeError(t, `type ${typeID(t)} don't have Michelson literal representation`, d);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
function instructionListType(inst, stack, ctx) {
|
|
451
|
+
let ret = stack;
|
|
452
|
+
let s = stack;
|
|
453
|
+
let i = 0;
|
|
454
|
+
for (const op of inst) {
|
|
455
|
+
const ft = functionTypeInternal(op, s, ctx);
|
|
456
|
+
ret = ft;
|
|
457
|
+
if ('failed' in ft) {
|
|
458
|
+
break;
|
|
459
|
+
}
|
|
460
|
+
s = ft;
|
|
461
|
+
i++;
|
|
462
|
+
}
|
|
463
|
+
if ('failed' in ret &&
|
|
464
|
+
ret.level == 0 &&
|
|
465
|
+
(!('prim' in ret.failed) || ret.failed.prim !== 'never') &&
|
|
466
|
+
i !== inst.length - 1) {
|
|
467
|
+
throw new MichelsonInstructionError(inst, ret, 'FAIL must appear in a tail position');
|
|
468
|
+
}
|
|
469
|
+
if ((ctx === null || ctx === void 0 ? void 0 : ctx.traceCallback) !== undefined) {
|
|
470
|
+
const trace = {
|
|
471
|
+
op: inst,
|
|
472
|
+
in: stack,
|
|
473
|
+
out: ret,
|
|
474
|
+
};
|
|
475
|
+
ctx.traceCallback(trace);
|
|
476
|
+
}
|
|
477
|
+
return 'failed' in ret ? { failed: ret.failed, level: ret.level + 1 } : ret;
|
|
478
|
+
}
|
|
479
|
+
function functionTypeInternal(inst, stack, ctx) {
|
|
480
|
+
const proto = (ctx === null || ctx === void 0 ? void 0 : ctx.protocol) || michelson_types_1.DefaultProtocol;
|
|
481
|
+
if (Array.isArray(inst)) {
|
|
482
|
+
return instructionListType(inst, stack, ctx);
|
|
483
|
+
}
|
|
484
|
+
const instruction = inst; // Make it const for type guarding
|
|
485
|
+
// make sure the stack has enough number of arguments of specific types
|
|
486
|
+
function args(n, ...typeIds) {
|
|
487
|
+
if (stack.length < typeIds.length + n) {
|
|
488
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: stack must have at least ${typeIds.length} element(s)`);
|
|
489
|
+
}
|
|
490
|
+
let i = n;
|
|
491
|
+
for (const ids of typeIds) {
|
|
492
|
+
if (ids !== null && ids.length !== 0) {
|
|
493
|
+
let ii = 0;
|
|
494
|
+
while (ii < ids.length && ids[ii] !== typeID(stack[i])) {
|
|
495
|
+
ii++;
|
|
496
|
+
}
|
|
497
|
+
if (ii === ids.length) {
|
|
498
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: stack type mismatch: [${i}] expected to be ${ids}, got ${typeID(stack[i])} instead`);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
i++;
|
|
502
|
+
}
|
|
503
|
+
return stack.slice(n, typeIds.length + n);
|
|
504
|
+
}
|
|
505
|
+
function rethrow(fn) {
|
|
506
|
+
return (...args) => {
|
|
507
|
+
try {
|
|
508
|
+
return fn(...args);
|
|
509
|
+
}
|
|
510
|
+
catch (err) {
|
|
511
|
+
if (err instanceof utils_1.MichelsonError) {
|
|
512
|
+
throw new MichelsonInstructionError(instruction, stack, err.message);
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
throw err;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
function rethrowTypeGuard(fn) {
|
|
521
|
+
return (arg) => {
|
|
522
|
+
try {
|
|
523
|
+
return fn(arg);
|
|
524
|
+
}
|
|
525
|
+
catch (err) {
|
|
526
|
+
if (err instanceof utils_1.MichelsonError) {
|
|
527
|
+
throw new MichelsonInstructionError(instruction, stack, err.message);
|
|
528
|
+
}
|
|
529
|
+
else {
|
|
530
|
+
throw err;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
const argAnn = rethrow(utils_1.unpackAnnotations);
|
|
536
|
+
const ensureStacksEqual = rethrow(assertStacksEqual);
|
|
537
|
+
const ensureTypesEqual = rethrow(assertScalarTypesEqual);
|
|
538
|
+
const ensureComparableType = rethrowTypeGuard(michelson_validator_1.assertMichelsonComparableType);
|
|
539
|
+
const ensurePackableType = rethrowTypeGuard(michelson_validator_1.assertMichelsonPackableType);
|
|
540
|
+
const ensureStorableType = rethrowTypeGuard(michelson_validator_1.assertMichelsonStorableType);
|
|
541
|
+
const ensurePushableType = rethrowTypeGuard(michelson_validator_1.assertMichelsonPushableType);
|
|
542
|
+
const ensureBigMapStorableType = rethrowTypeGuard(michelson_validator_1.assertMichelsonBigMapStorableType);
|
|
543
|
+
// unpack instruction annotations and assert their maximum number
|
|
544
|
+
function instructionAnn(num, opt) {
|
|
545
|
+
const a = argAnn(instruction, Object.assign(Object.assign({}, opt), { emptyFields: num.f !== undefined && num.f > 1, emptyVar: num.v !== undefined && num.v > 1 }));
|
|
546
|
+
const assertNum = (a, n, type) => {
|
|
547
|
+
if (a && a.length > (n || 0)) {
|
|
548
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: at most ${n || 0} ${type} annotations allowed`);
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
assertNum(a.f, num.f, 'field');
|
|
552
|
+
assertNum(a.t, num.t, 'type');
|
|
553
|
+
assertNum(a.v, num.v, 'variable');
|
|
554
|
+
return a;
|
|
555
|
+
}
|
|
556
|
+
// also keeps annotation class if null is provided
|
|
557
|
+
function annotate(tt, a) {
|
|
558
|
+
const tx = tt;
|
|
559
|
+
const t = Array.isArray(tx) ? { prim: 'pair', args: tx } : tx;
|
|
560
|
+
const src = argAnn(t);
|
|
561
|
+
const ann = a.v !== undefined || a.t !== undefined || a.f !== undefined
|
|
562
|
+
? [
|
|
563
|
+
...((a.v === null ? src.v : a.v) || []),
|
|
564
|
+
...((a.t === null ? src.t : a.t) || []),
|
|
565
|
+
...((a.f === null ? src.f : a.f) || []),
|
|
566
|
+
]
|
|
567
|
+
: undefined;
|
|
568
|
+
const { annots: _annots } = t, rest = __rest(t, ["annots"]);
|
|
569
|
+
return Object.assign(Object.assign({}, rest), (ann && ann.length !== 0 && { annots: ann }));
|
|
570
|
+
}
|
|
571
|
+
// shortcut to copy at most one variable annotation from the instruction to the type
|
|
572
|
+
function annotateVar(t, def) {
|
|
573
|
+
const ia = instructionAnn({ v: 1 });
|
|
574
|
+
return annotate(t, {
|
|
575
|
+
v: ia.v !== undefined ? ia.v : def !== undefined ? [def] : null,
|
|
576
|
+
t: null,
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
// annotate CAR/CDR/UNPAIR/GET
|
|
580
|
+
function annotateField(arg, field, insAnn, n, defField) {
|
|
581
|
+
var _a, _b, _c, _d;
|
|
582
|
+
const fieldAnn = (_a = argAnn(field).f) === null || _a === void 0 ? void 0 : _a[0]; // field's field annotation
|
|
583
|
+
const insFieldAnn = (_b = insAnn.f) === null || _b === void 0 ? void 0 : _b[n];
|
|
584
|
+
if (insFieldAnn !== undefined &&
|
|
585
|
+
insFieldAnn !== '%' &&
|
|
586
|
+
fieldAnn !== undefined &&
|
|
587
|
+
insFieldAnn !== fieldAnn) {
|
|
588
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: field names doesn't match: ${insFieldAnn} !== ${fieldAnn}`);
|
|
589
|
+
}
|
|
590
|
+
const insVarAnn = (_c = insAnn.v) === null || _c === void 0 ? void 0 : _c[n]; // nth instruction's variable annotation
|
|
591
|
+
const varAnn = (_d = argAnn(arg).v) === null || _d === void 0 ? void 0 : _d[0]; // instruction argument's variable annotation
|
|
592
|
+
return annotate(field, {
|
|
593
|
+
t: null,
|
|
594
|
+
v: insVarAnn
|
|
595
|
+
? insVarAnn === '@%'
|
|
596
|
+
? fieldAnn
|
|
597
|
+
? ['@' + fieldAnn.slice(1)]
|
|
598
|
+
: undefined
|
|
599
|
+
: insVarAnn === '@%%'
|
|
600
|
+
? varAnn
|
|
601
|
+
? ['@' + varAnn.slice(1) + '.' + (fieldAnn ? fieldAnn.slice(1) : defField)]
|
|
602
|
+
: fieldAnn
|
|
603
|
+
? ['@' + fieldAnn.slice(1)]
|
|
604
|
+
: undefined
|
|
605
|
+
: [insVarAnn]
|
|
606
|
+
: null,
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
// comb helper functions
|
|
610
|
+
function getN(src, n, i = n) {
|
|
611
|
+
const p = (0, utils_1.unpackComb)('pair', src);
|
|
612
|
+
if (i === 1) {
|
|
613
|
+
return [p.args[0]];
|
|
614
|
+
}
|
|
615
|
+
else if (i === 2) {
|
|
616
|
+
return p.args;
|
|
617
|
+
}
|
|
618
|
+
const right = p.args[1];
|
|
619
|
+
if ((0, utils_1.isPairType)(right)) {
|
|
620
|
+
return [p.args[0], ...getN(right, n, i - 1)];
|
|
621
|
+
}
|
|
622
|
+
else {
|
|
623
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: at least ${n} fields are expected`);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
function getNth(src, n, i = n) {
|
|
627
|
+
if (i === 0) {
|
|
628
|
+
return src;
|
|
629
|
+
}
|
|
630
|
+
const p = (0, utils_1.unpackComb)('pair', src);
|
|
631
|
+
if (i === 1) {
|
|
632
|
+
return p.args[0];
|
|
633
|
+
}
|
|
634
|
+
const right = p.args[1];
|
|
635
|
+
if ((0, utils_1.isPairType)(right)) {
|
|
636
|
+
return getNth(right, n, i - 2);
|
|
637
|
+
}
|
|
638
|
+
else if (i === 2) {
|
|
639
|
+
return right;
|
|
640
|
+
}
|
|
641
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: at least ${n + 1} fields are expected`);
|
|
642
|
+
}
|
|
643
|
+
function updateNth(src, x, n, i = n) {
|
|
644
|
+
if (i === 0) {
|
|
645
|
+
return x;
|
|
646
|
+
}
|
|
647
|
+
const p = (0, utils_1.unpackComb)('pair', src);
|
|
648
|
+
if (i === 1) {
|
|
649
|
+
return Object.assign(Object.assign({}, p), { args: [x, p.args[1]] });
|
|
650
|
+
}
|
|
651
|
+
const right = p.args[1];
|
|
652
|
+
if ((0, utils_1.isPairType)(right)) {
|
|
653
|
+
return Object.assign(Object.assign({}, p), { args: [p.args[0], updateNth(right, x, n, i - 2)] });
|
|
654
|
+
}
|
|
655
|
+
else if (i === 2) {
|
|
656
|
+
return Object.assign(Object.assign({}, p), { args: [p.args[0], x] });
|
|
657
|
+
}
|
|
658
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: at least ${n + 1} fields are expected`);
|
|
659
|
+
}
|
|
660
|
+
const varSuffix = (a, suffix) => [
|
|
661
|
+
'@' + (a.v ? a.v[0].slice(1) + '.' : '') + suffix,
|
|
662
|
+
];
|
|
663
|
+
function branchType(br0, br1) {
|
|
664
|
+
if ('failed' in br0 || 'failed' in br1) {
|
|
665
|
+
return 'failed' in br0 ? br1 : br0;
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
668
|
+
ensureStacksEqual(br0, br1);
|
|
669
|
+
return br0;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
const retStack = ((instruction) => {
|
|
673
|
+
var _a, _b, _c, _d, _e;
|
|
674
|
+
switch (instruction.prim) {
|
|
675
|
+
case 'DUP': {
|
|
676
|
+
const n = instruction.args ? parseInt(instruction.args[0].int, 10) : 1;
|
|
677
|
+
if (n === 0) {
|
|
678
|
+
throw new MichelsonInstructionError(instruction, stack, 'DUP 0 is forbidden');
|
|
679
|
+
}
|
|
680
|
+
const s = args(n - 1, null)[0];
|
|
681
|
+
if (typeID(s) === 'ticket') {
|
|
682
|
+
throw new MichelsonInstructionError(instruction, stack, "ticket can't be DUPed");
|
|
683
|
+
}
|
|
684
|
+
return [s, ...stack];
|
|
685
|
+
}
|
|
686
|
+
case 'SWAP': {
|
|
687
|
+
const s = args(0, null, null);
|
|
688
|
+
instructionAnn({});
|
|
689
|
+
return [s[1], s[0], ...stack.slice(2)];
|
|
690
|
+
}
|
|
691
|
+
case 'SOME':
|
|
692
|
+
return [
|
|
693
|
+
annotate({ prim: 'option', args: [args(0, null)[0]] }, instructionAnn({ t: 1, v: 1 })),
|
|
694
|
+
...stack.slice(1),
|
|
695
|
+
];
|
|
696
|
+
case 'UNIT':
|
|
697
|
+
return [annotate({ prim: 'unit' }, instructionAnn({ v: 1, t: 1 })), ...stack];
|
|
698
|
+
case 'PAIR': {
|
|
699
|
+
const n = instruction.args ? parseInt(instruction.args[0].int, 10) : 2;
|
|
700
|
+
if (n < 2) {
|
|
701
|
+
throw new MichelsonInstructionError(instruction, stack, `PAIR ${n} is forbidden`);
|
|
702
|
+
}
|
|
703
|
+
const s = args(0, ...new Array(n).fill(null));
|
|
704
|
+
const ia = instructionAnn({ f: n, t: 1, v: 1 }, { specialFields: true });
|
|
705
|
+
const trim = (s) => {
|
|
706
|
+
const i = s.lastIndexOf('.');
|
|
707
|
+
return s.slice(i > 0 ? i + 1 : 1);
|
|
708
|
+
};
|
|
709
|
+
const retArgs = s.map((v, i) => {
|
|
710
|
+
var _a;
|
|
711
|
+
const va = argAnn(v);
|
|
712
|
+
const f = ia.f && ia.f.length > i && ia.f[i] !== '%'
|
|
713
|
+
? ia.f[i] === '%@'
|
|
714
|
+
? va.v
|
|
715
|
+
? ['%' + trim(((_a = va.v) === null || _a === void 0 ? void 0 : _a[0]) || '')]
|
|
716
|
+
: undefined
|
|
717
|
+
: [ia.f[i]]
|
|
718
|
+
: undefined;
|
|
719
|
+
return annotate(v, { v: null, t: null, f });
|
|
720
|
+
});
|
|
721
|
+
return [
|
|
722
|
+
annotate({
|
|
723
|
+
prim: 'pair',
|
|
724
|
+
args: retArgs,
|
|
725
|
+
}, { t: ia.t, v: ia.v }),
|
|
726
|
+
...stack.slice(n),
|
|
727
|
+
];
|
|
728
|
+
}
|
|
729
|
+
case 'UNPAIR': {
|
|
730
|
+
const n = instruction.args ? parseInt(instruction.args[0].int, 10) : 2;
|
|
731
|
+
if (n < 2) {
|
|
732
|
+
throw new MichelsonInstructionError(instruction, stack, `UNPAIR ${n} is forbidden`);
|
|
733
|
+
}
|
|
734
|
+
const s = args(0, ['pair'])[0];
|
|
735
|
+
const ia = instructionAnn({ f: 2, v: 2 }, { specialVar: true });
|
|
736
|
+
const fields = getN(s, n);
|
|
737
|
+
return [
|
|
738
|
+
...fields.map((field, i) => annotateField(s, field, ia, i, i === 0 ? 'car' : 'cdr')),
|
|
739
|
+
...stack.slice(1),
|
|
740
|
+
];
|
|
741
|
+
}
|
|
742
|
+
case 'CAR':
|
|
743
|
+
case 'CDR': {
|
|
744
|
+
const s = (0, utils_1.unpackComb)('pair', args(0, ['pair'])[0]);
|
|
745
|
+
const field = s.args[instruction.prim === 'CAR' ? 0 : 1];
|
|
746
|
+
const ia = instructionAnn({ f: 1, v: 1 }, { specialVar: true });
|
|
747
|
+
return [
|
|
748
|
+
annotateField(s, field, ia, 0, instruction.prim.toLocaleLowerCase()),
|
|
749
|
+
...stack.slice(1),
|
|
750
|
+
];
|
|
751
|
+
}
|
|
752
|
+
case 'CONS': {
|
|
753
|
+
const s = args(0, null, ['list']);
|
|
754
|
+
ensureTypesEqual(s[0], s[1].args[0]);
|
|
755
|
+
return [annotateVar({ prim: 'list', args: [s[1].args[0]] }), ...stack.slice(2)];
|
|
756
|
+
}
|
|
757
|
+
case 'SIZE':
|
|
758
|
+
args(0, ['string', 'list', 'set', 'map', 'bytes']);
|
|
759
|
+
return [annotateVar({ prim: 'nat' }), ...stack.slice(1)];
|
|
760
|
+
case 'MEM': {
|
|
761
|
+
const s = args(0, null, ['set', 'map', 'big_map']);
|
|
762
|
+
ensureComparableType(s[0]);
|
|
763
|
+
ensureTypesEqual(s[0], s[1].args[0]);
|
|
764
|
+
return [annotateVar({ prim: 'bool' }), ...stack.slice(2)];
|
|
765
|
+
}
|
|
766
|
+
case 'GET':
|
|
767
|
+
if (instruction.args) {
|
|
768
|
+
// comb operation
|
|
769
|
+
const n = parseInt(instruction.args[0].int, 10);
|
|
770
|
+
const s = args(0, ['pair'])[0];
|
|
771
|
+
return [annotateVar(getNth(s, n)), ...stack.slice(1)];
|
|
772
|
+
}
|
|
773
|
+
else {
|
|
774
|
+
// map operation
|
|
775
|
+
const s = args(0, null, ['map', 'big_map']);
|
|
776
|
+
ensureComparableType(s[0]);
|
|
777
|
+
ensureTypesEqual(s[0], s[1].args[0]);
|
|
778
|
+
return [annotateVar({ prim: 'option', args: [s[1].args[1]] }), ...stack.slice(2)];
|
|
779
|
+
}
|
|
780
|
+
case 'UPDATE':
|
|
781
|
+
if (instruction.args) {
|
|
782
|
+
// comb operation
|
|
783
|
+
const n = parseInt(instruction.args[0].int, 10);
|
|
784
|
+
const s = args(0, null, ['pair']);
|
|
785
|
+
return [annotateVar(updateNth(s[1], s[0], n)), ...stack.slice(2)];
|
|
786
|
+
}
|
|
787
|
+
else {
|
|
788
|
+
// map operation
|
|
789
|
+
const s0 = args(0, null, ['bool', 'option']);
|
|
790
|
+
ensureComparableType(s0[0]);
|
|
791
|
+
if (s0[1].prim === 'bool') {
|
|
792
|
+
const s1 = args(2, ['set']);
|
|
793
|
+
ensureTypesEqual(s0[0], s1[0].args[0]);
|
|
794
|
+
return [
|
|
795
|
+
annotateVar({
|
|
796
|
+
prim: 'set',
|
|
797
|
+
args: [annotate(s0[0], { t: null })],
|
|
798
|
+
}),
|
|
799
|
+
...stack.slice(3),
|
|
800
|
+
];
|
|
801
|
+
}
|
|
802
|
+
const s1 = args(2, ['map', 'big_map']);
|
|
803
|
+
ensureTypesEqual(s0[0], s1[0].args[0]);
|
|
804
|
+
if (s1[0].prim === 'map') {
|
|
805
|
+
return [
|
|
806
|
+
annotateVar({
|
|
807
|
+
prim: 'map',
|
|
808
|
+
args: [annotate(s0[0], { t: null }), annotate(s0[1].args[0], { t: null })],
|
|
809
|
+
}),
|
|
810
|
+
...stack.slice(3),
|
|
811
|
+
];
|
|
812
|
+
}
|
|
813
|
+
ensureBigMapStorableType(s0[1].args[0]);
|
|
814
|
+
return [
|
|
815
|
+
annotateVar({
|
|
816
|
+
prim: 'big_map',
|
|
817
|
+
args: [annotate(s0[0], { t: null }), annotate(s0[1].args[0], { t: null })],
|
|
818
|
+
}),
|
|
819
|
+
...stack.slice(3),
|
|
820
|
+
];
|
|
821
|
+
}
|
|
822
|
+
case 'GET_AND_UPDATE': {
|
|
823
|
+
const ia = instructionAnn({ v: 2 });
|
|
824
|
+
const s = args(0, null, ['option'], ['map', 'big_map']);
|
|
825
|
+
ensureComparableType(s[0]);
|
|
826
|
+
ensureTypesEqual(s[0], s[2].args[0]);
|
|
827
|
+
ensureTypesEqual(s[1].args[0], s[2].args[1]);
|
|
828
|
+
const va = (_a = ia.v) === null || _a === void 0 ? void 0 : _a.map((v) => (v !== '@' ? [v] : undefined));
|
|
829
|
+
if (s[2].prim === 'map') {
|
|
830
|
+
return [
|
|
831
|
+
annotate({ prim: 'option', args: [s[2].args[1]] }, { v: va === null || va === void 0 ? void 0 : va[0] }),
|
|
832
|
+
annotate({
|
|
833
|
+
prim: 'map',
|
|
834
|
+
args: [annotate(s[0], { t: null }), annotate(s[1].args[0], { t: null })],
|
|
835
|
+
}, { v: va === null || va === void 0 ? void 0 : va[1] }),
|
|
836
|
+
...stack.slice(3),
|
|
837
|
+
];
|
|
838
|
+
}
|
|
839
|
+
ensureBigMapStorableType(s[1].args[0]);
|
|
840
|
+
return [
|
|
841
|
+
annotate({ prim: 'option', args: [s[2].args[1]] }, { v: va === null || va === void 0 ? void 0 : va[0] }),
|
|
842
|
+
annotate({
|
|
843
|
+
prim: 'big_map',
|
|
844
|
+
args: [annotate(s[0], { t: null }), annotate(s[1].args[0], { t: null })],
|
|
845
|
+
}, { v: va === null || va === void 0 ? void 0 : va[1] }),
|
|
846
|
+
...stack.slice(3),
|
|
847
|
+
];
|
|
848
|
+
}
|
|
849
|
+
case 'EXEC': {
|
|
850
|
+
const s = args(0, null, ['lambda']);
|
|
851
|
+
ensureTypesEqual(s[0], s[1].args[0]);
|
|
852
|
+
return [annotateVar(s[1].args[1]), ...stack.slice(2)];
|
|
853
|
+
}
|
|
854
|
+
case 'APPLY': {
|
|
855
|
+
const s = args(0, null, ['lambda']);
|
|
856
|
+
ensureStorableType(s[0]);
|
|
857
|
+
ensurePushableType(s[0]);
|
|
858
|
+
if (!(0, utils_1.isPairType)(s[1].args[0])) {
|
|
859
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: function's argument must be a pair: ${typeID(s[1].args[0])}`);
|
|
860
|
+
}
|
|
861
|
+
const pt = s[1].args[0];
|
|
862
|
+
ensureTypesEqual(s[0], typeArgs(pt)[0]);
|
|
863
|
+
return [
|
|
864
|
+
annotateVar({ prim: 'lambda', args: [typeArgs(pt)[1], s[1].args[1]] }),
|
|
865
|
+
...stack.slice(2),
|
|
866
|
+
];
|
|
867
|
+
}
|
|
868
|
+
case 'FAILWITH': {
|
|
869
|
+
const s = args(0, null)[0];
|
|
870
|
+
if (!(0, michelson_types_1.ProtoInferiorTo)(proto, michelson_types_1.Protocol.PtEdo2Zk)) {
|
|
871
|
+
ensurePackableType(s);
|
|
872
|
+
}
|
|
873
|
+
return { failed: s, level: 0 };
|
|
874
|
+
}
|
|
875
|
+
case 'NEVER':
|
|
876
|
+
args(0, ['never']);
|
|
877
|
+
return { failed: { prim: 'never' }, level: 0 };
|
|
878
|
+
case 'RENAME':
|
|
879
|
+
return [annotateVar(args(0, null)[0]), ...stack.slice(1)];
|
|
880
|
+
case 'CONCAT': {
|
|
881
|
+
const s0 = args(0, ['string', 'list', 'bytes']);
|
|
882
|
+
if (s0[0].prim === 'list') {
|
|
883
|
+
if (typeID(s0[0].args[0]) !== 'string' && typeID(s0[0].args[0]) !== 'bytes') {
|
|
884
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: can't concatenate list of ${typeID(s0[0].args[0])}'s`);
|
|
885
|
+
}
|
|
886
|
+
return [annotateVar(s0[0].args[0]), ...stack.slice(1)];
|
|
887
|
+
}
|
|
888
|
+
const s1 = args(1, ['string', 'bytes']);
|
|
889
|
+
if (s0[0].prim !== s1[0].prim) {
|
|
890
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: can't concatenate ${s0[0].prim} with ${s1[0].prim}`);
|
|
891
|
+
}
|
|
892
|
+
return [annotateVar(s1[0]), ...stack.slice(2)];
|
|
893
|
+
}
|
|
894
|
+
case 'SLICE':
|
|
895
|
+
return [
|
|
896
|
+
annotateVar({ prim: 'option', args: [args(0, ['nat'], ['nat'], ['string', 'bytes'])[2]] }, '@slice'),
|
|
897
|
+
...stack.slice(3),
|
|
898
|
+
];
|
|
899
|
+
case 'PACK': {
|
|
900
|
+
const s = args(0, null)[0];
|
|
901
|
+
ensurePackableType(s);
|
|
902
|
+
return [annotateVar({ prim: 'bytes' }, '@packed'), ...stack.slice(1)];
|
|
903
|
+
}
|
|
904
|
+
case 'ADD': {
|
|
905
|
+
const s = args(0, ['nat', 'int', 'timestamp', 'mutez', 'bls12_381_g1', 'bls12_381_g2', 'bls12_381_fr'], ['nat', 'int', 'timestamp', 'mutez', 'bls12_381_g1', 'bls12_381_g2', 'bls12_381_fr']);
|
|
906
|
+
if ((s[0].prim === 'nat' && s[1].prim === 'int') ||
|
|
907
|
+
(s[0].prim === 'int' && s[1].prim === 'nat')) {
|
|
908
|
+
return [annotateVar({ prim: 'int' }), ...stack.slice(2)];
|
|
909
|
+
}
|
|
910
|
+
else if ((s[0].prim === 'int' && s[1].prim === 'timestamp') ||
|
|
911
|
+
(s[0].prim === 'timestamp' && s[1].prim === 'int')) {
|
|
912
|
+
return [annotateVar({ prim: 'timestamp' }), ...stack.slice(2)];
|
|
913
|
+
}
|
|
914
|
+
else if ((s[0].prim === 'int' ||
|
|
915
|
+
s[0].prim === 'nat' ||
|
|
916
|
+
s[0].prim === 'mutez' ||
|
|
917
|
+
s[0].prim === 'bls12_381_g1' ||
|
|
918
|
+
s[0].prim === 'bls12_381_g2' ||
|
|
919
|
+
s[0].prim === 'bls12_381_fr') &&
|
|
920
|
+
s[0].prim === s[1].prim) {
|
|
921
|
+
return [annotateVar(s[0]), ...stack.slice(2)];
|
|
922
|
+
}
|
|
923
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: can't add ${s[0].prim} to ${s[1].prim}`);
|
|
924
|
+
}
|
|
925
|
+
case 'SUB': {
|
|
926
|
+
const s = (0, michelson_types_1.ProtoInferiorTo)(proto, michelson_types_1.Protocol.PsiThaCa)
|
|
927
|
+
? args(0, ['nat', 'int', 'timestamp', 'mutez'], ['nat', 'int', 'timestamp', 'mutez'])
|
|
928
|
+
: args(0, ['nat', 'int', 'timestamp'], ['nat', 'int', 'timestamp']);
|
|
929
|
+
if (((s[0].prim === 'nat' || s[0].prim === 'int') &&
|
|
930
|
+
(s[1].prim === 'nat' || s[1].prim === 'int')) ||
|
|
931
|
+
(s[0].prim === 'timestamp' && s[1].prim === 'timestamp')) {
|
|
932
|
+
return [annotateVar({ prim: 'int' }), ...stack.slice(2)];
|
|
933
|
+
}
|
|
934
|
+
else if (s[0].prim === 'timestamp' && s[1].prim === 'int') {
|
|
935
|
+
return [annotateVar({ prim: 'timestamp' }), ...stack.slice(2)];
|
|
936
|
+
}
|
|
937
|
+
else if (s[0].prim === 'mutez' && s[1].prim === 'mutez') {
|
|
938
|
+
return [annotateVar({ prim: 'mutez' }), ...stack.slice(2)];
|
|
939
|
+
}
|
|
940
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: can't subtract ${s[0].prim} from ${s[1].prim}`);
|
|
941
|
+
}
|
|
942
|
+
case 'SUB_MUTEZ': {
|
|
943
|
+
const _s = args(0, ['mutez'], ['mutez']);
|
|
944
|
+
return [annotateVar({ prim: 'option', args: [{ prim: 'mutez' }] }), ...stack.slice(2)];
|
|
945
|
+
}
|
|
946
|
+
case 'MUL': {
|
|
947
|
+
const s = args(0, ['nat', 'int', 'mutez', 'bls12_381_g1', 'bls12_381_g2', 'bls12_381_fr'], ['nat', 'int', 'mutez', 'bls12_381_g1', 'bls12_381_g2', 'bls12_381_fr']);
|
|
948
|
+
if ((s[0].prim === 'nat' && s[1].prim === 'int') ||
|
|
949
|
+
(s[0].prim === 'int' && s[1].prim === 'nat')) {
|
|
950
|
+
return [annotateVar({ prim: 'int' }), ...stack.slice(2)];
|
|
951
|
+
}
|
|
952
|
+
else if ((s[0].prim === 'nat' && s[1].prim === 'mutez') ||
|
|
953
|
+
(s[0].prim === 'mutez' && s[1].prim === 'nat')) {
|
|
954
|
+
return [annotateVar({ prim: 'mutez' }), ...stack.slice(2)];
|
|
955
|
+
}
|
|
956
|
+
else if (((s[0].prim === 'bls12_381_g1' ||
|
|
957
|
+
s[0].prim === 'bls12_381_g2' ||
|
|
958
|
+
s[0].prim === 'bls12_381_fr') &&
|
|
959
|
+
s[1].prim === 'bls12_381_fr') ||
|
|
960
|
+
((s[0].prim === 'nat' || s[0].prim === 'int') && s[0].prim === s[1].prim)) {
|
|
961
|
+
return [annotateVar(s[0]), ...stack.slice(2)];
|
|
962
|
+
}
|
|
963
|
+
else if (((s[0].prim === 'nat' || s[0].prim === 'int') && s[1].prim === 'bls12_381_fr') ||
|
|
964
|
+
((s[1].prim === 'nat' || s[1].prim === 'int') && s[0].prim === 'bls12_381_fr')) {
|
|
965
|
+
return [annotateVar({ prim: 'bls12_381_fr' }), ...stack.slice(2)];
|
|
966
|
+
}
|
|
967
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: can't multiply ${s[0].prim} by ${s[1].prim}`);
|
|
968
|
+
}
|
|
969
|
+
case 'EDIV': {
|
|
970
|
+
const res = (a, b) => ({
|
|
971
|
+
prim: 'option',
|
|
972
|
+
args: [{ prim: 'pair', args: [{ prim: a }, { prim: b }] }],
|
|
973
|
+
});
|
|
974
|
+
const s = args(0, ['nat', 'int', 'mutez'], ['nat', 'int', 'mutez']);
|
|
975
|
+
if (s[0].prim === 'nat' && s[1].prim === 'nat') {
|
|
976
|
+
return [annotateVar(res('nat', 'nat')), ...stack.slice(2)];
|
|
977
|
+
}
|
|
978
|
+
else if ((s[0].prim === 'nat' || s[0].prim === 'int') &&
|
|
979
|
+
(s[1].prim === 'nat' || s[1].prim === 'int')) {
|
|
980
|
+
return [annotateVar(res('int', 'nat')), ...stack.slice(2)];
|
|
981
|
+
}
|
|
982
|
+
else if (s[0].prim === 'mutez' && s[1].prim === 'nat') {
|
|
983
|
+
return [annotateVar(res('mutez', 'mutez')), ...stack.slice(2)];
|
|
984
|
+
}
|
|
985
|
+
else if (s[0].prim === 'mutez' && s[1].prim === 'mutez') {
|
|
986
|
+
return [annotateVar(res('nat', 'mutez')), ...stack.slice(2)];
|
|
987
|
+
}
|
|
988
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: can't euclideally divide ${s[0].prim} by ${s[1].prim}`);
|
|
989
|
+
}
|
|
990
|
+
case 'ABS':
|
|
991
|
+
args(0, ['int']);
|
|
992
|
+
return [annotateVar({ prim: 'nat' }), ...stack.slice(1)];
|
|
993
|
+
case 'ISNAT':
|
|
994
|
+
args(0, ['int']);
|
|
995
|
+
return [annotateVar({ prim: 'option', args: [{ prim: 'nat' }] }), ...stack.slice(1)];
|
|
996
|
+
case 'INT':
|
|
997
|
+
args(0, ['nat', 'bls12_381_fr', 'bytes']);
|
|
998
|
+
return [annotateVar({ prim: 'int' }), ...stack.slice(1)];
|
|
999
|
+
case 'BYTES':
|
|
1000
|
+
args(0, ['nat', 'int']);
|
|
1001
|
+
return [annotateVar({ prim: 'bytes' }), ...stack.slice(1)];
|
|
1002
|
+
case 'NAT':
|
|
1003
|
+
args(0, ['bytes']);
|
|
1004
|
+
return [annotateVar({ prim: 'nat' }), ...stack.slice(1)];
|
|
1005
|
+
case 'NEG': {
|
|
1006
|
+
const s = args(0, ['nat', 'int', 'bls12_381_g1', 'bls12_381_g2', 'bls12_381_fr'])[0];
|
|
1007
|
+
if (s.prim === 'nat' || s.prim === 'int') {
|
|
1008
|
+
return [annotateVar({ prim: 'int' }), ...stack.slice(1)];
|
|
1009
|
+
}
|
|
1010
|
+
return [annotateVar(s), ...stack.slice(1)];
|
|
1011
|
+
}
|
|
1012
|
+
case 'LSL':
|
|
1013
|
+
case 'LSR':
|
|
1014
|
+
args(0, ['nat', 'bytes'], ['nat', 'bytes']);
|
|
1015
|
+
return [annotateVar({ prim: 'nat' }), ...stack.slice(2)];
|
|
1016
|
+
case 'OR':
|
|
1017
|
+
case 'XOR': {
|
|
1018
|
+
const s = args(0, ['nat', 'bytes', 'bool'], ['nat', 'bytes', 'bool']);
|
|
1019
|
+
if (s[0].prim !== s[1].prim) {
|
|
1020
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: both arguments must be of the same type: ${s[0].prim}, ${s[1].prim}`);
|
|
1021
|
+
}
|
|
1022
|
+
return [annotateVar(s[1]), ...stack.slice(2)];
|
|
1023
|
+
}
|
|
1024
|
+
case 'AND': {
|
|
1025
|
+
const s = args(0, ['nat', 'bytes', 'bool', 'int'], ['nat', 'bytes', 'bool']);
|
|
1026
|
+
if ((s[0].prim !== 'int' || s[1].prim !== 'nat') && s[0].prim !== s[1].prim) {
|
|
1027
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: both arguments must be of the same type: ${s[0].prim}, ${s[1].prim}`);
|
|
1028
|
+
}
|
|
1029
|
+
return [annotateVar(s[1]), ...stack.slice(2)];
|
|
1030
|
+
}
|
|
1031
|
+
case 'NOT': {
|
|
1032
|
+
const s = args(0, ['nat', 'bytes', 'bool', 'int'])[0];
|
|
1033
|
+
if (s.prim === 'bool') {
|
|
1034
|
+
return [annotateVar({ prim: 'bool' }), ...stack.slice(1)];
|
|
1035
|
+
}
|
|
1036
|
+
return [annotateVar({ prim: 'int' }), ...stack.slice(1)];
|
|
1037
|
+
}
|
|
1038
|
+
case 'COMPARE': {
|
|
1039
|
+
const s = args(0, null, null);
|
|
1040
|
+
ensureComparableType(s[0]);
|
|
1041
|
+
ensureComparableType(s[1]);
|
|
1042
|
+
return [annotateVar({ prim: 'int' }), ...stack.slice(2)];
|
|
1043
|
+
}
|
|
1044
|
+
case 'EQ':
|
|
1045
|
+
case 'NEQ':
|
|
1046
|
+
case 'LT':
|
|
1047
|
+
case 'GT':
|
|
1048
|
+
case 'LE':
|
|
1049
|
+
case 'GE':
|
|
1050
|
+
args(0, ['int']);
|
|
1051
|
+
return [annotateVar({ prim: 'bool' }), ...stack.slice(1)];
|
|
1052
|
+
case 'SELF': {
|
|
1053
|
+
if ((ctx === null || ctx === void 0 ? void 0 : ctx.contract) === undefined) {
|
|
1054
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: contract required`);
|
|
1055
|
+
}
|
|
1056
|
+
const ia = instructionAnn({ f: 1, v: 1 });
|
|
1057
|
+
const ep = contractEntryPoint(ctx.contract, (_b = ia.f) === null || _b === void 0 ? void 0 : _b[0]);
|
|
1058
|
+
if (ep === null) {
|
|
1059
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: contract has no entrypoint ${ep}`);
|
|
1060
|
+
}
|
|
1061
|
+
return [
|
|
1062
|
+
annotate({ prim: 'contract', args: [ep] }, { v: ia.v ? ia.v : ['@self'] }),
|
|
1063
|
+
...stack,
|
|
1064
|
+
];
|
|
1065
|
+
}
|
|
1066
|
+
case 'TRANSFER_TOKENS': {
|
|
1067
|
+
const s = args(0, null, ['mutez'], ['contract']);
|
|
1068
|
+
ensureTypesEqual(s[0], s[2].args[0]);
|
|
1069
|
+
return [annotateVar({ prim: 'operation' }), ...stack.slice(3)];
|
|
1070
|
+
}
|
|
1071
|
+
case 'SET_DELEGATE': {
|
|
1072
|
+
const s = args(0, ['option'])[0];
|
|
1073
|
+
if (typeID(s.args[0]) !== 'key_hash') {
|
|
1074
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: key hash expected: ${typeID(s.args[0])}`);
|
|
1075
|
+
}
|
|
1076
|
+
return [annotateVar({ prim: 'operation' }), ...stack.slice(1)];
|
|
1077
|
+
}
|
|
1078
|
+
case 'IMPLICIT_ACCOUNT':
|
|
1079
|
+
args(0, ['key_hash']);
|
|
1080
|
+
return [annotateVar({ prim: 'contract', args: [{ prim: 'unit' }] }), ...stack.slice(1)];
|
|
1081
|
+
case 'NOW':
|
|
1082
|
+
return [annotateVar({ prim: 'timestamp' }, '@now'), ...stack];
|
|
1083
|
+
case 'AMOUNT':
|
|
1084
|
+
return [annotateVar({ prim: 'mutez' }, '@amount'), ...stack];
|
|
1085
|
+
case 'BALANCE':
|
|
1086
|
+
return [annotateVar({ prim: 'mutez' }, '@balance'), ...stack];
|
|
1087
|
+
case 'CHECK_SIGNATURE':
|
|
1088
|
+
args(0, ['key'], ['signature'], ['bytes']);
|
|
1089
|
+
return [annotateVar({ prim: 'bool' }), ...stack.slice(3)];
|
|
1090
|
+
case 'BLAKE2B':
|
|
1091
|
+
case 'SHA256':
|
|
1092
|
+
case 'SHA512':
|
|
1093
|
+
case 'KECCAK':
|
|
1094
|
+
case 'SHA3':
|
|
1095
|
+
args(0, ['bytes']);
|
|
1096
|
+
return [annotateVar({ prim: 'bytes' }), ...stack.slice(1)];
|
|
1097
|
+
case 'HASH_KEY':
|
|
1098
|
+
args(0, ['key']);
|
|
1099
|
+
return [annotateVar({ prim: 'key_hash' }), ...stack.slice(1)];
|
|
1100
|
+
case 'SOURCE':
|
|
1101
|
+
return [annotateVar({ prim: 'address' }, '@source'), ...stack];
|
|
1102
|
+
case 'SENDER':
|
|
1103
|
+
return [annotateVar({ prim: 'address' }, '@sender'), ...stack];
|
|
1104
|
+
case 'ADDRESS': {
|
|
1105
|
+
const s = args(0, ['contract'])[0];
|
|
1106
|
+
const ia = instructionAnn({ v: 1 });
|
|
1107
|
+
return [
|
|
1108
|
+
annotate({ prim: 'address', [michelson_types_1.refContract]: s }, { v: ia.v ? ia.v : varSuffix(argAnn(s), 'address') }),
|
|
1109
|
+
...stack.slice(1),
|
|
1110
|
+
];
|
|
1111
|
+
}
|
|
1112
|
+
case 'SELF_ADDRESS': {
|
|
1113
|
+
const addr = { prim: 'address' };
|
|
1114
|
+
if ((ctx === null || ctx === void 0 ? void 0 : ctx.contract) !== undefined) {
|
|
1115
|
+
addr[michelson_types_1.refContract] = {
|
|
1116
|
+
prim: 'contract',
|
|
1117
|
+
args: [contractSection(ctx.contract, 'parameter').args[0]],
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
return [annotateVar(addr, '@address'), ...stack];
|
|
1121
|
+
}
|
|
1122
|
+
case 'CHAIN_ID':
|
|
1123
|
+
return [annotateVar({ prim: 'chain_id' }), ...stack];
|
|
1124
|
+
case 'DROP': {
|
|
1125
|
+
instructionAnn({});
|
|
1126
|
+
const n = instruction.args !== undefined ? parseInt(instruction.args[0].int, 10) : 1;
|
|
1127
|
+
args(n - 1, null);
|
|
1128
|
+
return stack.slice(n);
|
|
1129
|
+
}
|
|
1130
|
+
case 'DIG': {
|
|
1131
|
+
instructionAnn({});
|
|
1132
|
+
const n = parseInt(instruction.args[0].int, 10);
|
|
1133
|
+
return [args(n, null)[0], ...stack.slice(0, n), ...stack.slice(n + 1)];
|
|
1134
|
+
}
|
|
1135
|
+
case 'DUG': {
|
|
1136
|
+
instructionAnn({});
|
|
1137
|
+
const n = parseInt(instruction.args[0].int, 10);
|
|
1138
|
+
return [...stack.slice(1, n + 1), args(0, null)[0], ...stack.slice(n + 1)];
|
|
1139
|
+
}
|
|
1140
|
+
case 'NONE':
|
|
1141
|
+
assertTypeAnnotationsValid(instruction.args[0]);
|
|
1142
|
+
return [
|
|
1143
|
+
annotate({ prim: 'option', args: [instruction.args[0]] }, instructionAnn({ t: 1, v: 1 })),
|
|
1144
|
+
...stack,
|
|
1145
|
+
];
|
|
1146
|
+
case 'LEFT':
|
|
1147
|
+
case 'RIGHT': {
|
|
1148
|
+
const s = args(0, null)[0];
|
|
1149
|
+
const ia = instructionAnn({ f: 2, t: 1, v: 1 }, { specialFields: true });
|
|
1150
|
+
const va = argAnn(s);
|
|
1151
|
+
const children = [
|
|
1152
|
+
annotate(s, {
|
|
1153
|
+
t: null,
|
|
1154
|
+
v: null,
|
|
1155
|
+
f: ia.f && ia.f.length > 0 && ia.f[0] !== '%'
|
|
1156
|
+
? ia.f[0] === '%@'
|
|
1157
|
+
? va.v
|
|
1158
|
+
? ['%' + va.v[0].slice(1)]
|
|
1159
|
+
: undefined
|
|
1160
|
+
: ia.f
|
|
1161
|
+
: undefined,
|
|
1162
|
+
}),
|
|
1163
|
+
annotate(instruction.args[0], {
|
|
1164
|
+
t: null,
|
|
1165
|
+
f: ia.f && ia.f.length > 1 && ia.f[1] !== '%' ? ia.f : undefined,
|
|
1166
|
+
}),
|
|
1167
|
+
];
|
|
1168
|
+
return [
|
|
1169
|
+
annotate({
|
|
1170
|
+
prim: 'or',
|
|
1171
|
+
args: instruction.prim === 'LEFT' ? children : [children[1], children[0]],
|
|
1172
|
+
}, { t: ia.t, v: ia.v }),
|
|
1173
|
+
...stack.slice(1),
|
|
1174
|
+
];
|
|
1175
|
+
}
|
|
1176
|
+
case 'NIL':
|
|
1177
|
+
assertTypeAnnotationsValid(instruction.args[0]);
|
|
1178
|
+
return [
|
|
1179
|
+
annotate({ prim: 'list', args: [instruction.args[0]] }, instructionAnn({ t: 1, v: 1 })),
|
|
1180
|
+
...stack,
|
|
1181
|
+
];
|
|
1182
|
+
case 'UNPACK':
|
|
1183
|
+
args(0, ['bytes']);
|
|
1184
|
+
assertTypeAnnotationsValid(instruction.args[0]);
|
|
1185
|
+
return [
|
|
1186
|
+
annotateVar({ prim: 'option', args: [instruction.args[0]] }, '@unpacked'),
|
|
1187
|
+
...stack.slice(1),
|
|
1188
|
+
];
|
|
1189
|
+
case 'CONTRACT': {
|
|
1190
|
+
const s = args(0, ['address'])[0];
|
|
1191
|
+
assertTypeAnnotationsValid(instruction.args[0]);
|
|
1192
|
+
const ia = instructionAnn({ v: 1, f: 1 });
|
|
1193
|
+
const contract = s[michelson_types_1.refContract];
|
|
1194
|
+
if (contract !== undefined) {
|
|
1195
|
+
const ep = contractEntryPoint(contract, (_c = ia.f) === null || _c === void 0 ? void 0 : _c[0]);
|
|
1196
|
+
if (ep === null) {
|
|
1197
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: contract has no entrypoint ${ep}`);
|
|
1198
|
+
}
|
|
1199
|
+
ensureTypesEqual(ep, instruction.args[0]);
|
|
1200
|
+
}
|
|
1201
|
+
return [
|
|
1202
|
+
annotate({ prim: 'option', args: [{ prim: 'contract', args: [instruction.args[0]] }] }, { v: ia.v ? ia.v : varSuffix(argAnn(s), 'contract') }),
|
|
1203
|
+
...stack.slice(1),
|
|
1204
|
+
];
|
|
1205
|
+
}
|
|
1206
|
+
case 'CAST': {
|
|
1207
|
+
instructionAnn({});
|
|
1208
|
+
const s = args(0, null)[0];
|
|
1209
|
+
assertTypeAnnotationsValid(instruction.args[0]);
|
|
1210
|
+
ensureTypesEqual(instruction.args[0], s);
|
|
1211
|
+
return [instruction.args[0], ...stack.slice(1)];
|
|
1212
|
+
}
|
|
1213
|
+
case 'IF_NONE': {
|
|
1214
|
+
instructionAnn({});
|
|
1215
|
+
const s = args(0, ['option'])[0];
|
|
1216
|
+
const tail = stack.slice(1);
|
|
1217
|
+
const br0 = functionTypeInternal(instruction.args[0], tail, ctx);
|
|
1218
|
+
const br1 = functionTypeInternal(instruction.args[1], [annotate(s.args[0], { t: null, v: varSuffix(argAnn(s), 'some') }), ...tail], ctx);
|
|
1219
|
+
return branchType(br0, br1);
|
|
1220
|
+
}
|
|
1221
|
+
case 'IF_LEFT': {
|
|
1222
|
+
instructionAnn({});
|
|
1223
|
+
const s = args(0, ['or'])[0];
|
|
1224
|
+
const va = argAnn(s);
|
|
1225
|
+
const lefta = argAnn(s.args[0]);
|
|
1226
|
+
const righta = argAnn(s.args[1]);
|
|
1227
|
+
const tail = stack.slice(1);
|
|
1228
|
+
const br0 = functionTypeInternal(instruction.args[0], [
|
|
1229
|
+
annotate(s.args[0], {
|
|
1230
|
+
t: null,
|
|
1231
|
+
v: varSuffix(va, lefta.f ? lefta.f[0].slice(1) : 'left'),
|
|
1232
|
+
}),
|
|
1233
|
+
...tail,
|
|
1234
|
+
], ctx);
|
|
1235
|
+
const br1 = functionTypeInternal(instruction.args[1], [
|
|
1236
|
+
annotate(s.args[1], {
|
|
1237
|
+
t: null,
|
|
1238
|
+
v: varSuffix(va, righta.f ? righta.f[0].slice(1) : 'right'),
|
|
1239
|
+
}),
|
|
1240
|
+
...tail,
|
|
1241
|
+
], ctx);
|
|
1242
|
+
return branchType(br0, br1);
|
|
1243
|
+
}
|
|
1244
|
+
case 'IF_CONS': {
|
|
1245
|
+
instructionAnn({});
|
|
1246
|
+
const s = args(0, ['list'])[0];
|
|
1247
|
+
const va = argAnn(s);
|
|
1248
|
+
const tail = stack.slice(1);
|
|
1249
|
+
const br0 = functionTypeInternal(instruction.args[0], [
|
|
1250
|
+
annotate(s.args[0], { t: null, v: varSuffix(va, 'hd') }),
|
|
1251
|
+
annotate(s, { t: null, v: varSuffix(va, 'tl') }),
|
|
1252
|
+
...tail,
|
|
1253
|
+
], ctx);
|
|
1254
|
+
const br1 = functionTypeInternal(instruction.args[1], tail, ctx);
|
|
1255
|
+
return branchType(br0, br1);
|
|
1256
|
+
}
|
|
1257
|
+
case 'IF': {
|
|
1258
|
+
instructionAnn({});
|
|
1259
|
+
args(0, ['bool']);
|
|
1260
|
+
const tail = stack.slice(1);
|
|
1261
|
+
const br0 = functionTypeInternal(instruction.args[0], tail, ctx);
|
|
1262
|
+
const br1 = functionTypeInternal(instruction.args[1], tail, ctx);
|
|
1263
|
+
return branchType(br0, br1);
|
|
1264
|
+
}
|
|
1265
|
+
case 'MAP': {
|
|
1266
|
+
const s = args(0, ['list', 'map', 'option'])[0];
|
|
1267
|
+
const tail = stack.slice(1);
|
|
1268
|
+
const elt = s.prim === 'map' ? { prim: 'pair', args: s.args } : s.args[0];
|
|
1269
|
+
const body = functionTypeInternal(instruction.args[0], [annotate(elt, { t: null, v: varSuffix(argAnn(s), 'elt') }), ...tail], ctx);
|
|
1270
|
+
if ('failed' in body) {
|
|
1271
|
+
if (!('prim' in body.failed) || body.failed.prim !== 'never') {
|
|
1272
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: FAIL is not allowed in MAP`);
|
|
1273
|
+
}
|
|
1274
|
+
return { failed: body.failed, level: body.level + 1 };
|
|
1275
|
+
}
|
|
1276
|
+
if (body.length < 1) {
|
|
1277
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: function must return a value`);
|
|
1278
|
+
}
|
|
1279
|
+
ensureStacksEqual(body.slice(1), tail);
|
|
1280
|
+
return s.prim === 'list'
|
|
1281
|
+
? [annotateVar({ prim: 'list', args: [body[0]] }), ...tail]
|
|
1282
|
+
: s.prim === 'map'
|
|
1283
|
+
? [annotateVar({ prim: 'map', args: [s.args[0], body[0]] }), ...tail]
|
|
1284
|
+
: [annotateVar({ prim: 'option', args: [body[0]] }), ...tail];
|
|
1285
|
+
}
|
|
1286
|
+
case 'ITER': {
|
|
1287
|
+
instructionAnn({});
|
|
1288
|
+
const s = args(0, ['set', 'list', 'map'])[0];
|
|
1289
|
+
const tail = stack.slice(1);
|
|
1290
|
+
const elt = s.prim === 'map' ? { prim: 'pair', args: s.args } : s.args[0];
|
|
1291
|
+
const body = functionTypeInternal(instruction.args[0], [annotate(elt, { t: null, v: varSuffix(argAnn(s), 'elt') }), ...tail], ctx);
|
|
1292
|
+
if ('failed' in body) {
|
|
1293
|
+
return { failed: body.failed, level: body.level + 1 };
|
|
1294
|
+
}
|
|
1295
|
+
ensureStacksEqual(body, tail);
|
|
1296
|
+
return tail;
|
|
1297
|
+
}
|
|
1298
|
+
case 'LOOP': {
|
|
1299
|
+
instructionAnn({});
|
|
1300
|
+
args(0, ['bool']);
|
|
1301
|
+
const tail = stack.slice(1);
|
|
1302
|
+
const body = functionTypeInternal(instruction.args[0], tail, ctx);
|
|
1303
|
+
if ('failed' in body) {
|
|
1304
|
+
return { failed: body.failed, level: body.level + 1 };
|
|
1305
|
+
}
|
|
1306
|
+
ensureStacksEqual(body, [{ prim: 'bool' }, ...tail]);
|
|
1307
|
+
return tail;
|
|
1308
|
+
}
|
|
1309
|
+
case 'LOOP_LEFT': {
|
|
1310
|
+
instructionAnn({});
|
|
1311
|
+
const s = args(0, ['or'])[0];
|
|
1312
|
+
const tail = stack.slice(1);
|
|
1313
|
+
const body = functionTypeInternal(instruction.args[0], [annotate(s.args[0], { t: null, v: varSuffix(argAnn(s), 'left') }), ...tail], ctx);
|
|
1314
|
+
if ('failed' in body) {
|
|
1315
|
+
return { failed: body.failed, level: body.level + 1 };
|
|
1316
|
+
}
|
|
1317
|
+
ensureStacksEqual(body, [s, ...tail]);
|
|
1318
|
+
return [annotate(s.args[1], { t: null, v: instructionAnn({ v: 1 }).v }), ...tail];
|
|
1319
|
+
}
|
|
1320
|
+
case 'DIP': {
|
|
1321
|
+
instructionAnn({});
|
|
1322
|
+
const n = instruction.args.length === 2 ? parseInt(instruction.args[0].int, 10) : 1;
|
|
1323
|
+
args(n - 1, null);
|
|
1324
|
+
const head = stack.slice(0, n);
|
|
1325
|
+
const tail = stack.slice(n);
|
|
1326
|
+
// ternary operator is a type guard so use it instead of just `instruction.args.length - 1`
|
|
1327
|
+
const body = instruction.args.length === 2
|
|
1328
|
+
? functionTypeInternal(instruction.args[1], tail, ctx)
|
|
1329
|
+
: functionTypeInternal(instruction.args[0], tail, ctx);
|
|
1330
|
+
if ('failed' in body) {
|
|
1331
|
+
return { failed: body.failed, level: body.level + 1 };
|
|
1332
|
+
}
|
|
1333
|
+
return [...head, ...body];
|
|
1334
|
+
}
|
|
1335
|
+
case 'CREATE_CONTRACT': {
|
|
1336
|
+
const ia = instructionAnn({ v: 2 });
|
|
1337
|
+
const s = args(0, ['option'], ['mutez'], null);
|
|
1338
|
+
if (typeID(s[0].args[0]) !== 'key_hash') {
|
|
1339
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: key hash expected: ${typeID(s[0].args[0])}`);
|
|
1340
|
+
}
|
|
1341
|
+
if (ensureStorableType(s[2])) {
|
|
1342
|
+
assertContractValid(instruction.args[0]);
|
|
1343
|
+
assertScalarTypesEqual(contractSection(instruction.args[0], 'storage').args[0], s[2]);
|
|
1344
|
+
}
|
|
1345
|
+
const va = (_d = ia.v) === null || _d === void 0 ? void 0 : _d.map((v) => (v !== '@' ? [v] : undefined));
|
|
1346
|
+
return [
|
|
1347
|
+
annotate({ prim: 'operation' }, { v: va === null || va === void 0 ? void 0 : va[0] }),
|
|
1348
|
+
annotate({
|
|
1349
|
+
prim: 'address',
|
|
1350
|
+
[michelson_types_1.refContract]: {
|
|
1351
|
+
prim: 'contract',
|
|
1352
|
+
args: [contractSection(instruction.args[0], 'parameter').args[0]],
|
|
1353
|
+
},
|
|
1354
|
+
}, { v: va === null || va === void 0 ? void 0 : va[1] }),
|
|
1355
|
+
...stack.slice(3),
|
|
1356
|
+
];
|
|
1357
|
+
}
|
|
1358
|
+
case 'PUSH':
|
|
1359
|
+
assertTypeAnnotationsValid(instruction.args[0]);
|
|
1360
|
+
assertDataValidInternal(instruction.args[1], instruction.args[0], Object.assign(Object.assign({}, ctx), { contract: undefined }));
|
|
1361
|
+
return [annotateVar(instruction.args[0]), ...stack];
|
|
1362
|
+
case 'EMPTY_SET':
|
|
1363
|
+
assertTypeAnnotationsValid(instruction.args[0]);
|
|
1364
|
+
ensureComparableType(instruction.args[0]);
|
|
1365
|
+
return [
|
|
1366
|
+
annotate({ prim: 'set', args: instruction.args }, instructionAnn({ t: 1, v: 1 })),
|
|
1367
|
+
...stack,
|
|
1368
|
+
];
|
|
1369
|
+
case 'EMPTY_MAP':
|
|
1370
|
+
assertTypeAnnotationsValid(instruction.args[0]);
|
|
1371
|
+
ensureComparableType(instruction.args[0]);
|
|
1372
|
+
assertTypeAnnotationsValid(instruction.args[1]);
|
|
1373
|
+
return [
|
|
1374
|
+
annotate({ prim: 'map', args: instruction.args }, instructionAnn({ t: 1, v: 1 })),
|
|
1375
|
+
...stack,
|
|
1376
|
+
];
|
|
1377
|
+
case 'EMPTY_BIG_MAP':
|
|
1378
|
+
assertTypeAnnotationsValid(instruction.args[0]);
|
|
1379
|
+
ensureComparableType(instruction.args[0]);
|
|
1380
|
+
assertTypeAnnotationsValid(instruction.args[1]);
|
|
1381
|
+
ensureBigMapStorableType(instruction.args[0]);
|
|
1382
|
+
return [
|
|
1383
|
+
annotate({ prim: 'big_map', args: instruction.args }, instructionAnn({ t: 1, v: 1 })),
|
|
1384
|
+
...stack,
|
|
1385
|
+
];
|
|
1386
|
+
case 'LAMBDA_REC':
|
|
1387
|
+
case 'LAMBDA': {
|
|
1388
|
+
assertTypeAnnotationsValid(instruction.args[0]);
|
|
1389
|
+
assertTypeAnnotationsValid(instruction.args[1]);
|
|
1390
|
+
const s = [instruction.args[0]];
|
|
1391
|
+
if (instruction.prim === 'LAMBDA_REC') {
|
|
1392
|
+
s.push({ prim: 'lambda', args: [instruction.args[0], instruction.args[1]] });
|
|
1393
|
+
}
|
|
1394
|
+
const body = functionTypeInternal(instruction.args[2], s, Object.assign(Object.assign({}, ctx), { contract: undefined }));
|
|
1395
|
+
if ('failed' in body) {
|
|
1396
|
+
return { failed: body.failed, level: body.level + 1 };
|
|
1397
|
+
}
|
|
1398
|
+
if (body.length !== 1) {
|
|
1399
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: function must return a value`);
|
|
1400
|
+
}
|
|
1401
|
+
ensureTypesEqual(instruction.args[1], body[0]);
|
|
1402
|
+
return [
|
|
1403
|
+
annotateVar({ prim: 'lambda', args: [instruction.args[0], instruction.args[1]] }),
|
|
1404
|
+
...stack,
|
|
1405
|
+
];
|
|
1406
|
+
}
|
|
1407
|
+
case 'LEVEL':
|
|
1408
|
+
return [annotateVar({ prim: 'nat' }, '@level'), ...stack];
|
|
1409
|
+
case 'TOTAL_VOTING_POWER':
|
|
1410
|
+
return [annotateVar({ prim: 'nat' }), ...stack];
|
|
1411
|
+
case 'VOTING_POWER':
|
|
1412
|
+
args(0, ['key_hash']);
|
|
1413
|
+
return [annotateVar({ prim: 'nat' }), ...stack.slice(1)];
|
|
1414
|
+
case 'TICKET': {
|
|
1415
|
+
const s = args(0, null, ['nat'])[0];
|
|
1416
|
+
ensureComparableType(s);
|
|
1417
|
+
if ((0, michelson_types_1.ProtoInferiorTo)(proto, michelson_types_1.Protocol.PtLimaPtL)) {
|
|
1418
|
+
return [
|
|
1419
|
+
annotate({ prim: 'ticket', args: [s] }, instructionAnn({ t: 1, v: 1 })),
|
|
1420
|
+
...stack.slice(2),
|
|
1421
|
+
];
|
|
1422
|
+
}
|
|
1423
|
+
else {
|
|
1424
|
+
return [
|
|
1425
|
+
annotateVar({
|
|
1426
|
+
prim: 'option',
|
|
1427
|
+
args: [annotate({ prim: 'ticket', args: [s] }, instructionAnn({ t: 1, v: 1 }))],
|
|
1428
|
+
}),
|
|
1429
|
+
...stack.slice(2),
|
|
1430
|
+
];
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
case 'JOIN_TICKETS': {
|
|
1434
|
+
const s = (0, utils_1.unpackComb)('pair', args(0, ['pair'])[0]);
|
|
1435
|
+
if (typeID(s.args[0]) !== 'ticket') {
|
|
1436
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: ticket expected: ${typeID(s.args[0])}`);
|
|
1437
|
+
}
|
|
1438
|
+
ensureTypesEqual(s.args[0], s.args[1]);
|
|
1439
|
+
return [
|
|
1440
|
+
annotateVar({
|
|
1441
|
+
prim: 'option',
|
|
1442
|
+
args: [annotate(s.args[0], { t: null })],
|
|
1443
|
+
}),
|
|
1444
|
+
...stack.slice(1),
|
|
1445
|
+
];
|
|
1446
|
+
}
|
|
1447
|
+
case 'SPLIT_TICKET': {
|
|
1448
|
+
const s = args(0, ['ticket'], ['pair']);
|
|
1449
|
+
const p = (0, utils_1.unpackComb)('pair', s[1]);
|
|
1450
|
+
if (typeID(p.args[0]) !== 'nat') {
|
|
1451
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: nat expected: ${typeID(p.args[0])}`);
|
|
1452
|
+
}
|
|
1453
|
+
ensureTypesEqual(p.args[0], p.args[1]);
|
|
1454
|
+
return [
|
|
1455
|
+
annotateVar({
|
|
1456
|
+
prim: 'option',
|
|
1457
|
+
args: [
|
|
1458
|
+
{
|
|
1459
|
+
prim: 'pair',
|
|
1460
|
+
args: [annotate(s[0], { t: null }), annotate(s[0], { t: null })],
|
|
1461
|
+
},
|
|
1462
|
+
],
|
|
1463
|
+
}),
|
|
1464
|
+
...stack.slice(2),
|
|
1465
|
+
];
|
|
1466
|
+
}
|
|
1467
|
+
case 'READ_TICKET': {
|
|
1468
|
+
const ia = instructionAnn({ v: 2 });
|
|
1469
|
+
const s = args(0, ['ticket'])[0];
|
|
1470
|
+
const va = (_e = ia.v) === null || _e === void 0 ? void 0 : _e.map((v) => (v !== '@' ? [v] : undefined));
|
|
1471
|
+
return [
|
|
1472
|
+
annotate({
|
|
1473
|
+
prim: 'pair',
|
|
1474
|
+
args: [{ prim: 'address' }, annotate(s.args[0], { t: null }), { prim: 'nat' }],
|
|
1475
|
+
}, { v: va === null || va === void 0 ? void 0 : va[0] }),
|
|
1476
|
+
annotate(s, { v: va === null || va === void 0 ? void 0 : va[1], t: null }),
|
|
1477
|
+
...stack.slice(1),
|
|
1478
|
+
];
|
|
1479
|
+
}
|
|
1480
|
+
case 'PAIRING_CHECK': {
|
|
1481
|
+
const p = args(0, ['list'])[0].args[0];
|
|
1482
|
+
if (!(0, utils_1.isPairType)(p)) {
|
|
1483
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: pair expected: ${typeID(p)}`);
|
|
1484
|
+
}
|
|
1485
|
+
const c = (0, utils_1.unpackComb)('pair', p);
|
|
1486
|
+
if (typeID(c.args[0]) !== 'bls12_381_g1') {
|
|
1487
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: bls12_381_g1 expected: ${typeID(c.args[0])}`);
|
|
1488
|
+
}
|
|
1489
|
+
if (typeID(c.args[1]) !== 'bls12_381_g2') {
|
|
1490
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: bls12_381_g2 expected: ${typeID(c.args[1])}`);
|
|
1491
|
+
}
|
|
1492
|
+
return [annotateVar({ prim: 'bool' }), ...stack.slice(1)];
|
|
1493
|
+
}
|
|
1494
|
+
case 'SAPLING_EMPTY_STATE':
|
|
1495
|
+
return [
|
|
1496
|
+
annotate({ prim: 'sapling_state', args: [instruction.args[0]] }, instructionAnn({ v: 1, t: 1 })),
|
|
1497
|
+
...stack,
|
|
1498
|
+
];
|
|
1499
|
+
case 'SAPLING_VERIFY_UPDATE': {
|
|
1500
|
+
const s = args(0, ['sapling_transaction'], ['sapling_state']);
|
|
1501
|
+
if (parseInt(s[0].args[0].int, 10) !== parseInt(s[1].args[0].int, 10)) {
|
|
1502
|
+
throw new MichelsonInstructionError(instruction, stack, `${instruction.prim}: sapling memo size mismatch: ${s[0].args[0].int} != ${s[1].args[0].int}`);
|
|
1503
|
+
}
|
|
1504
|
+
return (0, michelson_types_1.ProtoInferiorTo)(proto, michelson_types_1.Protocol.PtJakarta)
|
|
1505
|
+
? [
|
|
1506
|
+
annotateVar({
|
|
1507
|
+
prim: 'option',
|
|
1508
|
+
args: [
|
|
1509
|
+
{
|
|
1510
|
+
prim: 'pair',
|
|
1511
|
+
args: [{ prim: 'int' }, annotate(s[1], { t: null })],
|
|
1512
|
+
},
|
|
1513
|
+
],
|
|
1514
|
+
}),
|
|
1515
|
+
...stack.slice(2),
|
|
1516
|
+
]
|
|
1517
|
+
: [
|
|
1518
|
+
annotateVar({
|
|
1519
|
+
prim: 'option',
|
|
1520
|
+
args: [
|
|
1521
|
+
{
|
|
1522
|
+
prim: 'pair',
|
|
1523
|
+
args: [
|
|
1524
|
+
{ prim: 'bytes' },
|
|
1525
|
+
{
|
|
1526
|
+
prim: 'pair',
|
|
1527
|
+
args: [{ prim: 'int' }, annotate(s[1], { t: null })],
|
|
1528
|
+
},
|
|
1529
|
+
],
|
|
1530
|
+
},
|
|
1531
|
+
],
|
|
1532
|
+
}),
|
|
1533
|
+
...stack.slice(2),
|
|
1534
|
+
];
|
|
1535
|
+
}
|
|
1536
|
+
case 'OPEN_CHEST':
|
|
1537
|
+
args(0, ['chest_key'], ['chest'], ['nat']);
|
|
1538
|
+
return [
|
|
1539
|
+
annotateVar({ prim: 'or', args: [{ prim: 'bytes' }, { prim: 'bool' }] }),
|
|
1540
|
+
...stack.slice(3),
|
|
1541
|
+
];
|
|
1542
|
+
case 'VIEW': {
|
|
1543
|
+
const s = args(0, null, ['address']);
|
|
1544
|
+
ensurePushableType(s[0]);
|
|
1545
|
+
return [annotateVar({ prim: 'option', args: [instruction.args[1]] }), ...stack.slice(2)];
|
|
1546
|
+
}
|
|
1547
|
+
case 'MIN_BLOCK_TIME':
|
|
1548
|
+
return [annotateVar({ prim: 'nat' }), ...stack];
|
|
1549
|
+
case 'EMIT': {
|
|
1550
|
+
const ia = instructionAnn({ f: 1, t: 1 });
|
|
1551
|
+
if (instruction.args) {
|
|
1552
|
+
const s = args(0, null);
|
|
1553
|
+
ensureTypesEqual(s[0], instruction.args[0]);
|
|
1554
|
+
return [annotate({ prim: 'operation' }, ia), ...stack.slice(1)];
|
|
1555
|
+
}
|
|
1556
|
+
return [annotate({ prim: 'operation' }, ia), ...stack.slice(1)];
|
|
1557
|
+
}
|
|
1558
|
+
case 'IS_IMPLICIT_ACCOUNT':
|
|
1559
|
+
args(0, ['address']);
|
|
1560
|
+
return [annotateVar({ prim: 'option', args: [{ prim: 'key_hash' }] }), ...stack.slice(1)];
|
|
1561
|
+
case 'INDEX_ADDRESS':
|
|
1562
|
+
args(0, ['address']);
|
|
1563
|
+
return [annotateVar({ prim: 'nat' }), ...stack.slice(1)];
|
|
1564
|
+
case 'GET_ADDRESS_INDEX':
|
|
1565
|
+
args(0, ['address']);
|
|
1566
|
+
return [annotateVar({ prim: 'option', args: [{ prim: 'nat' }] }), ...stack.slice(1)];
|
|
1567
|
+
default:
|
|
1568
|
+
throw new utils_1.MichelsonError(instruction, `unexpected instruction: ${instruction.prim}`);
|
|
1569
|
+
}
|
|
1570
|
+
})(instruction);
|
|
1571
|
+
if ((ctx === null || ctx === void 0 ? void 0 : ctx.traceCallback) !== undefined) {
|
|
1572
|
+
const trace = {
|
|
1573
|
+
op: instruction,
|
|
1574
|
+
in: stack,
|
|
1575
|
+
out: retStack,
|
|
1576
|
+
};
|
|
1577
|
+
ctx.traceCallback(trace);
|
|
1578
|
+
}
|
|
1579
|
+
return retStack;
|
|
1580
|
+
}
|
|
1581
|
+
function contractSection(contract, section) {
|
|
1582
|
+
for (const s of contract) {
|
|
1583
|
+
if (s.prim === section) {
|
|
1584
|
+
return s;
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
throw new utils_1.MichelsonError(contract, `missing contract section: ${section}`);
|
|
1588
|
+
}
|
|
1589
|
+
function contractViews(contract) {
|
|
1590
|
+
const views = {};
|
|
1591
|
+
for (const s of contract) {
|
|
1592
|
+
if (s.prim === 'view') {
|
|
1593
|
+
views[s.args[0].string] = s;
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
return views;
|
|
1597
|
+
}
|
|
1598
|
+
function isContract(v) {
|
|
1599
|
+
if (Array.isArray(v)) {
|
|
1600
|
+
for (const s of v) {
|
|
1601
|
+
if ('prim' in s && (s.prim === 'parameter' || s.prim === 'storage' || s.prim === 'code')) {
|
|
1602
|
+
return true;
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
return false;
|
|
1607
|
+
}
|
|
1608
|
+
function contractEntryPoint(src, ep) {
|
|
1609
|
+
ep = ep || '%default';
|
|
1610
|
+
const entryPoint = contractEntryPoints(src).find((x) => x[0] === ep);
|
|
1611
|
+
if (entryPoint !== undefined) {
|
|
1612
|
+
return entryPoint[1];
|
|
1613
|
+
}
|
|
1614
|
+
else if (ep === '%default') {
|
|
1615
|
+
return isContract(src) ? contractSection(src, 'parameter').args[0] : src;
|
|
1616
|
+
}
|
|
1617
|
+
return null;
|
|
1618
|
+
}
|
|
1619
|
+
function isOrType(t) {
|
|
1620
|
+
return Array.isArray(t) || t.prim === 'or';
|
|
1621
|
+
}
|
|
1622
|
+
function contractEntryPoints(src) {
|
|
1623
|
+
if (isContract(src)) {
|
|
1624
|
+
const param = contractSection(src, 'parameter');
|
|
1625
|
+
const ch = contractEntryPoints(param.args[0]);
|
|
1626
|
+
const a = (0, utils_1.unpackAnnotations)(param);
|
|
1627
|
+
return a.f ? [[a.f[0], param.args[0]], ...ch] : ch;
|
|
1628
|
+
}
|
|
1629
|
+
if (isOrType(src)) {
|
|
1630
|
+
const args = typeArgs(src);
|
|
1631
|
+
const getArg = (n) => {
|
|
1632
|
+
const a = (0, utils_1.unpackAnnotations)(args[n]);
|
|
1633
|
+
if (typeID(args[n]) === 'or') {
|
|
1634
|
+
const ch = contractEntryPoints(args[n]);
|
|
1635
|
+
return a.f ? [[a.f[0], args[n]], ...ch] : ch;
|
|
1636
|
+
}
|
|
1637
|
+
return a.f ? [[a.f[0], args[n]]] : [];
|
|
1638
|
+
};
|
|
1639
|
+
return [...getArg(0), ...getArg(1)];
|
|
1640
|
+
}
|
|
1641
|
+
return [];
|
|
1642
|
+
}
|
|
1643
|
+
// Contract validation
|
|
1644
|
+
function assertContractValid(contract, ctx) {
|
|
1645
|
+
const assertSection = (parameter, storage, ret, code) => {
|
|
1646
|
+
assertTypeAnnotationsValid(parameter, true);
|
|
1647
|
+
assertTypeAnnotationsValid(storage);
|
|
1648
|
+
const arg = {
|
|
1649
|
+
prim: 'pair',
|
|
1650
|
+
args: [
|
|
1651
|
+
Object.assign(Object.assign({}, parameter), { annots: ['@parameter'] }),
|
|
1652
|
+
Object.assign(Object.assign({}, storage), { annots: ['@storage'] }),
|
|
1653
|
+
],
|
|
1654
|
+
};
|
|
1655
|
+
const out = functionTypeInternal(code, [arg], Object.assign(Object.assign({}, ctx), { contract }));
|
|
1656
|
+
if ('failed' in out) {
|
|
1657
|
+
return out;
|
|
1658
|
+
}
|
|
1659
|
+
try {
|
|
1660
|
+
assertStacksEqual(out, [ret]);
|
|
1661
|
+
}
|
|
1662
|
+
catch (err) {
|
|
1663
|
+
if (err instanceof utils_1.MichelsonError) {
|
|
1664
|
+
throw new MichelsonInstructionError(code, out, err.message);
|
|
1665
|
+
}
|
|
1666
|
+
else {
|
|
1667
|
+
throw err;
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
return out;
|
|
1671
|
+
};
|
|
1672
|
+
const parameter = contractSection(contract, 'parameter').args[0];
|
|
1673
|
+
const storage = contractSection(contract, 'storage').args[0];
|
|
1674
|
+
const code = contractSection(contract, 'code').args[0];
|
|
1675
|
+
const expected = {
|
|
1676
|
+
prim: 'pair',
|
|
1677
|
+
args: [{ prim: 'list', args: [{ prim: 'operation' }] }, storage],
|
|
1678
|
+
};
|
|
1679
|
+
const ret = assertSection(parameter, storage, expected, code);
|
|
1680
|
+
for (const view of Object.values(contractViews(contract))) {
|
|
1681
|
+
assertSection(view.args[1], storage, view.args[2], view.args[3]);
|
|
1682
|
+
}
|
|
1683
|
+
return ret;
|
|
1684
|
+
}
|
|
1685
|
+
// Exported wrapper functions
|
|
1686
|
+
function assertDataValid(d, t, ctx) {
|
|
1687
|
+
assertTypeAnnotationsValid(t);
|
|
1688
|
+
assertDataValidInternal(d, t, ctx || null);
|
|
1689
|
+
}
|
|
1690
|
+
function functionType(inst, stack, ctx) {
|
|
1691
|
+
for (const t of stack) {
|
|
1692
|
+
assertTypeAnnotationsValid(t);
|
|
1693
|
+
}
|
|
1694
|
+
if ((ctx === null || ctx === void 0 ? void 0 : ctx.contract) !== undefined) {
|
|
1695
|
+
for (const typesec of ['parameter', 'storage']) {
|
|
1696
|
+
const sec = contractSection(ctx.contract, typesec).args[0];
|
|
1697
|
+
assertTypeAnnotationsValid(sec);
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
return functionTypeInternal(inst, stack, ctx || null);
|
|
1701
|
+
}
|
|
1702
|
+
function assertTypesEqual(a, b, field = false) {
|
|
1703
|
+
if (Array.isArray(a)) {
|
|
1704
|
+
// type guards don't work for parametrized generic types
|
|
1705
|
+
for (const v of a) {
|
|
1706
|
+
assertTypeAnnotationsValid(v);
|
|
1707
|
+
}
|
|
1708
|
+
for (const v of b) {
|
|
1709
|
+
assertTypeAnnotationsValid(v);
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
else {
|
|
1713
|
+
assertTypeAnnotationsValid(a);
|
|
1714
|
+
assertTypeAnnotationsValid(b);
|
|
1715
|
+
}
|
|
1716
|
+
assertScalarTypesEqual(a, b, field);
|
|
1717
|
+
}
|
|
1718
|
+
function isTypeAnnotationsValid(t, field = false) {
|
|
1719
|
+
try {
|
|
1720
|
+
assertTypeAnnotationsValid(t, field);
|
|
1721
|
+
return true;
|
|
1722
|
+
}
|
|
1723
|
+
catch (_a) {
|
|
1724
|
+
return false;
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
function isContractValid(contract, ctx) {
|
|
1728
|
+
try {
|
|
1729
|
+
return assertContractValid(contract, ctx);
|
|
1730
|
+
}
|
|
1731
|
+
catch (_a) {
|
|
1732
|
+
return null;
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
function isDataValid(d, t, ctx) {
|
|
1736
|
+
try {
|
|
1737
|
+
assertDataValid(d, t, ctx);
|
|
1738
|
+
return true;
|
|
1739
|
+
}
|
|
1740
|
+
catch (_a) {
|
|
1741
|
+
return false;
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
function isTypeEqual(a, b, field = false) {
|
|
1745
|
+
try {
|
|
1746
|
+
assertTypesEqual(a, b, field);
|
|
1747
|
+
return true;
|
|
1748
|
+
}
|
|
1749
|
+
catch (_a) {
|
|
1750
|
+
return false;
|
|
1751
|
+
}
|
|
1752
|
+
}
|