From f92c266347bb23b3513cdb42be55239fc4c5185c Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:51:17 +0200 Subject: [PATCH] feat(docs): `Builder.storeMaybeRef`, `parseStdAddress` and `parseVarAddress` (#950) --- CHANGELOG.md | 2 +- docs/src/content/docs/ref/core-advanced.mdx | 80 ++++++++++++++++ docs/src/content/docs/ref/core-cells.mdx | 35 +++++++ src/imports/stdlib.ts | 101 +++++++++++++------- stdlib/std/cells.tact | 20 +++- stdlib/std/contract.tact | 50 +++++++++- 6 files changed, 250 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed59a4c82..79e411b99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,7 +71,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `asm` bodies for module-level functions: PR [#769](https://github.com/tact-lang/tact/pull/769), PR [#825](https://github.com/tact-lang/tact/pull/825) - Corresponding stdlib functions for new TVM instructions from 2023.07 and 2024.04 upgrades: PR [#331](https://github.com/tact-lang/tact/pull/331). Added the `storeBuilder` extension function and `gasConsumed`, `getComputeFee`, `getStorageFee`, `getForwardFee`, `getSimpleComputeFee`, `getSimpleForwardFee`, `getOriginalFwdFee`, `myStorageDue` functions. - `slice`, `rawSlice`, `ascii` and `crc32` built-in functions: PR [#787](https://github.com/tact-lang/tact/pull/787), PR [#799](https://github.com/tact-lang/tact/pull/799) -- `Builder.storeMaybeRef`, `parseStdAddress` and `parseVarAddress` stdlib functions: PR [#793](https://github.com/tact-lang/tact/pull/793) +- `Builder.storeMaybeRef`, `parseStdAddress` and `parseVarAddress` stdlib functions: PR [#793](https://github.com/tact-lang/tact/pull/793), PR [#950](https://github.com/tact-lang/tact/pull/950) - The compiler development guide: PR [#833](https://github.com/tact-lang/tact/pull/833) - Constant evaluator now uses an interpreter: PR [#664](https://github.com/tact-lang/tact/pull/664). This allows calls to user-defined functions and references to declared global constants. diff --git a/docs/src/content/docs/ref/core-advanced.mdx b/docs/src/content/docs/ref/core-advanced.mdx index e52ba2aad..8bbdcd726 100644 --- a/docs/src/content/docs/ref/core-advanced.mdx +++ b/docs/src/content/docs/ref/core-advanced.mdx @@ -3,6 +3,8 @@ title: Advanced description: "Advanced, niche or dangerous functions from the Core library of Tact" --- +import { Badge } from '@astrojs/starlight/components'; + Various niche, dangerous or unstable features which can produce unexpected results and are meant to be used by the more experienced users. :::caution @@ -251,6 +253,84 @@ nativeReserve(ton("0.1"), ReserveExact | ReserveBounceIfActionFail); // amount of nanoToncoins to reserve ``` +## parseStdAddress + +

+ +```tact +fun parseStdAddress(slice: Slice): StdAddress; +``` + +Converts a [`Slice{:tact}`][slice] containing an address into the `StdAddress{:tact}` [Struct][s] and returns it. The `StdAddress{:tact}` is a built-in [Struct][s] that consists of: + +Field | Type | Description +:---------- | :----------------------------- | :---------- +`workchain` | [`Int as int8{:tact}`][int] | Workchain ID of the address, usually $0$ (basechain) or $-1$ (masterchain) +`address` | [`Int as uint256{:tact}`][int] | Address in the specified `workchain` + +Attempts to pass a [`Slice{:tact}`][slice] with layout different from the `StdAddress{:tact}` or to load more data than a given [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. + +Usage example: + +```tact +let addr = address("EQDtFpEwcFAEcRe5mLVh2N6C0x-_hJEM7W61_JLnSF74p4q2"); +let parsedAddr = parseStdAddress(addr.asSlice()); + +parsedAddr.workchain; // 0 +parsedAddr.address; // 107...lots of digits...287 + +// Using newAddress() function with the contents of StdAddress will yield the initial Address: +let addr2: Address = newAddress(parsedAddr.workchain, parsedAddr.address); +addr2 == addr; // true +``` + +:::note + + For parsing addresses of variable length, see the [`parseVarAddress(){:tact}`](#parsevaraddress) function. + +::: + +## parseVarAddress + +

+ +```tact +fun parseVarAddress(slice: Slice): VarAddress; +``` + +Converts a [`Slice{:tact}`][slice] containing an address of variable length into the `VarAddress{:tact}` [Struct][s] and returns it. The `VarAddress{:tact}` is a built-in [Struct][s] consisting of: + +Field | Type | Description +:---------- | :--------------------------- | :---------- +`workchain` | [`Int as int32{:tact}`][int] | Workchain ID of the variable length address +`address` | [`Slice{:tact}`][slice] | Address in the specified `workchain` + +Attempts to pass a [`Slice{:tact}`][slice] with layout different from the `VarAddress{:tact}` or to load more data than a given [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. + +Usage example: + +```tact +let varAddrSlice = beginCell() + .storeUint(6, 3) // to recognize the following as a VarAddress + .storeUint(123, 9) // make address occupy 123 bits + .storeUint(234, 32) // specify workchain ID of 234 + .storeUint(345, 123) // specify address of 345 + .asSlice(); +let parsedVarAddr = parseVarAddress(varAddrSlice); + +parsedVarAddr.workchain; // 234 +parsedVarAddr.address; // CS{Cell{002...2b3} bits: 44..167; refs: 0..0} +parsedVarAddr.address.loadUint(123); // 345 +``` + +:::caution + + Variable-length addresses are intended for future extensions, and while validators must be ready to accept them in inbound messages, the standard (non-variable) addresses are used whenever possible. + +::: + [p]: /book/types#primitive-types [bool]: /book/types#booleans [int]: /book/integers +[slice]: /book/cells#slices +[s]: /book/structs-and-messages#structs diff --git a/docs/src/content/docs/ref/core-cells.mdx b/docs/src/content/docs/ref/core-cells.mdx index 7b8e3309f..c4e051ec6 100644 --- a/docs/src/content/docs/ref/core-cells.mdx +++ b/docs/src/content/docs/ref/core-cells.mdx @@ -3,6 +3,8 @@ title: Cells, Builders and Slices description: "Various Cell, Builder and Slice functions from the Core library of Tact" --- +import { Badge } from '@astrojs/starlight/components'; + [`Cell{:tact}`][cell] is a low-level [primitive][p] that represents data in TON Blockchain. Cells consist of $1023$ bits of data with up to $4$ references to another cells. They are read-only and immutable, and cannot have cyclic references. [`Builder{:tact}`][builder] is an immutable [primitive][p] to construct cells, and [`Slice{:tact}`][slice] is a mutable [primitive][p] to parse them. @@ -191,6 +193,8 @@ let buzz: Builder = b.storeBool(false); // writes 0 ## Builder.storeBit +

+ ```tact extends fun storeBit(self: Builder, value: Bool): Builder; ``` @@ -286,6 +290,31 @@ let b: Builder = beginCell(); let fizz: Builder = b.storeRef(emptyCell()); ``` +## Builder.storeMaybeRef + +

+ +```tact +extends fun storeMaybeRef(self: Builder, cell: Cell?): Builder; +``` + +Extension function for the [`Builder{:tact}`][builder]. + +If the `cell` is not `null{:tact}`, stores $1$ as a single bit and then reference `cell` into the copy of the [`Builder{:tact}`][builder]. Returns that copy. + +If the `cell` is `null{:tact}`, only stores $0$ as a single bit into the copy of the [`Builder{:tact}`][builder]. Returns that copy. + +As a single [`Cell{:tact}`][cell] can store up to $4$ references, attempts to store more throw an exception with [exit code 8](/book/exit-codes#8): `Cell overflow`. + +Usage example: + +```tact +let b: Builder = beginCell(); +let fizz: Builder = b + .storeMaybeRef(emptyCell()) // stores a single 1 bit, then an empty cell + .storeMaybeRef(null); // stores only a single 0 bit +``` + ## Builder.refs ```tact @@ -525,6 +554,8 @@ let fizz: Bool = s.loadBool(); // true ## Slice.loadBit +

+ ```tact extends mutates fun loadBit(self: Slice): Bool; ``` @@ -817,6 +848,8 @@ fun coinCell(): Cell { ## Struct.toSlice +

+ ```tact extends fun toSlice(self: Struct): Slice; ``` @@ -939,6 +972,8 @@ fun coinCell(): Cell { ## Message.toSlice +

+ ```tact extends fun toSlice(self: Message): Slice; ``` diff --git a/src/imports/stdlib.ts b/src/imports/stdlib.ts index d4f5b8d91..c50def19b 100644 --- a/src/imports/stdlib.ts +++ b/src/imports/stdlib.ts @@ -136,37 +136,45 @@ files['std/cells.tact'] = 'eyBTVFZBUlVJTlQxNiB9Cgphc20oY2VsbCBzZWxmKSBleHRlbmRzIGZ1biBzdG9yZVJlZihzZWxmOiBCdWlsZGVyLCBjZWxsOiBDZWxsKTogQnVpbGRlciB7IFNUUkVG' + 'IH0KCmFzbSBleHRlbmRzIGZ1biBzdG9yZVNsaWNlKHNlbGY6IEJ1aWxkZXIsIGNlbGw6IFNsaWNlKTogQnVpbGRlciB7IFNUU0xJQ0VSIH0KCmFzbSBleHRlbmRzIGZ1' + 'biBzdG9yZUJ1aWxkZXIoc2VsZjogQnVpbGRlciwgY2VsbDogQnVpbGRlcik6IEJ1aWxkZXIgeyBTVEJSIH0KCkBuYW1lKF9fdGFjdF9zdG9yZV9hZGRyZXNzKQpleHRl' + - 'bmRzIG5hdGl2ZSBzdG9yZUFkZHJlc3Moc2VsZjogQnVpbGRlciwgYWRkcmVzczogQWRkcmVzcyk6IEJ1aWxkZXI7Cgphc20oY2VsbCBzZWxmKSBleHRlbmRzIGZ1biBz' + - 'dG9yZU1heWJlUmVmKHNlbGY6IEJ1aWxkZXIsIGNlbGw6IENlbGw/KTogQnVpbGRlciB7IFNUT1BUUkVGIH0KCmFzbSBleHRlbmRzIGZ1biBlbmRDZWxsKHNlbGY6IEJ1' + - 'aWxkZXIpOiBDZWxsIHsgRU5EQyB9Cgphc20gZXh0ZW5kcyBmdW4gcmVmcyhzZWxmOiBCdWlsZGVyKTogSW50IHsgQlJFRlMgfQoKYXNtIGV4dGVuZHMgZnVuIGJpdHMo' + - 'c2VsZjogQnVpbGRlcik6IEludCB7IEJCSVRTIH0KCi8vCi8vIFNsaWNlCi8vCgphc20gZXh0ZW5kcyBmdW4gYmVnaW5QYXJzZShzZWxmOiBDZWxsKTogU2xpY2UgeyBD' + - 'VE9TIH0KCmFzbSgtPiAxIDApIGV4dGVuZHMgbXV0YXRlcyBmdW4gbG9hZFJlZihzZWxmOiBTbGljZSk6IENlbGwgeyBMRFJFRiB9Cgphc20gZXh0ZW5kcyBmdW4gcHJl' + - 'bG9hZFJlZihzZWxmOiBTbGljZSk6IENlbGwgeyBQTERSRUYgfQoKLy8gc3BlY2lhbCB0cmVhdG1lbnQgaW4gRnVuYyBjb21waWxlciwgc28gbm90IHJlcGxhY2VkIHdp' + - 'dGggYXNtICJMRFNMSUNFWCIKQG5hbWUobG9hZF9iaXRzKQpleHRlbmRzIG11dGF0ZXMgbmF0aXZlIGxvYWRCaXRzKHNlbGY6IFNsaWNlLCBsOiBJbnQpOiBTbGljZTsK' + - 'Ci8vIHNwZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIsIHNvIG5vdCByZXBsYWNlZCB3aXRoIGFzbSAiUExEU0xJQ0VYIgpAbmFtZShwcmVsb2FkX2JpdHMp' + - 'CmV4dGVuZHMgbmF0aXZlIHByZWxvYWRCaXRzKHNlbGY6IFNsaWNlLCBsOiBJbnQpOiBTbGljZTsKCi8vIHNwZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIs' + - 'IHNvIG5vdCByZXBsYWNlZCB3aXRoIGFzbSAiTERJWCIKQG5hbWUobG9hZF9pbnQpCmV4dGVuZHMgbXV0YXRlcyBuYXRpdmUgbG9hZEludChzZWxmOiBTbGljZSwgbDog' + - 'SW50KTogSW50OwoKLy8gc3BlY2lhbCB0cmVhdG1lbnQgaW4gRnVuYyBjb21waWxlciwgc28gbm90IHJlcGxhY2VkIHdpdGggYXNtICJQTERJWCIKQG5hbWUocHJlbG9h' + - 'ZF9pbnQpCmV4dGVuZHMgbmF0aXZlIHByZWxvYWRJbnQoc2VsZjogU2xpY2UsIGw6IEludCk6IEludDsKCi8vIHNwZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGls' + - 'ZXIsIHNvIG5vdCByZXBsYWNlZCB3aXRoIGFzbSAiTERVWCIKQG5hbWUobG9hZF91aW50KQpleHRlbmRzIG11dGF0ZXMgbmF0aXZlIGxvYWRVaW50KHNlbGY6IFNsaWNl' + - 'LCBsOiBJbnQpOiBJbnQ7CgovLyBzcGVjaWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBpbGVyLCBzbyBub3QgcmVwbGFjZWQgd2l0aCBhc20gIlBMRFVYIgpAbmFtZShw' + - 'cmVsb2FkX3VpbnQpCmV4dGVuZHMgbmF0aXZlIHByZWxvYWRVaW50KHNlbGY6IFNsaWNlLCBsOiBJbnQpOiBJbnQ7Cgphc20oLT4gMSAwKSBleHRlbmRzIG11dGF0ZXMg' + - 'ZnVuIGxvYWRCb29sKHNlbGY6IFNsaWNlKTogQm9vbCB7IDEgTERJIH0KCi8vLyBFeHRlbnNpb24gbXV0YXRpb24gZnVuY3Rpb24gZm9yIHRoZSBgU2xpY2VgLiBBbGlh' + - 'cyB0byBgU2xpY2UubG9hZEJvb2woKWAuCi8vLwovLy8gYGBgdGFjdAovLy8gbGV0IHM6IFNsaWNlID0gYmVnaW5DZWxsKCkuc3RvcmVCb29sKHRydWUpLmFzU2xpY2Uo' + - 'KTsKLy8vIGxldCBmaXp6OiBCb29sID0gcy5sb2FkQml0KCk7IC8vIHRydWUKLy8vIGBgYAovLy8KLy8vIEBzaW5jZSBUYWN0IDEuNS4wCi8vLyBAc2VlIGh0dHBzOi8v' + - 'ZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNlbGxzI3NsaWNlbG9hZGJpdAovLy8KYXNtKC0+IDEgMCkgZXh0ZW5kcyBtdXRhdGVzIGZ1biBsb2FkQml0KHNlbGY6' + - 'IFNsaWNlKTogQm9vbCB7IDEgTERJIH0KCmFzbSggLT4gMSAwKSBleHRlbmRzIG11dGF0ZXMgZnVuIGxvYWRDb2lucyhzZWxmOiBTbGljZSk6IEludCB7IExEVkFSVUlO' + - 'VDE2IH0KCkBuYW1lKF9fdGFjdF9sb2FkX2FkZHJlc3MpCmV4dGVuZHMgbXV0YXRlcyBuYXRpdmUgbG9hZEFkZHJlc3Moc2VsZjogU2xpY2UpOiBBZGRyZXNzOwoKYXNt' + - 'IGV4dGVuZHMgbXV0YXRlcyBmdW4gc2tpcEJpdHMoc2VsZjogU2xpY2UsIGw6IEludCkgeyBTRFNLSVBGSVJTVCB9Cgphc20gZXh0ZW5kcyBmdW4gZW5kUGFyc2Uoc2Vs' + - 'ZjogU2xpY2UpIHsgRU5EUyB9CgovLwovLyBTbGljZSBzaXplCi8vCgphc20gZXh0ZW5kcyBmdW4gcmVmcyhzZWxmOiBTbGljZSk6IEludCB7IFNSRUZTIH0KCmFzbSBl' + - 'eHRlbmRzIGZ1biBiaXRzKHNlbGY6IFNsaWNlKTogSW50IHsgU0JJVFMgfQoKYXNtIGV4dGVuZHMgZnVuIGVtcHR5KHNlbGY6IFNsaWNlKTogQm9vbCB7IFNFTVBUWSB9' + - 'Cgphc20gZXh0ZW5kcyBmdW4gZGF0YUVtcHR5KHNlbGY6IFNsaWNlKTogQm9vbCB7IFNERU1QVFkgfQoKYXNtIGV4dGVuZHMgZnVuIHJlZnNFbXB0eShzZWxmOiBTbGlj' + - 'ZSk6IEJvb2wgeyBTUkVNUFRZIH0KCi8vCi8vIENvbnZlcnNpb25zCi8vCgppbmxpbmUgZXh0ZW5kcyBmdW4gYXNTbGljZShzZWxmOiBCdWlsZGVyKTogU2xpY2Ugewog' + - 'ICAgcmV0dXJuIHNlbGYuZW5kQ2VsbCgpLmJlZ2luUGFyc2UoKTsKfQoKaW5saW5lIGV4dGVuZHMgZnVuIGFzU2xpY2Uoc2VsZjogQ2VsbCk6IFNsaWNlIHsKICAgIHJl' + - 'dHVybiBzZWxmLmJlZ2luUGFyc2UoKTsKfQoKaW5saW5lIGV4dGVuZHMgZnVuIGFzQ2VsbChzZWxmOiBTbGljZSk6IENlbGwgewogICAgcmV0dXJuIGJlZ2luQ2VsbCgp' + - 'CiAgICAgICAgLnN0b3JlU2xpY2Uoc2VsZikKICAgICAgICAuZW5kQ2VsbCgpOwp9CgppbmxpbmUgZXh0ZW5kcyBmdW4gYXNDZWxsKHNlbGY6IEJ1aWxkZXIpOiBDZWxs' + - 'IHsKICAgIHJldHVybiBzZWxmLmVuZENlbGwoKTsKfQoKaW5saW5lIGZ1biBlbXB0eUNlbGwoKTogQ2VsbCB7CiAgICByZXR1cm4gYmVnaW5DZWxsKCkuZW5kQ2VsbCgp' + - 'Owp9CgppbmxpbmUgZnVuIGVtcHR5U2xpY2UoKTogU2xpY2UgewogICAgcmV0dXJuIGVtcHR5Q2VsbCgpLmFzU2xpY2UoKTsKfQ=='; + 'bmRzIG5hdGl2ZSBzdG9yZUFkZHJlc3Moc2VsZjogQnVpbGRlciwgYWRkcmVzczogQWRkcmVzcyk6IEJ1aWxkZXI7CgovLy8gRXh0ZW5zaW9uIGZ1bmN0aW9uIGZvciB0' + + 'aGUgYEJ1aWxkZXJgLgovLy8KLy8vIElmIHRoZSBgY2VsbGAgaXMgbm90IGBudWxsYCwgc3RvcmVzIDEgYXMgYSBzaW5nbGUgYml0IGFuZCB0aGVuIHJlZmVyZW5jZSBg' + + 'Y2VsbGAgaW50byB0aGUgY29weSBvZiB0aGUgYEJ1aWxkZXJgLiBSZXR1cm5zIHRoYXQgY29weS4KLy8vCi8vLyBJZiB0aGUgYGNlbGxgIGlzIGBudWxsYCwgb25seSBz' + + 'dG9yZXMgMCBhcyBhIHNpbmdsZSBiaXQgaW50byB0aGUgY29weSBvZiB0aGUgYEJ1aWxkZXJgLiBSZXR1cm5zIHRoYXQgY29weS4KLy8vCi8vLyBBcyBhIHNpbmdsZSBg' + + 'Q2VsbGAgY2FuIHN0b3JlIHVwIHRvIDQgcmVmZXJlbmNlcywgYXR0ZW1wdHMgdG8gc3RvcmUgbW9yZSB0aHJvdyBhbiBleGNlcHRpb24gd2l0aCBleGl0IGNvZGUgODog' + + 'YENlbGwgb3ZlcmZsb3dgLgovLy8KLy8vIGBgYHRhY3QKLy8vIGxldCBiOiBCdWlsZGVyID0gYmVnaW5DZWxsKCk7Ci8vLyBsZXQgZml6ejogQnVpbGRlciA9IGIKLy8v' + + 'ICAgICAuc3RvcmVNYXliZVJlZihlbXB0eUNlbGwoKSkgLy8gMSwgdGhlbiBlbXB0eSBjZWxsCi8vLyAgICAgLnN0b3JlTWF5YmVSZWYobnVsbCk7ICAgICAgIC8vIDAK' + + 'Ly8vIGBgYAovLy8KLy8vIEBzaW5jZSBUYWN0IDEuNS4wCi8vLyBAc2VlIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNlbGxzI2J1aWxkZXJzdG9y' + + 'ZW1heWJlcmVmCi8vLwphc20oY2VsbCBzZWxmKSBleHRlbmRzIGZ1biBzdG9yZU1heWJlUmVmKHNlbGY6IEJ1aWxkZXIsIGNlbGw6IENlbGw/KTogQnVpbGRlciB7IFNU' + + 'T1BUUkVGIH0KCmFzbSBleHRlbmRzIGZ1biBlbmRDZWxsKHNlbGY6IEJ1aWxkZXIpOiBDZWxsIHsgRU5EQyB9Cgphc20gZXh0ZW5kcyBmdW4gcmVmcyhzZWxmOiBCdWls' + + 'ZGVyKTogSW50IHsgQlJFRlMgfQoKYXNtIGV4dGVuZHMgZnVuIGJpdHMoc2VsZjogQnVpbGRlcik6IEludCB7IEJCSVRTIH0KCi8vCi8vIFNsaWNlCi8vCgphc20gZXh0' + + 'ZW5kcyBmdW4gYmVnaW5QYXJzZShzZWxmOiBDZWxsKTogU2xpY2UgeyBDVE9TIH0KCmFzbSgtPiAxIDApIGV4dGVuZHMgbXV0YXRlcyBmdW4gbG9hZFJlZihzZWxmOiBT' + + 'bGljZSk6IENlbGwgeyBMRFJFRiB9Cgphc20gZXh0ZW5kcyBmdW4gcHJlbG9hZFJlZihzZWxmOiBTbGljZSk6IENlbGwgeyBQTERSRUYgfQoKLy8gc3BlY2lhbCB0cmVh' + + 'dG1lbnQgaW4gRnVuYyBjb21waWxlciwgc28gbm90IHJlcGxhY2VkIHdpdGggYXNtICJMRFNMSUNFWCIKQG5hbWUobG9hZF9iaXRzKQpleHRlbmRzIG11dGF0ZXMgbmF0' + + 'aXZlIGxvYWRCaXRzKHNlbGY6IFNsaWNlLCBsOiBJbnQpOiBTbGljZTsKCi8vIHNwZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIsIHNvIG5vdCByZXBsYWNl' + + 'ZCB3aXRoIGFzbSAiUExEU0xJQ0VYIgpAbmFtZShwcmVsb2FkX2JpdHMpCmV4dGVuZHMgbmF0aXZlIHByZWxvYWRCaXRzKHNlbGY6IFNsaWNlLCBsOiBJbnQpOiBTbGlj' + + 'ZTsKCi8vIHNwZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIsIHNvIG5vdCByZXBsYWNlZCB3aXRoIGFzbSAiTERJWCIKQG5hbWUobG9hZF9pbnQpCmV4dGVu' + + 'ZHMgbXV0YXRlcyBuYXRpdmUgbG9hZEludChzZWxmOiBTbGljZSwgbDogSW50KTogSW50OwoKLy8gc3BlY2lhbCB0cmVhdG1lbnQgaW4gRnVuYyBjb21waWxlciwgc28g' + + 'bm90IHJlcGxhY2VkIHdpdGggYXNtICJQTERJWCIKQG5hbWUocHJlbG9hZF9pbnQpCmV4dGVuZHMgbmF0aXZlIHByZWxvYWRJbnQoc2VsZjogU2xpY2UsIGw6IEludCk6' + + 'IEludDsKCi8vIHNwZWNpYWwgdHJlYXRtZW50IGluIEZ1bmMgY29tcGlsZXIsIHNvIG5vdCByZXBsYWNlZCB3aXRoIGFzbSAiTERVWCIKQG5hbWUobG9hZF91aW50KQpl' + + 'eHRlbmRzIG11dGF0ZXMgbmF0aXZlIGxvYWRVaW50KHNlbGY6IFNsaWNlLCBsOiBJbnQpOiBJbnQ7CgovLyBzcGVjaWFsIHRyZWF0bWVudCBpbiBGdW5jIGNvbXBpbGVy' + + 'LCBzbyBub3QgcmVwbGFjZWQgd2l0aCBhc20gIlBMRFVYIgpAbmFtZShwcmVsb2FkX3VpbnQpCmV4dGVuZHMgbmF0aXZlIHByZWxvYWRVaW50KHNlbGY6IFNsaWNlLCBs' + + 'OiBJbnQpOiBJbnQ7Cgphc20oLT4gMSAwKSBleHRlbmRzIG11dGF0ZXMgZnVuIGxvYWRCb29sKHNlbGY6IFNsaWNlKTogQm9vbCB7IDEgTERJIH0KCi8vLyBFeHRlbnNp' + + 'b24gbXV0YXRpb24gZnVuY3Rpb24gZm9yIHRoZSBgU2xpY2VgLiBBbGlhcyB0byBgU2xpY2UubG9hZEJvb2woKWAuCi8vLwovLy8gYGBgdGFjdAovLy8gbGV0IHM6IFNs' + + 'aWNlID0gYmVnaW5DZWxsKCkuc3RvcmVCb29sKHRydWUpLmFzU2xpY2UoKTsKLy8vIGxldCBmaXp6OiBCb29sID0gcy5sb2FkQml0KCk7IC8vIHRydWUKLy8vIGBgYAov' + + 'Ly8KLy8vIEBzaW5jZSBUYWN0IDEuNS4wCi8vLyBAc2VlIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWNlbGxzI3NsaWNlbG9hZGJpdAovLy8KYXNt' + + 'KC0+IDEgMCkgZXh0ZW5kcyBtdXRhdGVzIGZ1biBsb2FkQml0KHNlbGY6IFNsaWNlKTogQm9vbCB7IDEgTERJIH0KCmFzbSggLT4gMSAwKSBleHRlbmRzIG11dGF0ZXMg' + + 'ZnVuIGxvYWRDb2lucyhzZWxmOiBTbGljZSk6IEludCB7IExEVkFSVUlOVDE2IH0KCkBuYW1lKF9fdGFjdF9sb2FkX2FkZHJlc3MpCmV4dGVuZHMgbXV0YXRlcyBuYXRp' + + 'dmUgbG9hZEFkZHJlc3Moc2VsZjogU2xpY2UpOiBBZGRyZXNzOwoKYXNtIGV4dGVuZHMgbXV0YXRlcyBmdW4gc2tpcEJpdHMoc2VsZjogU2xpY2UsIGw6IEludCkgeyBT' + + 'RFNLSVBGSVJTVCB9Cgphc20gZXh0ZW5kcyBmdW4gZW5kUGFyc2Uoc2VsZjogU2xpY2UpIHsgRU5EUyB9CgovLwovLyBTbGljZSBzaXplCi8vCgphc20gZXh0ZW5kcyBm' + + 'dW4gcmVmcyhzZWxmOiBTbGljZSk6IEludCB7IFNSRUZTIH0KCmFzbSBleHRlbmRzIGZ1biBiaXRzKHNlbGY6IFNsaWNlKTogSW50IHsgU0JJVFMgfQoKYXNtIGV4dGVu' + + 'ZHMgZnVuIGVtcHR5KHNlbGY6IFNsaWNlKTogQm9vbCB7IFNFTVBUWSB9Cgphc20gZXh0ZW5kcyBmdW4gZGF0YUVtcHR5KHNlbGY6IFNsaWNlKTogQm9vbCB7IFNERU1Q' + + 'VFkgfQoKYXNtIGV4dGVuZHMgZnVuIHJlZnNFbXB0eShzZWxmOiBTbGljZSk6IEJvb2wgeyBTUkVNUFRZIH0KCi8vCi8vIENvbnZlcnNpb25zCi8vCgppbmxpbmUgZXh0' + + 'ZW5kcyBmdW4gYXNTbGljZShzZWxmOiBCdWlsZGVyKTogU2xpY2UgewogICAgcmV0dXJuIHNlbGYuZW5kQ2VsbCgpLmJlZ2luUGFyc2UoKTsKfQoKaW5saW5lIGV4dGVu' + + 'ZHMgZnVuIGFzU2xpY2Uoc2VsZjogQ2VsbCk6IFNsaWNlIHsKICAgIHJldHVybiBzZWxmLmJlZ2luUGFyc2UoKTsKfQoKaW5saW5lIGV4dGVuZHMgZnVuIGFzQ2VsbChz' + + 'ZWxmOiBTbGljZSk6IENlbGwgewogICAgcmV0dXJuIGJlZ2luQ2VsbCgpCiAgICAgICAgLnN0b3JlU2xpY2Uoc2VsZikKICAgICAgICAuZW5kQ2VsbCgpOwp9Cgppbmxp' + + 'bmUgZXh0ZW5kcyBmdW4gYXNDZWxsKHNlbGY6IEJ1aWxkZXIpOiBDZWxsIHsKICAgIHJldHVybiBzZWxmLmVuZENlbGwoKTsKfQoKaW5saW5lIGZ1biBlbXB0eUNlbGwo' + + 'KTogQ2VsbCB7CiAgICByZXR1cm4gYmVnaW5DZWxsKCkuZW5kQ2VsbCgpOwp9CgppbmxpbmUgZnVuIGVtcHR5U2xpY2UoKTogU2xpY2UgewogICAgcmV0dXJuIGVtcHR5' + + 'Q2VsbCgpLmFzU2xpY2UoKTsKfQo='; files['std/config.tact'] = 'YXNtIGZ1biBnZXRDb25maWdQYXJhbShpZDogSW50KTogQ2VsbD8geyBDT05GSUdPUFRQQVJBTSB9Cg=='; files['std/context.tact'] = @@ -203,10 +211,33 @@ files['std/contract.tact'] = 'ZGVkIHZhbHVlcykgZnJvbSBgZndkX2ZlZWAgcGFyc2VkIGZyb20gaW5jb21pbmcgbWVzc2FnZS4gYGlzX21hc3RlcmNoYWluYCBpcyB0cnVlIGlmIHRoZSBzb3VyY2Ug' + 'b3IgdGhlIGRlc3RpbmF0aW9uIGlzIGluIG1hc3RlcmNoYWluLCBmYWxzZSBpZiBib3RoIGFyZSBpbiBiYXNlY2hhaW4uCmFzbSBmdW4gZ2V0T3JpZ2luYWxGd2RGZWUo' + 'ZndkX2ZlZTogSW50LCBpc19tYXN0ZXJjaGFpbjogQm9vbCk6IEludCB7IEdFVE9SSUdJTkFMRldERkVFIH0KCi8vIEN1cnJlbnQgZGVidCBmb3Igc3RvcmFnZSBmZWUg' + - 'aW4gbmFub3RvbnMuCmFzbSBmdW4gbXlTdG9yYWdlRHVlKCk6IEludCB7IERVRVBBWU1FTlQgfQoKc3RydWN0IFN0ZEFkZHJlc3MgewogICAgd29ya2NoYWluOiBJbnQg' + - 'YXMgaW50ODsKICAgIGFkZHJlc3M6IEludCBhcyB1aW50MjU2Owp9CgpzdHJ1Y3QgVmFyQWRkcmVzcyB7CiAgICB3b3JrY2hhaW46IEludCBhcyBpbnQzMjsKICAgIGFk' + - 'ZHJlc3M6IFNsaWNlOwp9Cgphc20gZnVuIHBhcnNlU3RkQWRkcmVzcyhzbGljZTogU2xpY2UpOiBTdGRBZGRyZXNzIHsgUkVXUklURVNUREFERFIgfQoKYXNtIGZ1biBw' + - 'YXJzZVZhckFkZHJlc3Moc2xpY2U6IFNsaWNlKTogVmFyQWRkcmVzcyB7IFJFV1JJVEVWQVJBRERSIH0='; + 'aW4gbmFub3RvbnMuCmFzbSBmdW4gbXlTdG9yYWdlRHVlKCk6IEludCB7IERVRVBBWU1FTlQgfQoKLy8vIFN0cnVjdCByZXByZXNlbnRpbmcgdGhlIHN0YW5kYXJkIGFk' + + 'ZHJlc3Mgb24gVE9OIEJsb2NrY2hhaW4gd2l0aCBzaWduZWQgOC1iaXQgYHdvcmtjaGFpbmAgSUQgYW5kIGFuIHVuc2lnbmVkIDI1Ni1iaXQgYGFkZHJlc3NgIGluIHRo' + + 'ZSBzcGVjaWZpZWQgYHdvcmtjaGFpbmAuCi8vLwovLy8gQXQgdGhlIG1vbWVudCwgb25seSBgd29ya2NoYWluYCBJRHMgdXNlZCBvbiBUT04gYXJlIDAgb2YgdGhlIGJh' + + 'c2VjaGFpbiBhbmQgLTEgb2YgdGhlIG1hc3RlcmNoYWluLgovLy8KLy8vIEBzaW5jZSBUYWN0IDEuNS4wCi8vLyBAc2VlIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3Jn' + + 'L3JlZi9jb3JlLWFkdmFuY2VkI3BhcnNlc3RkYWRkcmVzcwovLy8gQHNlZSBodHRwczovL2dpdGh1Yi5jb20vdG9uLWJsb2NrY2hhaW4vdG9uL2Jsb2IvbWFzdGVyL2Ny' + + 'eXB0by9ibG9jay9ibG9jay50bGIjTDEwNS1MMTA2Ci8vLwpzdHJ1Y3QgU3RkQWRkcmVzcyB7CiAgICB3b3JrY2hhaW46IEludCBhcyBpbnQ4OwogICAgYWRkcmVzczog' + + 'SW50IGFzIHVpbnQyNTY7Cn0KCi8vLyBTdHJ1Y3QgcmVwcmVzZW50aW5nIHRoZSBhZGRyZXNzIG9mIHZhcmlhYmxlIGxlbmd0aCB3aXRoIHNpZ25lZCAzMi1iaXQgYHdv' + + 'cmtjaGFpbmAgSUQgYW5kIGEgYFNsaWNlYCBjb250YWluaW5nIHVuc2lnbmVkIGBhZGRyZXNzYCBpbiB0aGUgc3BlY2lmaWVkIGB3b3JrY2hhaW5gLgovLy8KLy8vIFZh' + + 'cmlhYmxlLWxlbmd0aCBhZGRyZXNzZXMgYXJlIGludGVuZGVkIGZvciBmdXR1cmUgZXh0ZW5zaW9ucywgYW5kIHdoaWxlIHZhbGlkYXRvcnMgbXVzdCBiZSByZWFkeSB0' + + 'byBhY2NlcHQgdGhlbSBpbiBpbmJvdW5kIG1lc3NhZ2VzLCB0aGUgc3RhbmRhcmQgKG5vbi12YXJpYWJsZSkgYWRkcmVzc2VzIGFyZSB1c2VkIHdoZW5ldmVyIHBvc3Np' + + 'YmxlLgovLy8KLy8vIEBzaW5jZSBUYWN0IDEuNS4wCi8vLyBAc2VlIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI3BhcnNldmFyYWRk' + + 'cmVzcwovLy8gQHNlZSBodHRwczovL2dpdGh1Yi5jb20vdG9uLWJsb2NrY2hhaW4vdG9uL2Jsb2IvbWFzdGVyL2NyeXB0by9ibG9jay9ibG9jay50bGIjTDEwNy1MMTA4' + + 'Ci8vLwpzdHJ1Y3QgVmFyQWRkcmVzcyB7CiAgICB3b3JrY2hhaW46IEludCBhcyBpbnQzMjsKICAgIGFkZHJlc3M6IFNsaWNlOwp9CgovLy8gQ29udmVydHMgYSBgU2xp' + + 'Y2VgIGNvbnRhaW5pbmcgYW4gYWRkcmVzcyBpbnRvIHRoZSBgU3RkQWRkcmVzc2AgU3RydWN0IGFuZCByZXR1cm5zIGl0LgovLy8KLy8vIGBgYHRhY3QKLy8vIGxldCBh' + + 'ZGRyID0gYWRkcmVzcygiRVFEdEZwRXdjRkFFY1JlNW1MVmgyTjZDMHgtX2hKRU03VzYxX0pMblNGNzRwNHEyIik7Ci8vLyBsZXQgcGFyc2VkQWRkciA9IHBhcnNlU3Rk' + + 'QWRkcmVzcyhhZGRyLmFzU2xpY2UoKSk7Ci8vLwovLy8gcGFyc2VkQWRkci53b3JrY2hhaW47IC8vIDAKLy8vIHBhcnNlZEFkZHIuYWRkcmVzczsgICAvLyAxMDcuLi4y' + + 'ODcKLy8vIGBgYAovLy8KLy8vIEBzaW5jZSBUYWN0IDEuNS4wCi8vLyBAc2VlIGh0dHBzOi8vZG9jcy50YWN0LWxhbmcub3JnL3JlZi9jb3JlLWFkdmFuY2VkI3BhcnNl' + + 'c3RkYWRkcmVzcwovLy8KYXNtIGZ1biBwYXJzZVN0ZEFkZHJlc3Moc2xpY2U6IFNsaWNlKTogU3RkQWRkcmVzcyB7IFJFV1JJVEVTVERBRERSIH0KCi8vLyBDb252ZXJ0' + + 'cyBhIGBTbGljZWAgY29udGFpbmluZyBhbiBhZGRyZXNzIG9mIHZhcmlhYmxlIGxlbmd0aCBpbnRvIHRoZSBgVmFyQWRkcmVzc2AgU3RydWN0IGFuZCByZXR1cm5zIGl0' + + 'LgovLy8KLy8vIGBgYHRhY3QKLy8vIGxldCB2YXJBZGRyU2xpY2UgPSBiZWdpbkNlbGwoKQovLy8gICAgIC5zdG9yZVVpbnQoNiwgMykgICAgIC8vIHRvIHJlY29nbml6' + + 'ZSB0aGUgZm9sbG93aW5nIGFzIGEgVmFyQWRkcmVzcwovLy8gICAgIC5zdG9yZVVpbnQoMTIzLCA5KSAgIC8vIG1ha2UgYWRkcmVzcyBvY2N1cHkgMTIzIGJpdHMKLy8v' + + 'ICAgICAuc3RvcmVVaW50KDIzNCwgMzIpICAvLyBzcGVjaWZ5IHdvcmtjaGFpbiBJRCBvZiAyMzQKLy8vICAgICAuc3RvcmVVaW50KDM0NSwgMTIzKSAvLyBzcGVjaWZ5' + + 'IGFkZHJlc3Mgb2YgMzQ1Ci8vLyAgICAgLmFzU2xpY2UoKTsKLy8vIGxldCBwYXJzZWRWYXJBZGRyID0gcGFyc2VWYXJBZGRyZXNzKHZhckFkZHJTbGljZSk7Ci8vLwov' + + 'Ly8gcGFyc2VkVmFyQWRkci53b3JrY2hhaW47ICAgICAgICAgICAgIC8vIDIzNAovLy8gcGFyc2VkVmFyQWRkci5hZGRyZXNzOyAgICAgICAgICAgICAgIC8vIENTe0Nl' + + 'bGx7MDAyLi4uMmIzfSBiaXRzOiA0NC4uMTY3OyByZWZzOiAwLi4wfQovLy8gcGFyc2VkVmFyQWRkci5hZGRyZXNzLmxvYWRVaW50KDEyMyk7IC8vIDM0NQovLy8gYGBg' + + 'Ci8vLwovLy8gQHNpbmNlIFRhY3QgMS41LjAKLy8vIEBzZWUgaHR0cHM6Ly9kb2NzLnRhY3QtbGFuZy5vcmcvcmVmL2NvcmUtYWR2YW5jZWQjcGFyc2V2YXJhZGRyZXNz' + + 'Ci8vLwphc20gZnVuIHBhcnNlVmFyQWRkcmVzcyhzbGljZTogU2xpY2UpOiBWYXJBZGRyZXNzIHsgUkVXUklURVZBUkFERFIgfQo='; files['std/crypto.tact'] = 'YXNtIGV4dGVuZHMgZnVuIGhhc2goc2VsZjogQ2VsbCk6IEludCB7IEhBU0hDVSB9Cgphc20gZXh0ZW5kcyBmdW4gaGFzaChzZWxmOiBTbGljZSk6IEludCB7IEhBU0hT' + 'VSB9Cgphc20gZnVuIGNoZWNrU2lnbmF0dXJlKGhhc2g6IEludCwgc2lnbmF0dXJlOiBTbGljZSwgcHVibGljX2tleTogSW50KTogQm9vbCB7IENIS1NJR05VIH0KCmFz' + diff --git a/stdlib/std/cells.tact b/stdlib/std/cells.tact index f3c8e1429..eb9b1c561 100644 --- a/stdlib/std/cells.tact +++ b/stdlib/std/cells.tact @@ -40,6 +40,24 @@ asm extends fun storeBuilder(self: Builder, cell: Builder): Builder { STBR } @name(__tact_store_address) extends native storeAddress(self: Builder, address: Address): Builder; +/// Extension function for the `Builder`. +/// +/// If the `cell` is not `null`, stores 1 as a single bit and then reference `cell` into the copy of the `Builder`. Returns that copy. +/// +/// If the `cell` is `null`, only stores 0 as a single bit into the copy of the `Builder`. Returns that copy. +/// +/// As a single `Cell` can store up to 4 references, attempts to store more throw an exception with exit code 8: `Cell overflow`. +/// +/// ```tact +/// let b: Builder = beginCell(); +/// let fizz: Builder = b +/// .storeMaybeRef(emptyCell()) // 1, then empty cell +/// .storeMaybeRef(null); // 0 +/// ``` +/// +/// @since Tact 1.5.0 +/// @see https://docs.tact-lang.org/ref/core-cells#builderstoremayberef +/// asm(cell self) extends fun storeMaybeRef(self: Builder, cell: Cell?): Builder { STOPTREF } asm extends fun endCell(self: Builder): Cell { ENDC } @@ -147,4 +165,4 @@ inline fun emptyCell(): Cell { inline fun emptySlice(): Slice { return emptyCell().asSlice(); -} \ No newline at end of file +} diff --git a/stdlib/std/contract.tact b/stdlib/std/contract.tact index 1c3cd4fe1..5a782dfa8 100644 --- a/stdlib/std/contract.tact +++ b/stdlib/std/contract.tact @@ -44,16 +44,64 @@ asm fun getOriginalFwdFee(fwd_fee: Int, is_masterchain: Bool): Int { GETORIGINAL // Current debt for storage fee in nanotons. asm fun myStorageDue(): Int { DUEPAYMENT } +/// Struct representing the standard address on TON Blockchain with signed 8-bit `workchain` ID and an unsigned 256-bit `address` in the specified `workchain`. +/// +/// At the moment, only `workchain` IDs used on TON are 0 of the basechain and -1 of the masterchain. +/// +/// @since Tact 1.5.0 +/// @see https://docs.tact-lang.org/ref/core-advanced#parsestdaddress +/// @see https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L105-L106 +/// struct StdAddress { workchain: Int as int8; address: Int as uint256; } +/// Struct representing the address of variable length with signed 32-bit `workchain` ID and a `Slice` containing unsigned `address` in the specified `workchain`. +/// +/// Variable-length addresses are intended for future extensions, and while validators must be ready to accept them in inbound messages, the standard (non-variable) addresses are used whenever possible. +/// +/// @since Tact 1.5.0 +/// @see https://docs.tact-lang.org/ref/core-advanced#parsevaraddress +/// @see https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb#L107-L108 +/// struct VarAddress { workchain: Int as int32; address: Slice; } +/// Converts a `Slice` containing an address into the `StdAddress` Struct and returns it. +/// +/// ```tact +/// let addr = address("EQDtFpEwcFAEcRe5mLVh2N6C0x-_hJEM7W61_JLnSF74p4q2"); +/// let parsedAddr = parseStdAddress(addr.asSlice()); +/// +/// parsedAddr.workchain; // 0 +/// parsedAddr.address; // 107...287 +/// ``` +/// +/// @since Tact 1.5.0 +/// @see https://docs.tact-lang.org/ref/core-advanced#parsestdaddress +/// asm fun parseStdAddress(slice: Slice): StdAddress { REWRITESTDADDR } -asm fun parseVarAddress(slice: Slice): VarAddress { REWRITEVARADDR } \ No newline at end of file +/// Converts a `Slice` containing an address of variable length into the `VarAddress` Struct and returns it. +/// +/// ```tact +/// let varAddrSlice = beginCell() +/// .storeUint(6, 3) // to recognize the following as a VarAddress +/// .storeUint(123, 9) // make address occupy 123 bits +/// .storeUint(234, 32) // specify workchain ID of 234 +/// .storeUint(345, 123) // specify address of 345 +/// .asSlice(); +/// let parsedVarAddr = parseVarAddress(varAddrSlice); +/// +/// parsedVarAddr.workchain; // 234 +/// parsedVarAddr.address; // CS{Cell{002...2b3} bits: 44..167; refs: 0..0} +/// parsedVarAddr.address.loadUint(123); // 345 +/// ``` +/// +/// @since Tact 1.5.0 +/// @see https://docs.tact-lang.org/ref/core-advanced#parsevaraddress +/// +asm fun parseVarAddress(slice: Slice): VarAddress { REWRITEVARADDR }