-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathblockchain.func
More file actions
581 lines (508 loc) · 22.3 KB
/
blockchain.func
File metadata and controls
581 lines (508 loc) · 22.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
{-
This file is part of stdlib.func.
It is derived from code originally part of the TON Blockchain project.
stdlib.func is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
stdlib.func is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with stdlib.func (see the file LICENSE.LGPL). If not, see
<https://www.gnu.org/licenses/>. You should also have received a copy of
the GNU General Public License (see the file LICENSE.GPL), which is
referenced by the LGPL.
-}
;; ██████╗ █████╗ ███████╗ ██╗ ███████╗███████╗███████╗███████╗
;; ██╔════╝ ██╔══██╗██╔════╝ ██╔╝ ██╔════╝██╔════╝██╔════╝██╔════╝
;; ██║ ███╗███████║███████╗ ██╔╝ █████╗ █████╗ █████╗ ███████╗
;; ██║ ██║██╔══██║╚════██║ ██╔╝ ██╔══╝ ██╔══╝ ██╔══╝ ╚════██║
;; ╚██████╔╝██║ ██║███████║ ██╔╝ ██║ ███████╗███████╗███████║
;; ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝╚══════╝
;;; Accepts the incoming message, setting the gas limit to its maximum allowed value.
;;; Resets the gas credit to zero, effectively paying for gas consumed so far and ensuring
;;; the transaction has enough gas to proceed. Crucial for processing external messages.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; None
() accept_message() impure asm "ACCEPT";
;;; Sets the gas limit to the minimum of the provided limit and the maximum allowed gas.
;;; Resets the gas credit to zero. Throws an out-of-gas exception if gas consumed already exceeds the new limit.
;;; Note: Using a very large limit (≥ 2^63 - 1) is equivalent to accept_message().
;;;
;;; Args:
;;; limit (int): The desired gas limit.
;;;
;;; Returns:
;;; None
() set_gas_limit(int limit) impure asm "SETGASLIMIT";
;;; Retrieves the current total storage fee collected during the storage phase.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; int: The accumulated storage fees in nanoTONs.
int storage_fees() asm "STORAGEFEES";
;;; Returns the amount of gas consumed by the VM execution up to this point in the current transaction.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; int: Gas consumed so far.
int gas_consumed() asm "GASCONSUMED";
;;; Calculates the computation fee in nanoTONs for a transaction based on gas usage and workchain.
;;; Retrieves pricing data from the blockchain configuration.
;;;
;;; Args:
;;; workchain (int): The workchain ID (0 for basechain, -1 for masterchain).
;;; gas_used (int): The amount of gas consumed.
;;;
;;; Returns:
;;; int: The estimated compute fee in nanoTONs.
int get_compute_fee(int workchain, int gas_used) asm(gas_used workchain) "GETGASFEE";
;;; Calculates the storage fee in nanoTONs based on contract data size and storage duration.
;;; Uses current storage pricing from the blockchain configuration.
;;;
;;; Args:
;;; workchain (int): The workchain ID.
;;; seconds (int): Storage duration in seconds.
;;; bits (int): Total number of bits stored.
;;; cells (int): Total number of cells stored (with deduplication).
;;;
;;; Returns:
;;; int: The estimated storage fee in nanoTONs.
int get_storage_fee(int workchain, int seconds, int bits, int cells) asm(cells bits seconds workchain) "GETSTORAGEFEE";
;;; Calculates the forward fee in nanoTONs for sending a message based on its size.
;;; Considers deduplication and root-is-not-counted rules when measuring message size.
;;;
;;; Args:
;;; workchain (int): The workchain ID (is_mc flag - true if source or destination is in masterchain).
;;; bits (int): Total number of bits in the message.
;;; cells (int): Total number of cells in the message.
;;;
;;; Returns:
;;; int: The estimated forwarding fee in nanoTONs.
int get_forward_fee(int workchain, int bits, int cells) asm(cells bits workchain) "GETFORWARDFEE";
;;; Returns the gas consumed by precompiled/native functions.
;;; Currently returns null. Will return cost of contract execution in gas units if the contract is precompiled.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; int: Gas consumed by precompiled operations or null.
int get_precompiled_gas_consumption() asm "GETPRECOMPILEDGAS";
;;; Calculates the simplified compute fee without the flat price component.
;;; Computes (gas_used * price) / 2^16 for additional gas consumption.
;;;
;;; Args:
;;; workchain (int): The workchain ID.
;;; gas_used (int): The amount of gas consumed.
;;;
;;; Returns:
;;; int: The simplified compute fee in nanoTONs.
int get_simple_compute_fee(int workchain, int gas_used) asm(gas_used workchain) "GETGASFEESIMPLE";
;;; Calculates the simplified forward fee without the lump price component.
;;; Computes (bits*bit_price + cells*cell_price) / 2^16 for additional message size.
;;;
;;; Args:
;;; workchain (int): The workchain ID.
;;; bits (int): Total number of bits in the message.
;;; cells (int): Total number of cells in the message.
;;;
;;; Returns:
;;; int: The simplified forwarding fee in nanoTONs.
int get_simple_forward_fee(int workchain, int bits, int cells) asm(cells bits workchain) "GETFORWARDFEESIMPLE";
;;; Calculates the original forward fee from a potentially modified fee value.
;;; Computes fwd_fee * 2^16 / first_frac to get the original fee from the parsed message fee.
;;;
;;; Args:
;;; workchain (int): The workchain ID.
;;; fwd_fee (int): A forwarding fee value (potentially adjusted).
;;;
;;; Returns:
;;; int: The original forwarding fee in nanoTONs.
int get_original_fwd_fee(int workchain, int fwd_fee) asm(fwd_fee workchain) "GETORIGINALFWDFEE";
;;; Retrieves the amount currently due for contract storage payment.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; int: Amount due for storage in nanoTONs.
int my_storage_due() asm "DUEPAYMENT";
;;; Returns a tuple containing various fee-related configuration parameters from the blockchain config.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; tuple: A tuple holding fee configuration parameters.
tuple get_fee_configs() asm "UNPACKEDCONFIGTUPLE";
;; ██████╗ ██████╗ ███╗ ██╗███████╗██╗ ██████╗
;; ██╔════╝██╔═══██╗████╗ ██║██╔════╝██║██╔════╝
;; ██║ ██║ ██║██╔██╗ ██║█████╗ ██║██║ ███╗
;; ██║ ██║ ██║██║╚██╗██║██╔══╝ ██║██║ ██║
;; ╚██████╗╚██████╔╝██║ ╚████║██║ ██║╚██████╔╝
;; ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═════╝
;;; Returns the Unix timestamp of the current block.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; int: Current block's Unix timestamp.
int now() asm "NOW";
;;; Returns the logical time (lt) of the current block's begin time.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; int: Logical time of the block start.
int block_lt() asm "BLOCKLT";
;;; Returns the logical time (lt) of the current transaction.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; int: Logical time of the transaction.
int cur_lt() asm "LTIME";
;;; Returns the current balance of the smart contract in nanoTONs and a dictionary of extra currency balances.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; [int, cell]:
;;; int: Balance in nanoTONs.
;;; cell: Dictionary mapping currency IDs to balances.
[int, cell] get_balance() asm "BALANCE";
;;; Returns only the nanoTON balance of the smart contract.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; int: Balance in nanoTONs.
int get_ton_balance() asm "BALANCE FIRST";
;;; Returns the balance of a specific extra currency held by the contract.
;;;
;;; Args:
;;; id (int): The ID of the extra currency.
;;;
;;; Returns:
;;; int: Balance of the specified extra currency.
int get_extra_balance(int id) asm "GETEXTRABALANCE";
;;; Returns the internal address of the current smart contract as a slice.
;;; Can be further parsed using functions like parse_std_addr.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; slice: The contract's address slice.
slice my_address() asm "MYADDR";
;;; Returns the code cell of the current smart contract.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; cell: The contract's code cell.
cell my_code() asm "MYCODE";
;;; Returns information about previous blocks in the shardchain and masterchain.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; [tuple, tuple]:
;;; tuple: Tuple containing last_mc_blocks (last 16 masterchain blocks).
;;; tuple: Tuple containing prev_key_block information.
[tuple, tuple] get_prev_blocks() asm "PREVBLOCKSINFOTUPLE";
;;; Returns a tuple containing information about the last 16 masterchain blocks.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; tuple: Tuple with info on the last 16 MC blocks.
tuple get_last_mc_blocks() asm "PREVMCBLOCKS";
;;; Returns a tuple containing information about the last 100 masterchain blocks.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; tuple: Tuple with info on the last 100 MC blocks.
tuple get_last_mc_blocks_100() asm "PREVMCBLOCKS_100";
;;; Returns a tuple containing information about the previous key block in the masterchain.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; tuple: Tuple with info on the previous key block.
tuple get_prev_key_block() asm "PREVKEYBLOCK";
;;; Unpacks a BlockId tuple into individual integer components.
;;; The tuple is unpacked due to how FunC handles tuple assignments.
;;;
;;; Args:
;;; block_id (tuple): A tuple representing a BlockId.
;;;
;;; Returns:
;;; [int, int, int, int, int]:
;;; int: Workchain ID.
;;; int: Shard ID.
;;; int: Block sequence number.
;;; int: Root hash (uint256).
;;; int: File hash (uint256).
[int, int, int, int, int] unpack_block_id(tuple block_id) asm "NOP"; ;; Renamed return type to match common usage
;;; Returns the current global ID of the blockchain network.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; int: The global ID.
int global_id() asm "GLOBALID";
;;; Retrieves a specific configuration parameter from the blockchain's global configuration.
;;; Returns the parameter's value as a cell, or null if the parameter doesn't exist.
;;;
;;; Args:
;;; x (int): The integer ID of the configuration parameter.
;;;
;;; Returns:
;;; cell: The cell containing the parameter's value, or null.
cell config_param(int x) asm "CONFIGOPTPARAM";
;; ██████╗ ███████╗ ██████╗ ██╗███████╗████████╗███████╗██████╗ ███████╗
;; ██╔══██╗██╔════╝██╔════╝ ██║██╔════╝╚══██╔══╝██╔════╝██╔══██╗██╔════╝
;; ██████╔╝█████╗ ██║ ███╗██║███████╗ ██║ █████╗ ██████╔╝███████╗
;; ██╔══██╗██╔══╝ ██║ ██║██║╚════██║ ██║ ██╔══╝ ██╔══██╗╚════██║
;; ██║ ██║███████╗╚██████╔╝██║███████║ ██║ ███████╗██║ ██║███████║
;; ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝╚══════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚══════╝
;;; Returns the current exception handler continuation stored in register c2.
;;; The handler is a function of type ((int, int) -> ()).
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; ((int, int) -> ()): The exception handler continuation.
((int, int) -> ()) get_exception_handler() asm "c2 PUSH";
;;; Sets the exception handler continuation in register c2.
;;; The handler will be called if an exception occurs.
;;;
;;; Args:
;;; c (((int, int) -> ())): The continuation to set as the exception handler.
;;;
;;; Returns:
;;; None
() set_exception_handler(((int, int) -> ()) c) impure asm "c2 POP";
;;; Returns the current continuation stored in register c3.
;;; c3 usually holds the main code of the contract and is used for function calls.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; cont: The continuation from register c3.
cont get_c3() asm "c3 PUSH";
;;; Sets the continuation in register c3.
;;; Can be used to update the smart contract code dynamically during runtime.
;;; Subsequent function calls will use the code from the new continuation.
;;;
;;; Args:
;;; c (cont): The new continuation to set in c3.
;;;
;;; Returns:
;;; None
() set_c3(cont c) impure asm "c3 POP";
;;; Returns the persistent data cell of the smart contract, stored in register c4.
;;; This cell holds the contract's state between transactions.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; cell: The persistent data cell from register c4.
cell get_data() asm "c4 PUSH";
;;; Sets the persistent data cell of the smart contract in register c4.
;;; This updates the contract's state.
;;;
;;; Args:
;;; c (cell): The new data cell to store in c4.
;;;
;;; Returns:
;;; None
() set_data(cell c) impure asm "c4 POP";
;;; Stores the provided cell into register c5, which holds the list of outgoing actions (messages).
;;;
;;; Args:
;;; actions (cell): The cell containing the list of actions.
;;;
;;; Returns:
;;; None
() set_actions(cell actions) impure asm "c5 POP";
;;; Clears the list of outgoing actions by storing an empty cell into register c5.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; None
() clean_actions() impure asm "<b b> PUSHREF c5 POP";
;;; Creates an output action to change the smart contract's code.
;;; The change takes effect after the current transaction successfully finishes.
;;;
;;; Args:
;;; new_code (cell): The cell containing the new contract code.
;;;
;;; Returns:
;;; None
() set_code(cell new_code) impure asm "SETCODE";
;;; Creates an output action to modify the smart contract's library collection.
;;; It can add or remove a library specified by the code cell.
;;;
;;; Args:
;;; code (cell): The cell containing the library code.
;;; mode (int): Operation mode: 0=remove, 1=add private, 2=add public.
;;;
;;; Returns:
;;; None
() set_library(cell code, int mode) impure asm "SETLIBCODE";
;;; Commits the current state of registers c4 (persistent data) and c5 (actions).
;;; This makes the current execution state considered successful, even if an exception
;;; is thrown later in the computation phase. The saved state will be used.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; None
() commit() impure asm "COMMIT";
;; ██████╗ █████╗ ███╗ ██╗██████╗ ██████╗ ███╗ ███╗
;; ██╔══██╗██╔══██╗████╗ ██║██╔══██╗██╔═══██╗████╗ ████║
;; ██████╔╝███████║██╔██╗ ██║██║ ██║██║ ██║██╔████╔██║
;; ██╔══██╗██╔══██║██║╚██╗██║██║ ██║██║ ██║██║╚██╔╝██║
;; ██║ ██║██║ ██║██║ ╚████║██████╔╝╚██████╔╝██║ ╚═╝ ██║
;; ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═════╝ ╚═════╝ ╚═╝ ╚═╝
;;; Generates a pseudo-random unsigned 256-bit integer.
;;; Uses the current random seed, computes its SHA512 hash,
;;; updates the seed with the first 256 bits of the hash, and returns the last 256 bits.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; int: A pseudo-random uint256.
int random() asm "RANDU256";
;;; Generates a pseudo-random integer within the specified range [0, range-1] (or [range, -1] if range < 0).
;;; It generates a random uint256 and computes z = floor(x * range / 2^256).
;;;
;;; Args:
;;; range (int): The upper bound (exclusive if positive) or lower bound (inclusive if negative).
;;;
;;; Returns:
;;; int: A pseudo-random integer in the specified range.
int rand(int range) asm "RAND";
;;; Returns the current value of the pseudo-random number generator seed (an unsigned 256-bit integer).
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; int: The current random seed (uint256).
int get_seed() asm "RANDSEED";
;;; Sets the pseudo-random number generator seed to the provided unsigned 256-bit integer.
;;;
;;; Args:
;;; seed (int): The new seed value (uint256).
;;;
;;; Returns:
;;; None
() set_seed(int seed) impure asm "SETRAND";
;;; Mixes an unsigned 256-bit integer into the random seed.
;;; The new seed becomes sha256(old_seed || x).
;;;
;;; Args:
;;; x (int): The integer value (uint256) to mix into the seed.
;;;
;;; Returns:
;;; None
() randomize(int x) impure asm "ADDRAND";
;;; Mixes the current transaction's logical time into the random seed.
;;; Useful for ensuring different random sequences across different transactions within the same block.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; None
() randomize_lt() impure asm "LTIME ADDRAND";
;; ██████╗ ██████╗ ███╗ ██╗████████╗██████╗ ██████╗ ██╗ ███████╗██╗ ██████╗ ██╗ ██╗
;; ██╔════╝██╔═══██╗████╗ ██║╚══██╔══╝██╔══██╗██╔═══██╗██║ ██╔════╝██║ ██╔═══██╗██║ ██║
;; ██║ ██║ ██║██╔██╗ ██║ ██║ ██████╔╝██║ ██║██║ █████╗ ██║ ██║ ██║██║ █╗ ██║
;; ██║ ██║ ██║██║╚██╗██║ ██║ ██╔══██╗██║ ██║██║ ██╔══╝ ██║ ██║ ██║██║███╗██║
;; ╚██████╗╚██████╔╝██║ ╚████║ ██║ ██║ ██║╚██████╔╝███████╗ ██║ ███████╗╚██████╔╝╚███╔███╔╝
;; ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚═╝ ╚══════╝ ╚═════╝ ╚══╝╚══╝
;;; Transforms a slice into a simple ordinary continuation.
;;; The continuation's code becomes the slice, and its stack and savelist are empty.
;;;
;;; Args:
;;; s (slice): The slice containing the code for the new continuation.
;;;
;;; Returns:
;;; cont: The newly created continuation.
cont bless(slice s) impure asm "BLESS";
;; ██████╗ ███████╗██████╗ ██╗ ██╗ ██████╗
;; ██╔══██╗██╔════╝██╔══██╗██║ ██║██╔════╝
;; ██║ ██║█████╗ ██████╔╝██║ ██║██║ ███╗
;; ██║ ██║██╔══╝ ██╔══██╗██║ ██║██║ ██║
;; ██████╔╝███████╗██████╔╝╚██████╔╝╚██████╔╝
;; ╚═════╝ ╚══════╝╚═════╝ ╚═════╝ ╚═════╝
;;; Dumps the current state of the TVM stack to the debug log.
;;; Shows at most the top 255 values and the total stack depth.
;;; This is a debug primitive and does nothing in production versions of TVM.
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; None
() dump_stack() impure asm "DUMPSTK";
;; ███████╗██╗ ██╗████████╗██████╗ █████╗
;; ██╔════╝╚██╗██╔╝╚══██╔══╝██╔══██╗██╔══██╗
;; █████╗ ╚███╔╝ ██║ ██████╔╝███████║
;; ██╔══╝ ██╔██╗ ██║ ██╔══██╗██╔══██║
;; ███████╗██╔╝ ██╗ ██║ ██║ ██║██║ ██║
;; ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝
;;; Pushes the unique value null of TVM type Null onto the stack.
;;; null is often used to represent absence of value or empty structures (like dictionaries).
;;;
;;; Args:
;;; None
;;;
;;; Returns:
;;; X: The null value (represented generically as type X).
forall X -> X null() asm "PUSHNULL";
;;; Marks a variable as "used" to prevent the compiler from optimizing away the code
;;; that produces it, even if the variable itself isn't directly used later.
;;; Useful for ensuring side effects of impure functions are not discarded.
;;; Returns the original value to allow chaining operations.
;;;
;;; Args:
;;; x (X): The variable to touch (can be of any type X).
;;;
;;; Returns:
;;; X: The original value.
forall X -> (X, ()) ~impure_touch(X x) impure asm "NOP";