From f9ddd6dfd898a8da3a8e78642c578aab77698cfa Mon Sep 17 00:00:00 2001 From: Aleksandr Kirsanov Date: Thu, 13 Jun 2024 20:13:18 +0300 Subject: [PATCH] Bump func-js-bin to v0.5.0, update contracts to modern syntax --- package.json | 4 +- test/compiler.spec.ts | 15 +- test/contracts/stdlib.fc | 436 +++++++++++++++++----------------- test/contracts/wallet-code.fc | 14 +- 4 files changed, 237 insertions(+), 232 deletions(-) diff --git a/package.json b/package.json index 179d30e..456e55d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ton-community/func-js", - "version": "0.7.0", + "version": "0.8.0", "description": "The TON FunC smart-contract compiler", "main": "dist/index.js", "bin": { @@ -29,7 +29,7 @@ "typescript": "^4.9.5" }, "dependencies": { - "@ton-community/func-js-bin": "0.4.4-newops.1", + "@ton-community/func-js-bin": "0.5.0", "arg": "^5.0.2" } } diff --git a/test/compiler.spec.ts b/test/compiler.spec.ts index 13033e3..38fb97e 100644 --- a/test/compiler.spec.ts +++ b/test/compiler.spec.ts @@ -3,17 +3,16 @@ import fs from 'fs'; import {Cell} from 'ton-core'; describe('func-js', () => { - const walletCodeCellHash = Buffer.from("hA3nAz+xEJePYGrDyjJ+BXBcxSp9Y2xaAFLRgGntfDs=", 'base64'); + const walletCodeCellHash = "8OtG02lbUYFZHJXjmAjKn0p69Ih9Y0V+4eS5KKH/Io0="; const compilerVersionExpected = { - funcVersion: "0.4.4", - funcFiftLibCommitDate: "2024-03-27 12:57:15 +0300", - funcFiftLibCommitHash: "ffe0a1c63073dda0a0dd0e14f199b83fe5b05e66", + funcVersion: "0.5.0", + funcFiftLibCommitHash: "3c02cbfcbb83739c5138f33ae58ae3abf8d593f4", }; it('should return compiler version', async () => { let version = await compilerVersion(); - expect(version).toEqual(compilerVersionExpected); + expect(version).toMatchObject(compilerVersionExpected); }); it('should compile', async () => { @@ -30,7 +29,7 @@ describe('func-js', () => { result = result as SuccessResult; let codeCell = Cell.fromBoc(Buffer.from(result.codeBoc, "base64"))[0]; - expect(codeCell.hash().equals(walletCodeCellHash)).toBe(true); + expect(codeCell.hash().toString('base64')).toBe(walletCodeCellHash); }); it('should compile using map source resolver', async () => { @@ -47,7 +46,7 @@ describe('func-js', () => { result = result as SuccessResult; let codeCell = Cell.fromBoc(Buffer.from(result.codeBoc, "base64"))[0]; - expect(codeCell.hash().equals(walletCodeCellHash)).toBe(true); + expect(codeCell.hash().toString('base64')).toBe(walletCodeCellHash); }); it('should handle includes', async () => { @@ -65,7 +64,7 @@ describe('func-js', () => { result = result as SuccessResult; let codeCell = Cell.fromBoc(Buffer.from(result.codeBoc, "base64"))[0]; - expect(codeCell.hash().equals(walletCodeCellHash)).toBe(true); + expect(codeCell.hash().toString('base64')).toBe(walletCodeCellHash); }); it('should fail if entry point source is not provided', async () => { diff --git a/test/contracts/stdlib.fc b/test/contracts/stdlib.fc index 7689bff..86ef899 100644 --- a/test/contracts/stdlib.fc +++ b/test/contracts/stdlib.fc @@ -1,215 +1,221 @@ -;; Standard library for funC -;; - -forall X -> tuple cons(X head, tuple tail) asm "CONS"; -forall X -> (X, tuple) uncons(tuple list) asm "UNCONS"; -forall X -> (tuple, X) list_next(tuple list) asm( -> 1 0) "UNCONS"; -forall X -> X car(tuple list) asm "CAR"; -tuple cdr(tuple list) asm "CDR"; -tuple empty_tuple() asm "NIL"; -forall X -> tuple tpush(tuple t, X value) asm "TPUSH"; -forall X -> (tuple, ()) ~tpush(tuple t, X value) asm "TPUSH"; -forall X -> [X] single(X x) asm "SINGLE"; -forall X -> X unsingle([X] t) asm "UNSINGLE"; -forall X, Y -> [X, Y] pair(X x, Y y) asm "PAIR"; -forall X, Y -> (X, Y) unpair([X, Y] t) asm "UNPAIR"; -forall X, Y, Z -> [X, Y, Z] triple(X x, Y y, Z z) asm "TRIPLE"; -forall X, Y, Z -> (X, Y, Z) untriple([X, Y, Z] t) asm "UNTRIPLE"; -forall X, Y, Z, W -> [X, Y, Z, W] tuple4(X x, Y y, Z z, W w) asm "4 TUPLE"; -forall X, Y, Z, W -> (X, Y, Z, W) untuple4([X, Y, Z, W] t) asm "4 UNTUPLE"; -forall X -> X first(tuple t) asm "FIRST"; -forall X -> X second(tuple t) asm "SECOND"; -forall X -> X third(tuple t) asm "THIRD"; -forall X -> X fourth(tuple t) asm "3 INDEX"; -forall X, Y -> X pair_first([X, Y] p) asm "FIRST"; -forall X, Y -> Y pair_second([X, Y] p) asm "SECOND"; -forall X, Y, Z -> X triple_first([X, Y, Z] p) asm "FIRST"; -forall X, Y, Z -> Y triple_second([X, Y, Z] p) asm "SECOND"; -forall X, Y, Z -> Z triple_third([X, Y, Z] p) asm "THIRD"; -forall X -> X null() asm "PUSHNULL"; -forall X -> (X, ()) ~impure_touch(X x) impure asm "NOP"; - -int now() asm "NOW"; -slice my_address() asm "MYADDR"; -tuple get_balance() asm "BALANCE"; -int cur_lt() asm "LTIME"; -int block_lt() asm "BLOCKLT"; - -int cell_hash(cell c) asm "HASHCU"; -int slice_hash(slice s) asm "HASHSU"; -int string_hash(slice s) asm "SHA256U"; - -int check_signature(int hash, slice signature, int public_key) asm "CHKSIGNU"; -int check_data_signature(slice data, slice signature, int public_key) asm "CHKSIGNS"; - -(int, int, int) compute_data_size(cell c, int max_cells) impure asm "CDATASIZE"; -(int, int, int) slice_compute_data_size(slice s, int max_cells) impure asm "SDATASIZE"; -(int, int, int, int) compute_data_size?(cell c, int max_cells) asm "CDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; -(int, int, int, int) slice_compute_data_size?(cell c, int max_cells) asm "SDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; - -;; () throw_if(int excno, int cond) impure asm "THROWARGIF"; - -() dump_stack() impure asm "DUMPSTK"; - -cell get_data() asm "c4 PUSH"; -() set_data(cell c) impure asm "c4 POP"; -cont get_c3() impure asm "c3 PUSH"; -() set_c3(cont c) impure asm "c3 POP"; -cont bless(slice s) impure asm "BLESS"; - -() accept_message() impure asm "ACCEPT"; -() set_gas_limit(int limit) impure asm "SETGASLIMIT"; -() commit() impure asm "COMMIT"; -() buy_gas(int gram) impure asm "BUYGAS"; - -int min(int x, int y) asm "MIN"; -int max(int x, int y) asm "MAX"; -(int, int) minmax(int x, int y) asm "MINMAX"; -int abs(int x) asm "ABS"; - -slice begin_parse(cell c) asm "CTOS"; -() end_parse(slice s) impure asm "ENDS"; -(slice, cell) load_ref(slice s) asm( -> 1 0) "LDREF"; -cell preload_ref(slice s) asm "PLDREF"; -;; (slice, int) ~load_int(slice s, int len) asm(s len -> 1 0) "LDIX"; -;; (slice, int) ~load_uint(slice s, int len) asm( -> 1 0) "LDUX"; -;; int preload_int(slice s, int len) asm "PLDIX"; -;; int preload_uint(slice s, int len) asm "PLDUX"; -;; (slice, slice) load_bits(slice s, int len) asm(s len -> 1 0) "LDSLICEX"; -;; slice preload_bits(slice s, int len) asm "PLDSLICEX"; -(slice, int) load_grams(slice s) asm( -> 1 0) "LDGRAMS"; -slice skip_bits(slice s, int len) asm "SDSKIPFIRST"; -(slice, ()) ~skip_bits(slice s, int len) asm "SDSKIPFIRST"; -slice first_bits(slice s, int len) asm "SDCUTFIRST"; -slice skip_last_bits(slice s, int len) asm "SDSKIPLAST"; -(slice, ()) ~skip_last_bits(slice s, int len) asm "SDSKIPLAST"; -slice slice_last(slice s, int len) asm "SDCUTLAST"; -(slice, cell) load_dict(slice s) asm( -> 1 0) "LDDICT"; -cell preload_dict(slice s) asm "PLDDICT"; -slice skip_dict(slice s) asm "SKIPDICT"; - -(slice, cell) load_maybe_ref(slice s) asm( -> 1 0) "LDOPTREF"; -cell preload_maybe_ref(slice s) asm "PLDOPTREF"; -builder store_maybe_ref(builder b, cell c) asm(c b) "STOPTREF"; - -int cell_depth(cell c) asm "CDEPTH"; - -int slice_refs(slice s) asm "SREFS"; -int slice_bits(slice s) asm "SBITS"; -(int, int) slice_bits_refs(slice s) asm "SBITREFS"; -int slice_empty?(slice s) asm "SEMPTY"; -int slice_data_empty?(slice s) asm "SDEMPTY"; -int slice_refs_empty?(slice s) asm "SREMPTY"; -int slice_depth(slice s) asm "SDEPTH"; - -int builder_refs(builder b) asm "BREFS"; -int builder_bits(builder b) asm "BBITS"; -int builder_depth(builder b) asm "BDEPTH"; - -builder begin_cell() asm "NEWC"; -cell end_cell(builder b) asm "ENDC"; - builder store_ref(builder b, cell c) asm(c b) "STREF"; -;; builder store_uint(builder b, int x, int len) asm(x b len) "STUX"; -;; builder store_int(builder b, int x, int len) asm(x b len) "STIX"; -builder store_slice(builder b, slice s) asm "STSLICER"; -builder store_grams(builder b, int x) asm "STGRAMS"; -builder store_dict(builder b, cell c) asm(c b) "STDICT"; - -(slice, slice) load_msg_addr(slice s) asm( -> 1 0) "LDMSGADDR"; -tuple parse_addr(slice s) asm "PARSEMSGADDR"; -(int, int) parse_std_addr(slice s) asm "REWRITESTDADDR"; -(int, slice) parse_var_addr(slice s) asm "REWRITEVARADDR"; - -cell idict_set_ref(cell dict, int key_len, int index, cell value) asm(value index dict key_len) "DICTISETREF"; -(cell, ()) ~idict_set_ref(cell dict, int key_len, int index, cell value) asm(value index dict key_len) "DICTISETREF"; -cell udict_set_ref(cell dict, int key_len, int index, cell value) asm(value index dict key_len) "DICTUSETREF"; -(cell, ()) ~udict_set_ref(cell dict, int key_len, int index, cell value) asm(value index dict key_len) "DICTUSETREF"; -cell idict_get_ref(cell dict, int key_len, int index) asm(index dict key_len) "DICTIGETOPTREF"; -(cell, int) idict_get_ref?(cell dict, int key_len, int index) asm(index dict key_len) "DICTIGETREF"; -(cell, int) udict_get_ref?(cell dict, int key_len, int index) asm(index dict key_len) "DICTUGETREF"; -(cell, cell) idict_set_get_ref(cell dict, int key_len, int index, cell value) asm(value index dict key_len) "DICTISETGETOPTREF"; -(cell, cell) udict_set_get_ref(cell dict, int key_len, int index, cell value) asm(value index dict key_len) "DICTUSETGETOPTREF"; -(cell, int) idict_delete?(cell dict, int key_len, int index) asm(index dict key_len) "DICTIDEL"; -(cell, int) udict_delete?(cell dict, int key_len, int index) asm(index dict key_len) "DICTUDEL"; -(slice, int) idict_get?(cell dict, int key_len, int index) asm(index dict key_len) "DICTIGET" "NULLSWAPIFNOT"; -(slice, int) udict_get?(cell dict, int key_len, int index) asm(index dict key_len) "DICTUGET" "NULLSWAPIFNOT"; -(cell, slice, int) idict_delete_get?(cell dict, int key_len, int index) asm(index dict key_len) "DICTIDELGET" "NULLSWAPIFNOT"; -(cell, slice, int) udict_delete_get?(cell dict, int key_len, int index) asm(index dict key_len) "DICTUDELGET" "NULLSWAPIFNOT"; -(cell, (slice, int)) ~idict_delete_get?(cell dict, int key_len, int index) asm(index dict key_len) "DICTIDELGET" "NULLSWAPIFNOT"; -(cell, (slice, int)) ~udict_delete_get?(cell dict, int key_len, int index) asm(index dict key_len) "DICTUDELGET" "NULLSWAPIFNOT"; -cell udict_set(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTUSET"; -(cell, ()) ~udict_set(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTUSET"; -cell idict_set(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTISET"; -(cell, ()) ~idict_set(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTISET"; -cell dict_set(cell dict, int key_len, slice index, slice value) asm(value index dict key_len) "DICTSET"; -(cell, ()) ~dict_set(cell dict, int key_len, slice index, slice value) asm(value index dict key_len) "DICTSET"; -(cell, int) udict_add?(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTUADD"; -(cell, int) udict_replace?(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTUREPLACE"; -(cell, int) idict_add?(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTIADD"; -(cell, int) idict_replace?(cell dict, int key_len, int index, slice value) asm(value index dict key_len) "DICTIREPLACE"; -cell udict_set_builder(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTUSETB"; -(cell, ()) ~udict_set_builder(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTUSETB"; -cell idict_set_builder(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTISETB"; -(cell, ()) ~idict_set_builder(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTISETB"; -cell dict_set_builder(cell dict, int key_len, slice index, builder value) asm(value index dict key_len) "DICTSETB"; -(cell, ()) ~dict_set_builder(cell dict, int key_len, slice index, builder value) asm(value index dict key_len) "DICTSETB"; -(cell, int) udict_add_builder?(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTUADDB"; -(cell, int) udict_replace_builder?(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTUREPLACEB"; -(cell, int) idict_add_builder?(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTIADDB"; -(cell, int) idict_replace_builder?(cell dict, int key_len, int index, builder value) asm(value index dict key_len) "DICTIREPLACEB"; -(cell, int, slice, int) udict_delete_get_min(cell dict, int key_len) asm(-> 0 2 1 3) "DICTUREMMIN" "NULLSWAPIFNOT2"; -(cell, (int, slice, int)) ~udict::delete_get_min(cell dict, int key_len) asm(-> 0 2 1 3) "DICTUREMMIN" "NULLSWAPIFNOT2"; -(cell, int, slice, int) idict_delete_get_min(cell dict, int key_len) asm(-> 0 2 1 3) "DICTIREMMIN" "NULLSWAPIFNOT2"; -(cell, (int, slice, int)) ~idict::delete_get_min(cell dict, int key_len) asm(-> 0 2 1 3) "DICTIREMMIN" "NULLSWAPIFNOT2"; -(cell, slice, slice, int) dict_delete_get_min(cell dict, int key_len) asm(-> 0 2 1 3) "DICTREMMIN" "NULLSWAPIFNOT2"; -(cell, (slice, slice, int)) ~dict::delete_get_min(cell dict, int key_len) asm(-> 0 2 1 3) "DICTREMMIN" "NULLSWAPIFNOT2"; -(cell, int, slice, int) udict_delete_get_max(cell dict, int key_len) asm(-> 0 2 1 3) "DICTUREMMAX" "NULLSWAPIFNOT2"; -(cell, (int, slice, int)) ~udict::delete_get_max(cell dict, int key_len) asm(-> 0 2 1 3) "DICTUREMMAX" "NULLSWAPIFNOT2"; -(cell, int, slice, int) idict_delete_get_max(cell dict, int key_len) asm(-> 0 2 1 3) "DICTIREMMAX" "NULLSWAPIFNOT2"; -(cell, (int, slice, int)) ~idict::delete_get_max(cell dict, int key_len) asm(-> 0 2 1 3) "DICTIREMMAX" "NULLSWAPIFNOT2"; -(cell, slice, slice, int) dict_delete_get_max(cell dict, int key_len) asm(-> 0 2 1 3) "DICTREMMAX" "NULLSWAPIFNOT2"; -(cell, (slice, slice, int)) ~dict::delete_get_max(cell dict, int key_len) asm(-> 0 2 1 3) "DICTREMMAX" "NULLSWAPIFNOT2"; -(int, slice, int) udict_get_min?(cell dict, int key_len) asm (-> 1 0 2) "DICTUMIN" "NULLSWAPIFNOT2"; -(int, slice, int) udict_get_max?(cell dict, int key_len) asm (-> 1 0 2) "DICTUMAX" "NULLSWAPIFNOT2"; -(int, cell, int) udict_get_min_ref?(cell dict, int key_len) asm (-> 1 0 2) "DICTUMINREF" "NULLSWAPIFNOT2"; -(int, cell, int) udict_get_max_ref?(cell dict, int key_len) asm (-> 1 0 2) "DICTUMAXREF" "NULLSWAPIFNOT2"; -(int, slice, int) idict_get_min?(cell dict, int key_len) asm (-> 1 0 2) "DICTIMIN" "NULLSWAPIFNOT2"; -(int, slice, int) idict_get_max?(cell dict, int key_len) asm (-> 1 0 2) "DICTIMAX" "NULLSWAPIFNOT2"; -(int, cell, int) idict_get_min_ref?(cell dict, int key_len) asm (-> 1 0 2) "DICTIMINREF" "NULLSWAPIFNOT2"; -(int, cell, int) idict_get_max_ref?(cell dict, int key_len) asm (-> 1 0 2) "DICTIMAXREF" "NULLSWAPIFNOT2"; -(int, slice, int) udict_get_next?(cell dict, int key_len, int pivot) asm(pivot dict key_len -> 1 0 2) "DICTUGETNEXT" "NULLSWAPIFNOT2"; -(int, slice, int) udict_get_nexteq?(cell dict, int key_len, int pivot) asm(pivot dict key_len -> 1 0 2) "DICTUGETNEXTEQ" "NULLSWAPIFNOT2"; -(int, slice, int) udict_get_prev?(cell dict, int key_len, int pivot) asm(pivot dict key_len -> 1 0 2) "DICTUGETPREV" "NULLSWAPIFNOT2"; -(int, slice, int) udict_get_preveq?(cell dict, int key_len, int pivot) asm(pivot dict key_len -> 1 0 2) "DICTUGETPREVEQ" "NULLSWAPIFNOT2"; -(int, slice, int) idict_get_next?(cell dict, int key_len, int pivot) asm(pivot dict key_len -> 1 0 2) "DICTIGETNEXT" "NULLSWAPIFNOT2"; -(int, slice, int) idict_get_nexteq?(cell dict, int key_len, int pivot) asm(pivot dict key_len -> 1 0 2) "DICTIGETNEXTEQ" "NULLSWAPIFNOT2"; -(int, slice, int) idict_get_prev?(cell dict, int key_len, int pivot) asm(pivot dict key_len -> 1 0 2) "DICTIGETPREV" "NULLSWAPIFNOT2"; -(int, slice, int) idict_get_preveq?(cell dict, int key_len, int pivot) asm(pivot dict key_len -> 1 0 2) "DICTIGETPREVEQ" "NULLSWAPIFNOT2"; -cell new_dict() asm "NEWDICT"; -int dict_empty?(cell c) asm "DICTEMPTY"; - -(slice, slice, slice, int) pfxdict_get?(cell dict, int key_len, slice key) asm(key dict key_len) "PFXDICTGETQ" "NULLSWAPIFNOT2"; -(cell, int) pfxdict_set?(cell dict, int key_len, slice key, slice value) asm(value key dict key_len) "PFXDICTSET"; -(cell, int) pfxdict_delete?(cell dict, int key_len, slice key) asm(key dict key_len) "PFXDICTDEL"; - -cell config_param(int x) asm "CONFIGOPTPARAM"; -int cell_null?(cell c) asm "ISNULL"; - -() raw_reserve(int amount, int mode) impure asm "RAWRESERVE"; -() raw_reserve_extra(int amount, cell extra_amount, int mode) impure asm "RAWRESERVEX"; -() send_raw_message(cell msg, int mode) impure asm "SENDRAWMSG"; -() set_code(cell new_code) impure asm "SETCODE"; - -int random() impure asm "RANDU256"; -int rand(int range) impure asm "RAND"; -int get_seed() impure asm "RANDSEED"; -int set_seed() impure asm "SETRAND"; -() randomize(int x) impure asm "ADDRAND"; -() randomize_lt() impure asm "LTIME" "ADDRAND"; - -builder store_coins(builder b, int x) asm "STVARUINT16"; -(slice, int) load_coins(slice s) asm( -> 1 0) "LDVARUINT16"; - -int equal_slices (slice a, slice b) asm "SDEQ"; -int builder_null?(builder b) asm "ISNULL"; -builder store_builder(builder to, builder from) asm "STBR"; \ No newline at end of file +// Standard library for FunC +// +#pragma version >=0.5.0; + +forall X -> tuple cons(X head, tuple tail) pure asm "CONS"; +forall X -> (X, tuple) uncons(tuple list) pure asm "UNCONS"; +forall X -> (tuple, X) list_next(tuple list) pure asm( -> 1 0) "UNCONS"; +forall X -> X car(tuple list) pure asm "CAR"; +tuple cdr(tuple list) pure asm "CDR"; +tuple empty_tuple() pure asm "NIL"; +forall X -> tuple tpush(tuple t, X value) pure asm "TPUSH"; +forall X -> (tuple, ()) ~tpush(tuple t, X value) pure asm "TPUSH"; +forall X -> [X] single(X x) pure asm "SINGLE"; +forall X -> X unsingle([X] t) pure asm "UNSINGLE"; +forall X, Y -> [X, Y] pair(X x, Y y) pure asm "PAIR"; +forall X, Y -> (X, Y) unpair([X, Y] t) pure asm "UNPAIR"; +forall X, Y, Z -> [X, Y, Z] triple(X x, Y y, Z z) pure asm "TRIPLE"; +forall X, Y, Z -> (X, Y, Z) untriple([X, Y, Z] t) pure asm "UNTRIPLE"; +forall X, Y, Z, W -> [X, Y, Z, W] tuple4(X x, Y y, Z z, W w) pure asm "4 TUPLE"; +forall X, Y, Z, W -> (X, Y, Z, W) untuple4([X, Y, Z, W] t) pure asm "4 UNTUPLE"; +forall X -> X first(tuple t) pure asm "FIRST"; +forall X -> X second(tuple t) pure asm "SECOND"; +forall X -> X third(tuple t) pure asm "THIRD"; +forall X -> X fourth(tuple t) pure asm "3 INDEX"; +forall X, Y -> X pair_first([X, Y] p) pure asm "FIRST"; +forall X, Y -> Y pair_second([X, Y] p) pure asm "SECOND"; +forall X, Y, Z -> X triple_first([X, Y, Z] p) pure asm "FIRST"; +forall X, Y, Z -> Y triple_second([X, Y, Z] p) pure asm "SECOND"; +forall X, Y, Z -> Z triple_third([X, Y, Z] p) pure asm "THIRD"; +forall X -> X null() pure asm "PUSHNULL"; +forall X -> (X, ()) ~impure_touch(X x) asm "NOP"; + +int now() pure asm "NOW"; +slice my_address() pure asm "MYADDR"; +tuple get_balance() pure asm "BALANCE"; +int cur_lt() pure asm "LTIME"; +int block_lt() pure asm "BLOCKLT"; + +int cell_hash(cell c) pure asm "HASHCU"; +int slice_hash(slice s) pure asm "HASHSU"; +int string_hash(slice s) pure asm "SHA256U"; + +int check_signature(int hash, slice signature, int public_key) pure asm "CHKSIGNU"; +int check_data_signature(slice data, slice signature, int public_key) pure asm "CHKSIGNS"; + +(int, int, int) compute_data_size(cell c, int max_cells) asm "CDATASIZE"; +(int, int, int) slice_compute_data_size(slice s, int max_cells) asm "SDATASIZE"; +(int, int, int, int) compute_data_size?(cell c, int max_cells) pure asm "CDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; +(int, int, int, int) slice_compute_data_size?(slice s, int max_cells) pure asm "SDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; + +() throw(int excno) builtin; +() throw_if(int excno, int cond) builtin; +() throw_unless(int excno, int cond) builtin; +forall X -> () throw_arg(X x, int excno) builtin; +forall X -> () throw_arg_if(X x, int excno, int cond) builtin; +forall X -> () throw_arg_unless(X x, int excno, int cond) builtin; + +() dump_stack() asm "DUMPSTK"; + +cell get_data() pure asm "c4 PUSH"; +() set_data(cell c) asm "c4 POP"; +cont get_c3() pure asm "c3 PUSH"; +() set_c3(cont c) asm "c3 POP"; +cont bless(slice s) pure asm "BLESS"; + +() accept_message() asm "ACCEPT"; +() set_gas_limit(int limit) asm "SETGASLIMIT"; +() commit() asm "COMMIT"; +() buy_gas(int gram) asm "BUYGAS"; + +int min(int x, int y) pure asm "MIN"; +int max(int x, int y) pure asm "MAX"; +(int, int) minmax(int x, int y) pure asm "MINMAX"; +int abs(int x) pure asm "ABS"; + +slice begin_parse(cell c) pure asm "CTOS"; +() end_parse(slice s) asm "ENDS"; +(slice, cell) load_ref(slice s) pure asm( -> 1 0) "LDREF"; +cell preload_ref(slice s) pure asm "PLDREF"; +(slice, int) load_int(slice s, int len) pure builtin; +(slice, int) load_uint(slice s, int len) pure builtin; +int preload_int(slice s, int len) pure builtin; +int preload_uint(slice s, int len) pure builtin; +(slice, slice) load_bits(slice s, int len) pure builtin; +slice preload_bits(slice s, int len) pure builtin; +(slice, int) load_grams(slice s) pure asm( -> 1 0) "LDGRAMS"; +slice skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; +(slice, ()) ~skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; +slice first_bits(slice s, int len) pure asm "SDCUTFIRST"; +slice skip_last_bits(slice s, int len) pure asm "SDSKIPLAST"; +(slice, ()) ~skip_last_bits(slice s, int len) pure asm "SDSKIPLAST"; +slice slice_last(slice s, int len) pure asm "SDCUTLAST"; +(slice, cell) load_dict(slice s) pure asm( -> 1 0) "LDDICT"; +cell preload_dict(slice s) pure asm "PLDDICT"; +slice skip_dict(slice s) pure asm "SKIPDICT"; + +(slice, cell) load_maybe_ref(slice s) pure asm( -> 1 0) "LDOPTREF"; +cell preload_maybe_ref(slice s) pure asm "PLDOPTREF"; +builder store_maybe_ref(builder b, cell c) pure asm(c b) "STOPTREF"; + +int cell_depth(cell c) pure asm "CDEPTH"; + +int slice_refs(slice s) pure asm "SREFS"; +int slice_bits(slice s) pure asm "SBITS"; +(int, int) slice_bits_refs(slice s) pure asm "SBITREFS"; +int slice_empty?(slice s) pure asm "SEMPTY"; +int slice_data_empty?(slice s) pure asm "SDEMPTY"; +int slice_refs_empty?(slice s) pure asm "SREMPTY"; +int slice_depth(slice s) pure asm "SDEPTH"; + +int builder_refs(builder b) pure asm "BREFS"; +int builder_bits(builder b) pure asm "BBITS"; +int builder_depth(builder b) pure asm "BDEPTH"; + +builder begin_cell() pure asm "NEWC"; +cell end_cell(builder b) pure asm "ENDC"; +builder store_ref(builder b, cell c) pure asm(c b) "STREF"; +builder store_uint(builder b, int x, int len) pure builtin; +builder store_int(builder b, int x, int len) pure builtin; +builder store_slice(builder b, slice s) pure asm "STSLICER"; +builder store_grams(builder b, int x) pure asm "STGRAMS"; +builder store_dict(builder b, cell c) pure asm(c b) "STDICT"; + +(slice, slice) load_msg_addr(slice s) pure asm( -> 1 0) "LDMSGADDR"; +tuple parse_addr(slice s) pure asm "PARSEMSGADDR"; +(int, int) parse_std_addr(slice s) pure asm "REWRITESTDADDR"; +(int, slice) parse_var_addr(slice s) pure asm "REWRITEVARADDR"; + +cell idict_set_ref(cell dict, int key_len, int index, cell value) pure asm(value index dict key_len) "DICTISETREF"; +(cell, ()) ~idict_set_ref(cell dict, int key_len, int index, cell value) pure asm(value index dict key_len) "DICTISETREF"; +cell udict_set_ref(cell dict, int key_len, int index, cell value) pure asm(value index dict key_len) "DICTUSETREF"; +(cell, ()) ~udict_set_ref(cell dict, int key_len, int index, cell value) pure asm(value index dict key_len) "DICTUSETREF"; +cell idict_get_ref(cell dict, int key_len, int index) pure asm(index dict key_len) "DICTIGETOPTREF"; +(cell, int) idict_get_ref?(cell dict, int key_len, int index) pure asm(index dict key_len) "DICTIGETREF"; +(cell, int) udict_get_ref?(cell dict, int key_len, int index) pure asm(index dict key_len) "DICTUGETREF"; +(cell, cell) idict_set_get_ref(cell dict, int key_len, int index, cell value) pure asm(value index dict key_len) "DICTISETGETOPTREF"; +(cell, cell) udict_set_get_ref(cell dict, int key_len, int index, cell value) pure asm(value index dict key_len) "DICTUSETGETOPTREF"; +(cell, int) idict_delete?(cell dict, int key_len, int index) pure asm(index dict key_len) "DICTIDEL"; +(cell, int) udict_delete?(cell dict, int key_len, int index) pure asm(index dict key_len) "DICTUDEL"; +(slice, int) idict_get?(cell dict, int key_len, int index) pure asm(index dict key_len) "DICTIGET" "NULLSWAPIFNOT"; +(slice, int) udict_get?(cell dict, int key_len, int index) pure asm(index dict key_len) "DICTUGET" "NULLSWAPIFNOT"; +(cell, slice, int) idict_delete_get?(cell dict, int key_len, int index) pure asm(index dict key_len) "DICTIDELGET" "NULLSWAPIFNOT"; +(cell, slice, int) udict_delete_get?(cell dict, int key_len, int index) pure asm(index dict key_len) "DICTUDELGET" "NULLSWAPIFNOT"; +(cell, (slice, int)) ~idict_delete_get?(cell dict, int key_len, int index) pure asm(index dict key_len) "DICTIDELGET" "NULLSWAPIFNOT"; +(cell, (slice, int)) ~udict_delete_get?(cell dict, int key_len, int index) pure asm(index dict key_len) "DICTUDELGET" "NULLSWAPIFNOT"; +cell udict_set(cell dict, int key_len, int index, slice value) pure asm(value index dict key_len) "DICTUSET"; +(cell, ()) ~udict_set(cell dict, int key_len, int index, slice value) pure asm(value index dict key_len) "DICTUSET"; +cell idict_set(cell dict, int key_len, int index, slice value) pure asm(value index dict key_len) "DICTISET"; +(cell, ()) ~idict_set(cell dict, int key_len, int index, slice value) pure asm(value index dict key_len) "DICTISET"; +cell dict_set(cell dict, int key_len, slice index, slice value) pure asm(value index dict key_len) "DICTSET"; +(cell, ()) ~dict_set(cell dict, int key_len, slice index, slice value) pure asm(value index dict key_len) "DICTSET"; +(cell, int) udict_add?(cell dict, int key_len, int index, slice value) pure asm(value index dict key_len) "DICTUADD"; +(cell, int) udict_replace?(cell dict, int key_len, int index, slice value) pure asm(value index dict key_len) "DICTUREPLACE"; +(cell, int) idict_add?(cell dict, int key_len, int index, slice value) pure asm(value index dict key_len) "DICTIADD"; +(cell, int) idict_replace?(cell dict, int key_len, int index, slice value) pure asm(value index dict key_len) "DICTIREPLACE"; +cell udict_set_builder(cell dict, int key_len, int index, builder value) pure asm(value index dict key_len) "DICTUSETB"; +(cell, ()) ~udict_set_builder(cell dict, int key_len, int index, builder value) pure asm(value index dict key_len) "DICTUSETB"; +cell idict_set_builder(cell dict, int key_len, int index, builder value) pure asm(value index dict key_len) "DICTISETB"; +(cell, ()) ~idict_set_builder(cell dict, int key_len, int index, builder value) pure asm(value index dict key_len) "DICTISETB"; +cell dict_set_builder(cell dict, int key_len, slice index, builder value) pure asm(value index dict key_len) "DICTSETB"; +(cell, ()) ~dict_set_builder(cell dict, int key_len, slice index, builder value) pure asm(value index dict key_len) "DICTSETB"; +(cell, int) udict_add_builder?(cell dict, int key_len, int index, builder value) pure asm(value index dict key_len) "DICTUADDB"; +(cell, int) udict_replace_builder?(cell dict, int key_len, int index, builder value) pure asm(value index dict key_len) "DICTUREPLACEB"; +(cell, int) idict_add_builder?(cell dict, int key_len, int index, builder value) pure asm(value index dict key_len) "DICTIADDB"; +(cell, int) idict_replace_builder?(cell dict, int key_len, int index, builder value) pure asm(value index dict key_len) "DICTIREPLACEB"; +(cell, int, slice, int) udict_delete_get_min(cell dict, int key_len) pure asm(-> 0 2 1 3) "DICTUREMMIN" "NULLSWAPIFNOT2"; +(cell, (int, slice, int)) ~udict::delete_get_min(cell dict, int key_len) pure asm(-> 0 2 1 3) "DICTUREMMIN" "NULLSWAPIFNOT2"; +(cell, int, slice, int) idict_delete_get_min(cell dict, int key_len) pure asm(-> 0 2 1 3) "DICTIREMMIN" "NULLSWAPIFNOT2"; +(cell, (int, slice, int)) ~idict::delete_get_min(cell dict, int key_len) pure asm(-> 0 2 1 3) "DICTIREMMIN" "NULLSWAPIFNOT2"; +(cell, slice, slice, int) dict_delete_get_min(cell dict, int key_len) pure asm(-> 0 2 1 3) "DICTREMMIN" "NULLSWAPIFNOT2"; +(cell, (slice, slice, int)) ~dict::delete_get_min(cell dict, int key_len) pure asm(-> 0 2 1 3) "DICTREMMIN" "NULLSWAPIFNOT2"; +(cell, int, slice, int) udict_delete_get_max(cell dict, int key_len) pure asm(-> 0 2 1 3) "DICTUREMMAX" "NULLSWAPIFNOT2"; +(cell, (int, slice, int)) ~udict::delete_get_max(cell dict, int key_len) pure asm(-> 0 2 1 3) "DICTUREMMAX" "NULLSWAPIFNOT2"; +(cell, int, slice, int) idict_delete_get_max(cell dict, int key_len) pure asm(-> 0 2 1 3) "DICTIREMMAX" "NULLSWAPIFNOT2"; +(cell, (int, slice, int)) ~idict::delete_get_max(cell dict, int key_len) pure asm(-> 0 2 1 3) "DICTIREMMAX" "NULLSWAPIFNOT2"; +(cell, slice, slice, int) dict_delete_get_max(cell dict, int key_len) pure asm(-> 0 2 1 3) "DICTREMMAX" "NULLSWAPIFNOT2"; +(cell, (slice, slice, int)) ~dict::delete_get_max(cell dict, int key_len) pure asm(-> 0 2 1 3) "DICTREMMAX" "NULLSWAPIFNOT2"; +(int, slice, int) udict_get_min?(cell dict, int key_len) pure asm (-> 1 0 2) "DICTUMIN" "NULLSWAPIFNOT2"; +(int, slice, int) udict_get_max?(cell dict, int key_len) pure asm (-> 1 0 2) "DICTUMAX" "NULLSWAPIFNOT2"; +(int, cell, int) udict_get_min_ref?(cell dict, int key_len) pure asm (-> 1 0 2) "DICTUMINREF" "NULLSWAPIFNOT2"; +(int, cell, int) udict_get_max_ref?(cell dict, int key_len) pure asm (-> 1 0 2) "DICTUMAXREF" "NULLSWAPIFNOT2"; +(int, slice, int) idict_get_min?(cell dict, int key_len) pure asm (-> 1 0 2) "DICTIMIN" "NULLSWAPIFNOT2"; +(int, slice, int) idict_get_max?(cell dict, int key_len) pure asm (-> 1 0 2) "DICTIMAX" "NULLSWAPIFNOT2"; +(int, cell, int) idict_get_min_ref?(cell dict, int key_len) pure asm (-> 1 0 2) "DICTIMINREF" "NULLSWAPIFNOT2"; +(int, cell, int) idict_get_max_ref?(cell dict, int key_len) pure asm (-> 1 0 2) "DICTIMAXREF" "NULLSWAPIFNOT2"; +(int, slice, int) udict_get_next?(cell dict, int key_len, int pivot) pure asm(pivot dict key_len -> 1 0 2) "DICTUGETNEXT" "NULLSWAPIFNOT2"; +(int, slice, int) udict_get_nexteq?(cell dict, int key_len, int pivot) pure asm(pivot dict key_len -> 1 0 2) "DICTUGETNEXTEQ" "NULLSWAPIFNOT2"; +(int, slice, int) udict_get_prev?(cell dict, int key_len, int pivot) pure asm(pivot dict key_len -> 1 0 2) "DICTUGETPREV" "NULLSWAPIFNOT2"; +(int, slice, int) udict_get_preveq?(cell dict, int key_len, int pivot) pure asm(pivot dict key_len -> 1 0 2) "DICTUGETPREVEQ" "NULLSWAPIFNOT2"; +(int, slice, int) idict_get_next?(cell dict, int key_len, int pivot) pure asm(pivot dict key_len -> 1 0 2) "DICTIGETNEXT" "NULLSWAPIFNOT2"; +(int, slice, int) idict_get_nexteq?(cell dict, int key_len, int pivot) pure asm(pivot dict key_len -> 1 0 2) "DICTIGETNEXTEQ" "NULLSWAPIFNOT2"; +(int, slice, int) idict_get_prev?(cell dict, int key_len, int pivot) pure asm(pivot dict key_len -> 1 0 2) "DICTIGETPREV" "NULLSWAPIFNOT2"; +(int, slice, int) idict_get_preveq?(cell dict, int key_len, int pivot) pure asm(pivot dict key_len -> 1 0 2) "DICTIGETPREVEQ" "NULLSWAPIFNOT2"; +cell new_dict() pure asm "NEWDICT"; +int dict_empty?(cell c) pure asm "DICTEMPTY"; + +(slice, slice, slice, int) pfxdict_get?(cell dict, int key_len, slice key) pure asm(key dict key_len) "PFXDICTGETQ" "NULLSWAPIFNOT2"; +(cell, int) pfxdict_set?(cell dict, int key_len, slice key, slice value) pure asm(value key dict key_len) "PFXDICTSET"; +(cell, int) pfxdict_delete?(cell dict, int key_len, slice key) pure asm(key dict key_len) "PFXDICTDEL"; + +cell config_param(int x) pure asm "CONFIGOPTPARAM"; +int cell_null?(cell c) pure asm "ISNULL"; + +() raw_reserve(int amount, int mode) asm "RAWRESERVE"; +() raw_reserve_extra(int amount, cell extra_amount, int mode) asm "RAWRESERVEX"; +() send_raw_message(cell msg, int mode) asm "SENDRAWMSG"; +() set_code(cell new_code) asm "SETCODE"; + +int random() asm "RANDU256"; +int rand(int range) asm "RAND"; +int get_seed() pure asm "RANDSEED"; +int set_seed() asm "SETRAND"; +() randomize(int x) asm "ADDRAND"; +() randomize_lt() asm "LTIME" "ADDRAND"; + +builder store_coins(builder b, int x) pure asm "STVARUINT16"; +(slice, int) load_coins(slice s) pure asm( -> 1 0) "LDVARUINT16"; + +int equal_slices (slice a, slice b) pure asm "SDEQ"; +int builder_null?(builder b) pure asm "ISNULL"; +builder store_builder(builder to, builder from) pure asm "STBR"; \ No newline at end of file diff --git a/test/contracts/wallet-code.fc b/test/contracts/wallet-code.fc index 8c10843..e41f486 100644 --- a/test/contracts/wallet-code.fc +++ b/test/contracts/wallet-code.fc @@ -1,12 +1,12 @@ #include "stdlib.fc"; -;; Simple wallet smart contract +// Simple wallet smart contract -() recv_internal(slice in_msg) impure { - ;; do nothing for internal messages +() recv_internal(slice in_msg) { + // do nothing for internal messages } -() recv_external(slice in_msg) impure { +() recv_external(slice in_msg) { var signature = in_msg~load_bits(512); var cs = in_msg; var (msg_seqno, valid_until) = (cs~load_uint(32), cs~load_uint(32)); @@ -26,13 +26,13 @@ set_data(begin_cell().store_uint(stored_seqno + 1, 32).store_uint(public_key, 256).end_cell()); } -;; Get methods +// Get methods -int seqno() method_id { +get int seqno() { return get_data().begin_parse().preload_uint(32); } -int get_public_key() method_id { +get int get_public_key() { var cs = get_data().begin_parse(); cs~load_uint(32); return cs.preload_uint(256);