mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Add legacy_tester for existing funC contracts (#588)
* Add legacy_tester for existing funC contracts * Add storage-contracts and pragma options
This commit is contained in:
parent
13b9f460af
commit
6b49d6a382
70 changed files with 14495 additions and 0 deletions
110
crypto/func/auto-tests/legacy_tests/dns-collection/dns-utils.fc
Normal file
110
crypto/func/auto-tests/legacy_tests/dns-collection/dns-utils.fc
Normal file
|
@ -0,0 +1,110 @@
|
|||
const int one_month = 2592000; ;; 1 month in seconds = 60 * 60 * 24 * 30
|
||||
const int one_year = 31622400; ;; 1 year in seconds = 60 * 60 * 24 * 366
|
||||
const int auction_start_time = 1659171600; ;; GMT: Monday, 30 July 2022 г., 09:00:00
|
||||
const int one_ton = 1000000000;
|
||||
const int dns_next_resolver_prefix = 0xba93; ;; dns_next_resolver prefix - https://github.com/ton-blockchain/ton/blob/7e3df93ca2ab336716a230fceb1726d81bac0a06/crypto/block/block.tlb#L819
|
||||
|
||||
const int dns_config_id = 80; ;; dns black list config param; in testnet -80
|
||||
|
||||
const int op::fill_up = 0x370fec51;
|
||||
const int op::outbid_notification = 0x557cea20;
|
||||
const int op::change_dns_record = 0x4eb1f0f9;
|
||||
const int op::process_governance_decision = 0x44beae41;
|
||||
const int op::dns_balance_release = 0x4ed14b65;
|
||||
|
||||
int mod(int x, int y) asm "MOD";
|
||||
|
||||
slice zero_address() {
|
||||
return begin_cell().store_uint(0, 2).end_cell().begin_parse();
|
||||
}
|
||||
|
||||
;; "ton\0test\0" -> "ton"
|
||||
int get_top_domain_bits(slice domain) {
|
||||
int i = 0;
|
||||
int need_break = 0;
|
||||
do {
|
||||
int char = domain~load_uint(8); ;; we do not check domain.length because it MUST contains \0 character
|
||||
need_break = char == 0;
|
||||
if (~ need_break) {
|
||||
i += 8;
|
||||
}
|
||||
} until (need_break);
|
||||
throw_if(201, i == 0); ;; starts with \0
|
||||
return i;
|
||||
}
|
||||
|
||||
slice read_domain_from_comment(slice in_msg_body) {
|
||||
int need_break = 0;
|
||||
builder result = begin_cell();
|
||||
do {
|
||||
result = result.store_slice(in_msg_body~load_bits(in_msg_body.slice_bits()));
|
||||
int refs_len = in_msg_body.slice_refs();
|
||||
need_break = refs_len == 0;
|
||||
if (~ need_break) {
|
||||
throw_unless(202, refs_len == 1);
|
||||
in_msg_body = in_msg_body~load_ref().begin_parse();
|
||||
}
|
||||
} until (need_break);
|
||||
return result.end_cell().begin_parse();
|
||||
}
|
||||
|
||||
int check_domain_string(slice domain) {
|
||||
int i = 0;
|
||||
int len = slice_bits(domain);
|
||||
int need_break = 0;
|
||||
do {
|
||||
need_break = i == len;
|
||||
if (~ need_break) {
|
||||
int char = domain~load_uint(8);
|
||||
;; we can do it because additional UTF-8 character's octets >= 128 -- https://www.ietf.org/rfc/rfc3629.txt
|
||||
int is_hyphen = (char == 45);
|
||||
int valid_char = (is_hyphen & (i > 0) & (i < len - 8)) | ((char >= 48) & (char <= 57)) | ((char >= 97) & (char <= 122)); ;; '-' or 0-9 or a-z
|
||||
|
||||
need_break = ~ valid_char;
|
||||
if (~ need_break) {
|
||||
i += 8;
|
||||
}
|
||||
}
|
||||
} until (need_break);
|
||||
return i == len;
|
||||
}
|
||||
|
||||
(int, int) get_min_price_config(int domain_char_count) {
|
||||
if (domain_char_count == 4) {
|
||||
return (1000, 100);
|
||||
}
|
||||
if (domain_char_count == 5) {
|
||||
return (500, 50);
|
||||
}
|
||||
if (domain_char_count == 6) {
|
||||
return (400, 40);
|
||||
}
|
||||
if (domain_char_count == 7) {
|
||||
return (300, 30);
|
||||
}
|
||||
if (domain_char_count == 8) {
|
||||
return (200, 20);
|
||||
}
|
||||
if (domain_char_count == 9) {
|
||||
return (100, 10);
|
||||
}
|
||||
if (domain_char_count == 10) {
|
||||
return (50, 5);
|
||||
}
|
||||
return (10, 1);
|
||||
}
|
||||
|
||||
int get_min_price(int domain_bits_length, int now_time) {
|
||||
(int start_min_price, int end_min_price) = get_min_price_config(domain_bits_length / 8);
|
||||
start_min_price *= one_ton;
|
||||
end_min_price *= one_ton;
|
||||
int seconds = now_time - auction_start_time;
|
||||
int months = seconds / one_month;
|
||||
if (months > 21) {
|
||||
return end_min_price;
|
||||
}
|
||||
repeat (months) {
|
||||
start_min_price = start_min_price * 90 / 100;
|
||||
}
|
||||
return start_min_price;
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
;; DNS resolver smart contract (implements NFT Collection interface)
|
||||
|
||||
|
||||
#include "stdlib.fc";
|
||||
#include "params.fc";
|
||||
#include "dns-utils.fc";
|
||||
|
||||
;; storage scheme
|
||||
;; storage#_ collection_content:^Cell
|
||||
;; nft_item_code:^Cell
|
||||
;; = Storage;
|
||||
|
||||
(cell, cell) load_data() inline {
|
||||
var ds = get_data().begin_parse();
|
||||
return (
|
||||
ds~load_ref(), ;; content
|
||||
ds~load_ref() ;; nft_item_code
|
||||
);
|
||||
}
|
||||
|
||||
() save_data(cell content, cell nft_item_code) impure inline {
|
||||
set_data(begin_cell()
|
||||
.store_ref(content)
|
||||
.store_ref(nft_item_code)
|
||||
.end_cell());
|
||||
}
|
||||
|
||||
cell calculate_nft_item_state_init(int item_index, cell nft_item_code) {
|
||||
cell data = begin_cell().store_uint(item_index, 256).store_slice(my_address()).end_cell();
|
||||
return begin_cell().store_uint(0, 2).store_dict(nft_item_code).store_dict(data).store_uint(0, 1).end_cell();
|
||||
}
|
||||
|
||||
slice calculate_nft_item_address(int wc, cell state_init) {
|
||||
return begin_cell()
|
||||
.store_uint(4, 3)
|
||||
.store_int(wc, 8)
|
||||
.store_uint(cell_hash(state_init), 256)
|
||||
.end_cell()
|
||||
.begin_parse();
|
||||
}
|
||||
|
||||
() deploy_nft_item(int item_index, cell nft_item_code, cell nft_content) impure {
|
||||
cell state_init = calculate_nft_item_state_init(item_index, nft_item_code);
|
||||
slice nft_address = calculate_nft_item_address(workchain(), state_init);
|
||||
var msg = begin_cell()
|
||||
.store_uint(0x18, 6)
|
||||
.store_slice(nft_address)
|
||||
.store_coins(0)
|
||||
.store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1)
|
||||
.store_ref(state_init)
|
||||
.store_ref(nft_content);
|
||||
send_raw_message(msg.end_cell(), 64); ;; carry all the remaining value of the inbound message, fee deducted from amount
|
||||
}
|
||||
|
||||
() recv_internal(int msg_value, cell in_msg_full, slice in_msg_body) impure {
|
||||
if (in_msg_body.slice_empty?()) { ;; bounce back empty messages
|
||||
throw(0xffff);
|
||||
}
|
||||
slice cs = in_msg_full.begin_parse();
|
||||
int flags = cs~load_uint(4);
|
||||
|
||||
if (flags & 1) { ;; ignore all bounced messages
|
||||
return ();
|
||||
}
|
||||
slice sender_address = cs~load_msg_addr();
|
||||
|
||||
int op = in_msg_body~load_uint(32);
|
||||
|
||||
var (content, nft_item_code) = load_data();
|
||||
|
||||
if (op == 0) { ;; deploy new nft
|
||||
int now_time = now();
|
||||
throw_unless(199, now_time > auction_start_time); ;; start of auction
|
||||
slice domain = read_domain_from_comment(in_msg_body);
|
||||
int len = slice_bits(domain);
|
||||
throw_unless(200, len > 3 * 8); ;; minimum 4 characters
|
||||
throw_unless(201, len <= 126 * 8); ;; maxmimum 126 characters
|
||||
throw_unless(202, mod(len, 8) == 0);
|
||||
throw_unless(203, check_domain_string(domain));
|
||||
int min_price = get_min_price(len, now_time);
|
||||
throw_unless(204, msg_value >= min_price);
|
||||
|
||||
int item_index = slice_hash(domain);
|
||||
|
||||
cell config_cell = config_param(dns_config_id);
|
||||
if (~ cell_null?(config_cell)) {
|
||||
slice config_cs = config_cell.begin_parse();
|
||||
cell config = config_cs~load_dict();
|
||||
(slice config_value, int found) = config.udict_get?(256, item_index);
|
||||
throw_if(205, found);
|
||||
}
|
||||
|
||||
cell nft_content = begin_cell()
|
||||
.store_slice(sender_address)
|
||||
.store_ref(begin_cell().store_slice(domain).end_cell())
|
||||
.end_cell();
|
||||
deploy_nft_item(item_index, nft_item_code, nft_content);
|
||||
return ();
|
||||
}
|
||||
|
||||
if (op == op::fill_up) { ;; just fill-up balance
|
||||
return ();
|
||||
}
|
||||
throw(0xffff);
|
||||
}
|
||||
|
||||
;; Get methods
|
||||
|
||||
(int, cell, slice) get_collection_data() method_id {
|
||||
var (content, nft_item_code) = load_data();
|
||||
return (-1, content, zero_address());
|
||||
}
|
||||
|
||||
slice get_nft_address_by_index(int index) method_id {
|
||||
var (content, nft_item_code) = load_data();
|
||||
cell state_init = calculate_nft_item_state_init(index, nft_item_code);
|
||||
return calculate_nft_item_address(workchain(), state_init);
|
||||
}
|
||||
|
||||
cell get_nft_content(int index, cell individual_nft_content) method_id {
|
||||
return individual_nft_content;
|
||||
}
|
||||
|
||||
(int, cell) dnsresolve(slice subdomain, int category) method_id {
|
||||
throw_unless(70, mod(slice_bits(subdomain), 8) == 0);
|
||||
|
||||
int starts_with_zero_byte = subdomain.preload_int(8) == 0;
|
||||
|
||||
if (starts_with_zero_byte & (slice_bits(subdomain) == 8)) { ;; "." requested
|
||||
return (8, null()); ;; resolved but no dns-records
|
||||
}
|
||||
if (starts_with_zero_byte) {
|
||||
subdomain~load_uint(8);
|
||||
}
|
||||
|
||||
int top_subdomain_bits = get_top_domain_bits(subdomain);
|
||||
slice top_subdomain = subdomain~load_bits(top_subdomain_bits);
|
||||
int item_index = slice_hash(top_subdomain);
|
||||
cell result = begin_cell()
|
||||
.store_uint(dns_next_resolver_prefix, 16)
|
||||
.store_slice(get_nft_address_by_index(item_index))
|
||||
.end_cell();
|
||||
return (top_subdomain_bits + (starts_with_zero_byte ? 8 : 0), result);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
int workchain() asm "0 PUSHINT";
|
||||
|
||||
() force_chain(slice addr) impure {
|
||||
(int wc, _) = parse_std_addr(addr);
|
||||
throw_unless(333, wc == workchain());
|
||||
}
|
216
crypto/func/auto-tests/legacy_tests/dns-collection/stdlib.fc
Normal file
216
crypto/func/auto-tests/legacy_tests/dns-collection/stdlib.fc
Normal file
|
@ -0,0 +1,216 @@
|
|||
;; 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";
|
||||
[int, cell] 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" "NULLSWAPIFNOT";
|
||||
(cell, int) udict_get_ref?(cell dict, int key_len, int index) asm(index dict key_len) "DICTUGETREF" "NULLSWAPIFNOT";
|
||||
(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";
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue