From 49791b30dc51e5d4cb2f563e1d6e1427bc1548f8 Mon Sep 17 00:00:00 2001 From: Novus Nota <68142933+novusnota@users.noreply.github.com> Date: Sun, 21 Jul 2024 12:35:10 +0200 Subject: [PATCH] feat: new page for Cells, Builders, Slices (#278) --- .../new-page-for-builder-cell-slices.mdx | 174 -------- cspell.json | 3 + pages/book/_meta.js | 1 + pages/book/bounced.mdx | 2 +- pages/book/cells.mdx | 371 ++++++++++++++++++ pages/book/contracts.mdx | 2 +- pages/book/debug.mdx | 6 +- pages/book/expressions.mdx | 5 +- pages/book/func.mdx | 2 +- pages/book/maps.mdx | 9 +- pages/book/operators.mdx | 8 +- pages/book/send.mdx | 19 +- pages/book/structs-and-messages.mdx | 12 +- pages/book/types.mdx | 8 +- pages/cookbook/single-communication.mdx | 2 +- pages/ref/core-cells.mdx | 370 ++++++++--------- pages/ref/core-common.mdx | 5 +- pages/ref/core-comptime.mdx | 3 +- pages/ref/core-debug.mdx | 13 +- pages/ref/core-math.mdx | 7 +- pages/ref/core-strings.mdx | 28 +- pages/ref/standard-libraries.mdx | 3 +- pages/ref/stdlib-content.mdx | 6 +- pages/ref/stdlib-dns.mdx | 18 +- 24 files changed, 654 insertions(+), 423 deletions(-) delete mode 100644 .github/temp-archive/new-page-for-builder-cell-slices.mdx create mode 100644 pages/book/cells.mdx diff --git a/.github/temp-archive/new-page-for-builder-cell-slices.mdx b/.github/temp-archive/new-page-for-builder-cell-slices.mdx deleted file mode 100644 index 70b10db4..00000000 --- a/.github/temp-archive/new-page-for-builder-cell-slices.mdx +++ /dev/null @@ -1,174 +0,0 @@ -TODO: Create additional page "Builders, Cells and Slices" and re-write examples below into its cohesive structure. - -## `Cell` - -### How to determine if a `Cell` is empty - -To check if there is any data in the [`Cell{:tact}`](/book/types#primitive-types), we should first convert it to the [`Slice{:tact}`](/book/types#primitive-types). If we are only interested in having bits, we should use `dataEmpty(){:tact}`, if only refs - `refsEmpty(){:tact}`. In case we want to check for the presence of any data, regardless of whether it is a bit or ref, we need to use `empty(){:tact}`. - -```tact -// Create an empty cell with no data and no refs -let empty_cell: Cell = emptyCell(); // alias for beginCell().endCell() -// Present `cell` as a `slice` to parse it. -let slice: Slice = empty_cell.asSlice(); -// Returns `true`, because `slice` doesn't have any data or refs -slice.empty(); - -// Create a cell with bits and references -let cell_with_data_and_refs: Cell = beginCell(). - storeUint(42, 8). - storeRef(emptyCell()). - endCell(); -// Change `cell` type to slice with `begin_parse()` -let slice: Slice = cell_with_data_and_refs.asSlice(); -// Returns `false`, because `slice` has both data and refs -slice.empty(); -``` - - - - **Useful links:**\ - [`empty(){:tact}` in Language→Reference](/language/ref/cells#sliceempty)\ - [`dataEmpty(){:tact}` in Language→Reference](/language/ref/cells#slicedataempty)\ - [`refsEmpty(){:tact}` in Language→Reference](/language/ref/cells#slicerefsempty)\ - [`emptyCell(){:tact}` in Language→Reference](/language/ref/cells#emptycell)\ - [`beginCell(){:tact}` in Language→Reference](/language/ref/cells#begincell)\ - [`endCell(){:tact}` in Language→Reference](/language/ref/cells#builderendcell) - - - -### How to determine if two Cells are equal - -Direct comparison: - -```tact -let a: Cell = beginCell() - .storeUint(123, 16) - .endCell(); - -let b: Cell = beginCell() - .storeUint(123, 16) - .endCell(); - -let areCellsEqual: Bool = a == b; // true -let areCellsNotEqual: Bool = a != b; // false -``` - -Note, that direct comparison via `=={:tact}` or `!={:tact}` operators implicitly uses hashes under the hood. - -Explicit comparisons using `.hash(){:tact}` are also available: - -```tact -let a: Cell = beginCell() - .storeUint(123, 16) - .endCell(); - -let b: Cell = beginCell() - .storeUint(123, 16) - .endCell(); - -let areCellsEqual: Bool = a.hash() == b.hash(); // true -let areCellsNotEqual: Bool = a.hash() != b.hash(); // false -``` - - - - **Useful links:**\ - [`Cell.hash(){:tact}` in Language→Reference](/language/ref/cells#cellhash) - - - -## `Slice` - -### How to determine if a `Slice` is empty - -A [`Slice{:tact}`](/book/types#primitive-types) is considered _empty_ if it has no stored `data` **and** no stored `references`. - -Use `empty(){:tact}` method to check if a [`Slice{:tact}`](/book/types#primitive-types) is empty. - -```tact -// Create an empty Slice with no data and no refs -let empty_slice: Slice = emptyCell().asSlice(); -// Returns `true`, because `empty_slice` doesn't have any data or refs -empty_slice.empty(); - -// Create a slice with some data -let slice_with_data: Slice = beginCell(). - storeUint(42, 8). - asSlice(); -// Returns `false`, because the slice has some data -slice_with_data.empty(); - -// Create a slice with a reference to an empty cell -let slice_with_refs: Slice = beginCell(). - storeRef(emptyCell()). - asSlice(); -// Returns `false`, because the slice has a reference -slice_with_refs.empty(); - -// Create a slice with data and a reference -let slice_with_data_and_refs: Slice = beginCell(). - storeUint(42, 8). - storeRef(emptyCell()). - asSlice(); -// Returns `false`, because the slice has both data and reference -slice_with_data_and_refs.empty(); -``` - -### How to determine if two Slices are equal - -Direct comparison: - -```tact -let firstSlice: Slice = "A".asSlice(); -let secondSlice: Slice = "A".asSlice(); - -let areEqual: Bool = firstSlice == secondSlice; -let areNotEqual: Bool = firstSlice != secondSlice; - -dump(areEqual) // true; -dump(areNotEqual) // false; -``` - -Note, that direct comparison via `=={:tact}` or `!={:tact}` operators implicitly uses hashes under the hood. - -Explicit comparisons using `.hash(){:tact}` are also available: - -```tact -fun areSlicesEqual(a: Slice, b: Slice): Bool { - return a.hash() == b.hash(); -} - -let firstSlice: Slice = "A".asSlice(); -let secondSlice: Slice = "A".asSlice(); - -let result: Bool = areSlicesEqual(firstSlice, secondSlice); -dump(result) // true; -``` - - - - **Useful links:**\ - [`String.asSlice(){:tact}` in Language→Reference](/language/ref/strings#stringasslice) - - - -### How to determine if a `Slice` has no data (no bits, but may have refs) - -```tact -let slice_with_data: Slice = beginCell(). - storeRef(emptyCell()). - asSlice(); // create a slice with ref but without data -let bitsCount: Int = slice_with_data.bits(); // 0 -let hasNoData: Bool = slice_with_data.dataEmpty(); // true -``` - -### How to determine if a `Slice` has no refs (but may have bits) - -```tact -let slice_with_data: Slice = beginCell(). - storeUint(0, 1). - asSlice(); // create a slice with data but without refs -let refsCount: Int = slice_with_data.refs(); // 0 -let hasNoRefs: Bool = slice_with_data.refsEmpty(); // true -``` diff --git a/cspell.json b/cspell.json index 97e9acce..f72db6b9 100644 --- a/cspell.json +++ b/cspell.json @@ -24,12 +24,15 @@ "Jetton", "Jettons", "jettons", + "jojo", "masterchain", "Masterchain", "mathrm", "nanotons", "nextra", "Offchain", + "quadtree", + "quadtrees", "RAWRESERVE", "respecifying", "Satoshi", diff --git a/pages/book/_meta.js b/pages/book/_meta.js index 58f9f6bb..a4a55312 100644 --- a/pages/book/_meta.js +++ b/pages/book/_meta.js @@ -8,6 +8,7 @@ export default { }, types: 'Type system overview', integers: 'Integers', + cells: 'Cells, Builders and Slices', maps: 'Maps', 'structs-and-messages': 'Structs and Messages', optionals: 'Optionals', diff --git a/pages/book/bounced.mdx b/pages/book/bounced.mdx index 554c7b61..80a35c96 100644 --- a/pages/book/bounced.mdx +++ b/pages/book/bounced.mdx @@ -26,7 +26,7 @@ contract MyContract { } ``` -To process bounced messages manually, you can use a fallback definition that handles a raw [`Slice{:tact}`](/book/types#primitive-types) directly. Note, that such receiver will get **all** the bounced messages produced by your contract: +To process bounced messages manually, you can use a fallback definition that handles a raw [`Slice{:tact}`](/book/cells#slices) directly. Note, that such receiver will get **all** the bounced messages produced by your contract: ```tact /rawMsg: Slice/ contract MyContract { diff --git a/pages/book/cells.mdx b/pages/book/cells.mdx new file mode 100644 index 00000000..7ac1e322 --- /dev/null +++ b/pages/book/cells.mdx @@ -0,0 +1,371 @@ +# Cells, Builders and Slices + +import { Callout } from 'nextra/components' + +[Cells](#cells), [Builders](#builders) and [Slices](#slices) are low-level [primitives][p] of TON Blockchain. The virtual machine of TON Blockchain, [TVM][tvm], uses cells to represent all data structures in persistent storage, and most in memory. + +## Cells + +`Cell{:tact}` is a [primitive][p] and a data structure, which [ordinarly](#cells-kinds) consists of up to $1023$ continuously laid out bits and up to $4$ references to other cells. Circular references are forbidden and cannot be created by the means of [TVM][tvm], which means cells can be viewed as [quadtrees][quadtree] or [directed acyclic graphs (DAGs)](https://en.wikipedia.org/wiki/Directed_acyclic_graph) of themselves. Contract code itself is represented by a tree of cells. + +Cells and [cell primitives](#cells-immutability) are bit-oriented, not byte-oriented: [TVM][tvm] regards data kept in cells as sequences (strings or streams) of up to $1023$ bits, not bytes. If necessary, contracts are free to use, say, $21$-bit integer fields serialized into [TVM][tvm] cells, thus using fewer persistent storage bytes to represent the same data. + +### Kinds [#cells-kinds] + +While the [TVM][tvm] type [`Cell{:tact}`](#cells) refers to all cells, there are different cell kinds with various memory layouts. The one described [earlier](#cells) is commonly referred to as an _ordinary_ (or cell — that's the most simple and most commonly used flavor of cells, which can only contain data. The grand majority of descriptions, guides and [references](/ref/core-cells) to cells and their usage assumes ordinary ones. + +Other kinds of cells are collectively called _exotic_ (or special) cells. They sometimes appear in actual representations of blocks and other data structures on TON Blockchain. Their memory layouts and purposes significantly differ from ordinary cells. + +Kinds (or subtypes) of all cells are encoded by an integer between $-1$ and $255$. Ordinary cells are encoded by $-1$, while exotic ones can be encoded by any other integer in that range. The subtype of an exotic cell is stored in the first $8$ bits of its data, which means valid exotic cells always have at least $8$ data bits. + +[TVM][tvm] currently supports the following exotic cell subtypes: +* [Pruned branch cell][c-pruned], with subtype encoded as $1$ — they represent deleted subtrees of cells. +* [Library reference cell][c-library], with subtype encoded as $2$ — they are used for storing libraries, and usually, in [masterchain](/book/masterchain) contexts. +* [Merkle proof cell][c-mproof], with subtype encoded as $3$ — they are used for verifying that certain portions of other cell's tree data belong to the full tree. +* [Merkle update cell][c-mupdate], with subtype encoded as $4$ — they always have two references and behave like a [Merkle proof][mproof] for both of them. + + + + **Useful links:**\ + [Pruned branch cells in TON Docs][c-pruned]\ + [Library reference cells in TON Docs][c-library]\ + [Merkle proof cells in TON Docs][c-mproof]\ + [Merkle update cells in TON Docs][c-mupdate]\ + [Simple proof-verifying example in TON Docs][mproof] + + + +[c-pruned]: https://docs.ton.org/develop/data-formats/exotic-cells#pruned-branch +[c-library]: https://docs.ton.org/develop/data-formats/library-cells +[c-mproof]: https://docs.ton.org/develop/data-formats/exotic-cells#merkle-proof +[c-mupdate]: https://docs.ton.org/develop/data-formats/exotic-cells#merkle-update +[mproof]: https://docs.ton.org/develop/data-formats/exotic-cells#simple-proof-verifying-example + +### Levels [#cells-levels] + +Every cell, being a [quadtree][quadtree], has an attribute called _level_, which is represented by an integer between $0$ and $3$. The level of an [ordinary](#cells-kinds) cell is always equal to the maximum of the levels of all its references. That is, level of an ordinary cell without references is equal to $0$. + +[Exotic](#cells-kinds) cells have different rules for determining their level, which are described [on this page in TON Docs](https://docs.ton.org/develop/data-formats/exotic-cells). + +### Standard representation [#cells-representation] + + + + To be resolved by [#280](https://github.com/tact-lang/tact-docs/issues/280). + + + +### Immutability [#cells-immutability] + +Cells are read-only and immutable, but there are two major sets of [ordinary](#cells-kinds) cell manipulation instructions in [TVM][tvm]: + +* Cell creation (or serialization) instructions, which are used to construct new cells from previously kept values and cells; +* And cell parsing (or deserialization) instructions, which are used to extract or load data previously stored into cells via serialization instructions. + +On top of that, there are instructions specific to [exotic](#cells-kinds) cells to create them and expect their values. However, [ordinary](#cells-kinds) cell parsing instructions can still be used on [exotic](#cells-kinds) ones, in which case they are automatically replaced by [ordinary](#cells-kinds) cells during such deserialization attempts. + +All cell manipulation instructions require transforming values of [`Cell{:tact}`](#cells) type to either [`Builder{:tact}`](#builders) or [`Slice{:tact}`](#slices) types before such cells can be modified or inspected. + +## Builders + +`Builder{:tact}` is a cell manipulation [primitive][p] for using cell creation instructions. They're immutable just like cells are, and allow constructing new cells from previously kept values and cells. Unlike cells, values of type `Builder{:tact}` appear only on [TVM][tvm] stack and cannot be stored in persistent storage. That means, for example, that persistent storage fields with type `Builder{:tact}` would actually be stored as cells under the hood. + +`Builder{:tact}` type represents partially composed cells, for which fast operations for appending integers, other cells, references to other cells and many others are defined: + +* [`Builder.storeUint(){:tact}` in Core library][b-2] +* [`Builder.storeInt(){:tact}` in Core library][b-3] +* [`Builder.storeBool(){:tact}` in Core library][b-4] +* [`Builder.storeSlice(){:tact}` in Core library][b-5] +* [`Builder.storeCoins(){:tact}` in Core library][b-6] +* [`Builder.storeAddress(){:tact}` in Core library][b-7] +* [`Builder.storeRef(){:tact}` in Core library][b-8] + +While you may use them for [manual construction](#cnp-manually) of the cells, it's strongly recommended to use [Structs][struct] instead: [Construction of cells with Structs](#cnp-structs). + +## Slices + +`Slice{:tact}` is a cell manipulation [primitive][p] for using cell parsing instructions. Unlike cells, they're mutable and allow extracting or loading data previously stored into cells via serialization instructions. Also unlike cells, values of type `Slice{:tact}` appear only on [TVM][tvm] stack and cannot be stored in persistent storage. That means, for example, that persistent storage fields with type `Slice{:tact}` would actually be stored as cells under the hood. + +`Slice{:tact}` type represents either the remainder of a partially parsed cell, or a value (subcell) residing inside such a cell and extracted from it by a parsing instruction: + +* [`Slice.loadUint(){:tact}` in Core library][s-2] +* [`Slice.loadInt(){:tact}` in Core library][s-3] +* [`Slice.loadBool(){:tact}` in Core library][s-4] +* [`Slice.loadSlice(){:tact}` in Core library][s-5] +* [`Slice.loadCoins(){:tact}` in Core library][s-6] +* [`Slice.loadAddress(){:tact}` in Core library][s-7] +* [`Slice.loadRef(){:tact}` in Core library][s-8] + +While you may use them for [manual parsing](#cnp-manually) of the cells, it's strongly recommended to use [Structs][struct] instead: [Parsing of cells with Structs](#cnp-structs). + +## Serialization + +Similar to serialization options of [`Int{:tact}`](/book/integers) type, `Cell{:tact}`, `Builder{:tact}` and `Slice{:tact}` also have various representations for encoding their values in the following cases: + +* as fields of [contracts](/book/contracts) and [traits](/book/types#traits), +* as fields of [Structs](/book/structs-and-messages#structs) and [Messages](/book/structs-and-messages#messages), +* and as key/value types of [maps](/book/maps). + +```tact +contract SerializationExample { + someCell: Cell as remaining; + someSlice: Slice as bytes32; +} +``` + +### `remaining` [#serialization-bytes64] + + + + To be resolved by [#26](https://github.com/tact-lang/tact-docs/issues/26). + + + +### `bytes32` [#serialization-bytes64] + + + + To be resolved by [#94](https://github.com/tact-lang/tact-docs/issues/94). + + + +### `bytes64` [#serialization-bytes64] + + + + To be resolved by [#94](https://github.com/tact-lang/tact-docs/issues/94). + + + +### Bag of Cells [#cells-boc] + +Bag of Cells, or _BoC_ for short, is a format for serializing and de-serializing cells into byte arrays as described in [boc.tlb](https://github.com/ton-blockchain/ton/blob/24dc184a2ea67f9c47042b4104bbb4d82289fac1/crypto/tl/boc.tlb#L25) [TL-B schema][tlb]. + +Read more about BoC in TON Docs: [Bag of Cells](https://docs.ton.org/develop/data-formats/cell-boc#bag-of-cells). + + + + Advanced information on [`Cell{:tact}`](#cells) serialization: [Canonical `Cell{:tact}` Serialization](https://docs.ton.org/develop/research-and-development/boc). + + + +## Operations + +### Construct and parse [#operations-cnp] + +In Tact, there are at least two ways to construct and parse cells: + +* [Manually](#cnp-manually), which involves active use of [`Builder{:tact}`](#builders), [`Slice{:tact}`](#slices) and [relevant methods](/ref/core-cells). +* [Using Structs](#cnp-structs), which is a recommended and much more convenient approach. + +#### Manually [#cnp-manually] + +Construction via `Builder{:tact}` | Parsing via `Slice{:tact}` +:------------------------------------- | :------------------------- +[`beginCell(){:tact}`][b-1] | [`Cell.beginParse(){:tact}`][s-1] +[`.storeUint(42, 7){:tact}`][b-2] | [`Slice.loadUint(7){:tact}`][s-2] +[`.storeInt(42, 7){:tact}`][b-3] | [`Slice.loadInt(7){:tact}`][s-3] +[`.storeBool(true){:tact}`][b-4] | [`Slice.loadBool(true){:tact}`][s-4] +[`.storeSlice(slice){:tact}`][b-5] | [`Slice.loadSlice(slice){:tact}`][s-5] +[`.storeCoins(42){:tact}`][b-6] | [`Slice.loadCoins(42){:tact}`][s-6] +[`.storeAddress(address){:tact}`][b-7] | [`Slice.loadAddress(){:tact}`][s-7] +[`.storeRef(cell){:tact}`][b-8] | [`Slice.loadRef(){:tact}`][s-8] +[`.endCell(){:tact}`][b-9] | [`Slice.endParse(){:tact}`][s-9] + +[b-1]: /ref/core-cells#begincell +[b-2]: /ref/core-cells#builderstoreuint +[b-3]: /ref/core-cells#builderstoreint +[b-4]: /ref/core-cells#builderstorebool +[b-5]: /ref/core-cells#builderstoreslice +[b-6]: /ref/core-cells#builderstorecoins +[b-7]: /ref/core-cells#builderstoreaddress +[b-8]: /ref/core-cells#builderstoreref +[b-9]: /ref/core-cells#builderendcell +[s-1]: /ref/core-cells#cellbeginparse +[s-2]: /ref/core-cells#sliceloaduint +[s-3]: /ref/core-cells#sliceloadint +[s-4]: /ref/core-cells#sliceloadbool +[s-5]: /ref/core-cells#sliceloadslice +[s-6]: /ref/core-cells#sliceloadcoins +[s-7]: /ref/core-cells#sliceloadaddress +[s-8]: /ref/core-cells#sliceloadref +[s-9]: /ref/core-cells#sliceendparse + +#### Using Structs (recommended) [#cnp-structs] + +[Structs][struct] and [Messages][message] are almost like living [TL-B schemas][tlb]. Which means that they're, essentially, [TL-B schemas][tlb] expressed in maintainable, verifiable and user-friendly Tact code. + +It is strongly recommended to use them and their [methods](/book/functions#extension-function) like [`Struct.toCell(){:tact}`][st-tc] and [`Struct.fromCell(){:tact}`][st-fc] instead of manually constructing and parsing cells, as this allows for much more declarative and self-explanatory contracts. + +The examples of manual parsing [above](#cnp-manually) could be re-written using [Structs][struct], with descriptive names of fields if one so desires: + +```tact /fromCell/ /toCell/ +// First Struct +struct Showcase { + id: Int as uint8; + someImportantNumber: Int as int8; + isThatCool: Bool; + payload: Slice; + nanoToncoins: Int as coins; + wackyTacky: Address; + jojoRef: Adventure; // another Struct +} + +// Here it is +struct Adventure { + bizarre: Bool = true; + time: Bool = false; +} + +fun example() { + // Basics + let s = Showcase.fromCell( + Showcase{ + id: 7, + someImportantNumber: 42, + isThatCool: true, + payload: emptySlice(), + nanoToncoins: 1330 + 7, + wackyTacky: myAddress(), + jojoRef: Adventure{ bizarre: true, time: false }, + }.toCell()); + s.isThatCool; // true +} +``` + +Note, that Tact's auto-layout algorithm is greedy. For example, `struct Adventure{:tact}` occupies very little space, and it won't be stored as a reference [`Cell{:tact}`](#cells), but will be provided directly as a [`Slice{:tact}`](#slices). + +By using [Structs][struct] and [Messages][message] over manual [`Cell{:tact}`](#cells) composition and parsing, those details would be simplified away and won't cause any hassle when the optimized layout changes. + + + + **Useful links:**\ + [Convert serialization](/book/func#convert-serialization)\ + [`Struct.toCell(){:tact}` in Core library][st-tc]\ + [`Struct.fromCell(){:tact}` in Core library][st-fc]\ + [`Struct.fromSlice(){:tact}` in Core library][st-fs]\ + [`Message.toCell(){:tact}` in Core library][msg-tc]\ + [`Message.fromCell(){:tact}` in Core library][msg-fc]\ + [`Message.fromSlice(){:tact}` in Core library][msg-fs] + + + +[st-tc]: /ref/core-cells#structtocell +[st-fc]: /ref/core-cells#structfromcell +[st-fs]: /ref/core-cells#structfromslice +[msg-tc]: /ref/core-cells#messagetocell +[msg-fc]: /ref/core-cells#messagefromcell +[msg-fs]: /ref/core-cells#messagefromslice + +### Check if empty [#operations-empty] + +Neither [`Cell{:tact}`](#cells) nor [`Builder{:tact}`](#builders) can be checked for emptiness directly — one needs to convert them to [`Slice{:tact}`](#slices) first. + +To check if there are any bits, use [`Slice.dataEmpty(){:tact}`][s-de]. To check if there are any references, use [`Slice.refsEmpty(){:tact}`][s-re]. And to check both at the same time, use [`Slice.empty(){:tact}`][s-e]. + +To also throw an [exit code 9](/book/exit-codes#9) whenever the [`Slice{:tact}`](#slices) isn't completely empty, use [`Slice.endParse(){:tact}`][s-ep]. + +```tact +// Preparations +let someCell = beginCell().storeUint(42, 7).endCell(); +let someBuilder = beginCell().storeRef(someCell); + +// Obtaining our Slices +let slice1 = someCell.asSlice(); +let slice2 = someBuilder.asSlice(); + +// .dataEmpty() +slice1.dataEmpty(); // false +slice2.dataEmpty(); // true + +// .refsEmpty() +slice1.refsEmpty(); // true +slice2.refsEmpty(); // false + +// .empty() +slice1.empty(); // false +slice2.empty(); // false + +// .endParse() +try { + slice1.endParse(); + slice2.endParse(); +} catch (e) { + e; // 9 +} +``` + + + + **Useful links:**\ + [`Cell.asSlice(){:tact}` in Core library](/ref/core-cells#cellasslice)\ + [`Builder.asSlice(){:tact}` in Core library](/ref/core-cells#builderasslice)\ + [`Slice.dataEmpty(){:tact}` in Core library][s-de]\ + [`Slice.refsEmpty(){:tact}` in Core library][s-re]\ + [`Slice.empty(){:tact}` in Core library][s-e]\ + [`Slice.endParse(){:tact}` in Core library][s-ep] + + + +[s-de]: /ref/core-cells#slicedataempty +[s-re]: /ref/core-cells#slicerefsempty +[s-e]: /ref/core-cells#sliceempty +[s-ep]: /ref/core-cells#sliceendparse + +### Check if equal [#operations-equal] + +Values of type [`Builder{:tact}`](#builders) cannot be compared directly using binary equality [`=={:tact}`][bin-eq] or inequality [`!={:tact}`][bin-eq] operators. However, values of type [`Cell{:tact}`](#cells) and [`Slice{:tact}`](#slices) can. + +Direct comparisons: + +```tact +let a = beginCell().storeUint(123, 8).endCell(); +let aSlice = a.asSlice(); + +let b = beginCell().storeUint(123, 8).endCell(); +let bSlice = b.asSlice(); + +let areCellsEqual = a == b; // true +let areCellsNotEqual = a != b; // false + +let areSlicesEqual = aSlice == bSlice; // true +let areSlicesNotEqual = aSlice != bSlice; // false +``` + +Note, that direct comparison via `=={:tact}` or `!={:tact}` operators implicitly uses [SHA-256](https://en.wikipedia.org/wiki/SHA-2#Hash_standard) hashes of [standard `Cell{:tact}` representation](#cells-representation) under the hood. + +Explicit comparisons using `.hash(){:tact}` are also available: + +```tact +let a = beginCell().storeUint(123, 8).endCell(); +let aSlice = a.asSlice(); + +let b = beginCell().storeUint(123, 8).endCell(); +let bSlice = b.asSlice(); + +let areCellsEqual = a.hash() == b.hash(); // true +let areCellsNotEqual = a.hash() != b.hash(); // false + +let areSlicesEqual = aSlice.hash() == bSlice.hash(); // true +let areSlicesNotEqual = aSlice.hash() != bSlice.hash(); // false +``` + + + + **Useful links:**\ + [`Cell.hash(){:tact}` in Core library](/ref/core-cells#cellhash)\ + [`Builder.hash(){:tact}` in Core library](/ref/core-cells#builderhash)\ + [`=={:tact}` and `!={:tact}`][bin-eq] + + + +[p]: /book/types#primitive-types +[struct]: /book/structs-and-messages#structs +[message]: /book/structs-and-messages#messages + +[tvm]: https://docs.ton.org/learn/tvm-instructions/tvm-overview +[tlb]: https://docs.ton.org/develop/data-formats/tl-b-language + +[quadtree]: https://en.wikipedia.org/wiki/Quadtree +[bin-eq]: /book/operators#binary-equality + diff --git a/pages/book/contracts.mdx b/pages/book/contracts.mdx index 3f3ae78d..905db6c2 100644 --- a/pages/book/contracts.mdx +++ b/pages/book/contracts.mdx @@ -128,7 +128,7 @@ Constant initializations must be relatively simple and only rely on values known You can read constants both in [receivers](#receiver-functions) and in [getters](#getter-functions). -Unlike [contract variables](#variables), **contract constants don't consume space in persistent state**. Their values are stored directly in the code [`Cell{:tact}`](/book/types#primitive-types) of the contract. +Unlike [contract variables](#variables), **contract constants don't consume space in persistent state**. Their values are stored directly in the code [`Cell{:tact}`](/book/cells#cells) of the contract. ```tact // global constants are calculated in compile-time and cannot change diff --git a/pages/book/debug.mdx b/pages/book/debug.mdx index 3d8b6074..abbd604c 100644 --- a/pages/book/debug.mdx +++ b/pages/book/debug.mdx @@ -34,7 +34,7 @@ Here are a few questions to ask yourself to challenge your assumptions: * Did you make a change to your code and assume it's unrelated to the issue you're facing? A common pitfall here is to modify the code and try to run the tests right away, without compiling the changes first. -* Did you expect variable or a [`Cell{:tact}`](/book/types#primitive-types) to contain a certain value (or a certain type of value) that is different from what was really there? Pay attention to your types and data layouts, especially their representation in [TL-B schemas](https://docs.ton.org/develop/data-formats/tl-b-language). +* Did you expect variable or a [`Cell{:tact}`](/book/cells#cells) to contain a certain value (or a certain type of value) that is different from what was really there? Pay attention to your types and data layouts, especially their representation in [TL-B schemas](https://docs.ton.org/develop/data-formats/tl-b-language). * Do you know the intent of the code? It's often more difficult to debug someone else's code. If it's not your code, it's possible you might need to spend time learning exactly what the code does before you can debug it effectively. @@ -273,7 +273,7 @@ To know the full list of such properties, look at auto-completion options provid #### toEqualCell -The method `expect(…).toEqualCell(){:typescript}` checks equality of two [cells](/book/types#primitive-types): +The method `expect(…).toEqualCell(){:typescript}` checks equality of two [cells](/book/cells#cells): ```typescript {3} expect(oneCell).toEqualCell(anotherCell); @@ -281,7 +281,7 @@ expect(oneCell).toEqualCell(anotherCell); #### toEqualSlice -The method `expect(…).toEqualSlice(){:typescript}` checks equality of two [slices](/book/types#primitive-types): +The method `expect(…).toEqualSlice(){:typescript}` checks equality of two [slices](/book/cells#slices): ```typescript {3} expect(oneSlice).toEqualSlice(anotherSlice); diff --git a/pages/book/expressions.mdx b/pages/book/expressions.mdx index 0159d8e4..c2dbdfb6 100644 --- a/pages/book/expressions.mdx +++ b/pages/book/expressions.mdx @@ -247,9 +247,10 @@ Where `StateInit{:tact}` is a built-in [Struct][s], that consists of: Field | Type | Description :----- | :----------------- | :---------- -`code` | [`Cell{:tact}`][p] | initial code of the [contract](/book/contracts) (the compiled bytecode) -`data` | [`Cell{:tact}`][p] | initial data of the [contract](/book/contracts) (arguments of `init(){:tact}` function of the contract) +`code` | [`Cell{:tact}`][cell] | initial code of the [contract](/book/contracts) (the compiled bytecode) +`data` | [`Cell{:tact}`][cell] | initial data of the [contract](/book/contracts) (arguments of `init(){:tact}` function of the contract) [p]: /book/types#primitive-types +[cell]: /book/cells#cells [s]: /book/structs-and-messages#structs [m]: /book/structs-and-messages#messages diff --git a/pages/book/func.mdx b/pages/book/func.mdx index 4c456f49..ff1d4e8f 100644 --- a/pages/book/func.mdx +++ b/pages/book/func.mdx @@ -6,7 +6,7 @@ Tact itself compiles to FunC and maps all its entities directly to various FunC [Primitive types](/book/types#primitive-types) in Tact are directly mapped to FunC ones. -All rules about copying variables are the same. One of the big differences is that there are no visible mutation operators in Tact and most [`Slice{:tact}`](/book/types#primitive-types) operations mutate variables in place. +All rules about copying variables are the same. One of the big differences is that there are no visible mutation operators in Tact and most [`Slice{:tact}`](/book/cells#slices) operations mutate variables in place. ## Convert serialization diff --git a/pages/book/maps.mdx b/pages/book/maps.mdx index bc656be1..c7f48038 100644 --- a/pages/book/maps.mdx +++ b/pages/book/maps.mdx @@ -23,7 +23,7 @@ Allowed value types: * [`Int{:tact}`][int] * [`Bool{:tact}`](/book/types#booleans) -* [`Cell{:tact}`][p] +* [`Cell{:tact}`][cell] * [`Address{:tact}`][p] * [Struct](/book/structs-and-messages#structs) * [Message](/book/structs-and-messages#messages) @@ -152,7 +152,7 @@ if (fizz == null) { ### Convert to a `Cell`, `.asCell()` [#ascell] -Use `.asCell(){:tact}` [method](/book/functions#extension-function) on maps to convert all their values to a [`Cell{:tact}`][p] type. Be mindful, that [`Cell{:tact}`][p] type is able to store up to 1023 bits, so converting larger maps to the Cell will result in error. +Use `.asCell(){:tact}` [method](/book/functions#extension-function) on maps to convert all their values to a [`Cell{:tact}`][cell] type. Be mindful, that [`Cell{:tact}`][cell] type is able to store up to 1023 bits, so converting larger maps to the Cell will result in error. As an example, this method is useful for sending small maps directly in the body of the reply: @@ -290,7 +290,7 @@ struct SerializedMapInside { While maps can be convenient to work with on a small scale, they cause a number of issues if the number of items is unbounded and map can significantly grow in size: -* As the upper bound of the smart contract state size is around $65\,000$ items of type [`Cell{:tact}`][p], it constrains the storage limit of maps to be about $30\,000$ key-value pairs for the whole contract. +* As the upper bound of the smart contract state size is around $65\,000$ items of type [`Cell{:tact}`][cell], it constrains the storage limit of maps to be about $30\,000$ key-value pairs for the whole contract. * The more entries you have in a map, the bigger [compute fees](https://docs.ton.org/develop/howto/fees-low-level#computation-fees) you'll get. Thus, working with large maps makes compute fees tough to predict and manage. @@ -326,5 +326,6 @@ If you still need a large map or an unbound (infinitely large) map, it's better TODO: Add reference to sharding page as per: https://github.com/tact-lang/tact-docs/issues/155 */} -[int]: /book/integers [p]: /book/types#primitive-types +[int]: /book/integers +[cell]: /book/cells#cells diff --git a/pages/book/operators.mdx b/pages/book/operators.mdx index 30c3e7e1..1e7f215e 100644 --- a/pages/book/operators.mdx +++ b/pages/book/operators.mdx @@ -374,15 +374,15 @@ Binary equality (_equal_) operator `=={:tact}` checks whether its two operands a Binary inequality (_not equal_) operator `!={:tact}` checks whether its two operands are _not equal_, returning a result of type [`Bool{:tact}`][bool]. -Both operators require operands to be of the same type and both don't perform implicit type conversions, except for the [`Cell{:tact}`][p] and [`Slice{:tact}`][p] types, which are implicitly compared by their hashes. +Both operators require operands to be of the same type and both don't perform implicit type conversions, except for the [`Cell{:tact}`][cell] and [`Slice{:tact}`][slice] types, which are implicitly compared by their hashes. Both operators can be applied to the following list of types and values: * [`Int{:tact}`][int] * [`Bool{:tact}`][bool] * [`Address{:tact}`][p] -* [`Cell{:tact}`][p], implicitly compares via `.hash(){:tact}` -* [`Slice{:tact}`][p], implicitly compares via `.hash(){:tact}` +* [`Cell{:tact}`][cell], implicitly compares via `.hash(){:tact}` +* [`Slice{:tact}`][slice], implicitly compares via `.hash(){:tact}` * [`String{:tact}`][p] * [`map{:tact}`](/book/maps), but only if their key and value types are identical * [Optionals and `null{:tact}` value](/book/optionals) @@ -648,3 +648,5 @@ value |= 5; // also bitwise ORs 5 and assigns result back [p]: /book/types#primitive-types [bool]: /book/types#booleans [int]: /book/integers +[cell]: /book/cells#cells +[slice]: /book/cells#slices diff --git a/pages/book/send.mdx b/pages/book/send.mdx index 2ea626f4..b321d082 100644 --- a/pages/book/send.mdx +++ b/pages/book/send.mdx @@ -6,15 +6,15 @@ TON blockchain is message-based — to communicate with other contracts and to d Messages in Tact are commonly composed using a built-in [Struct](/book/structs-and-messages#structs) `SendParameters{:tact}`, which consists of: -Field | Type | Description -:------- | :-------------------- | :---------- -`bounce` | [`Bool{:tact}`][p] | When set to `true` (default) message bounces back to the sender if the receiver contract doesn't exist or wasn't able to process the message. -`to` | [`Address{:tact}`][p] | Receiver internal [`Address{:tact}`][p] in TON blockchain. -`value` | [`Int{:tact}`][int] | The amount of [nanoToncoins][nano] you want to send with the message. This value is usually used to cover [forward fees][fwdfee], unless the optional flag [`SendPayGasSeparately{:tact}`](/book/message-mode#optional-flags) is used. -`mode` | [`Int{:tact}`][int] | An 8-bit value that configures how to send a message, defaults to $0$. See: [Message `mode`](/book/message-mode). -`body` | [`Cell?{:tact}`][p] | [Optional][opt] message body as a [`Cell{:tact}`][p] -`code` | [`Cell?{:tact}`][p] | [Optional][opt] initial code of the contract (the compiled bytecode) -`data` | [`Cell?{:tact}`][p] | [Optional][opt] initial data of the contract (arguments of [`init(){:tact}` function](/book/contracts#init-function) of the contract) +Field | Type | Description +:------- | :--------------------- | :---------- +`bounce` | [`Bool{:tact}`][p] | When set to `true` (default) message bounces back to the sender if the receiver contract doesn't exist or wasn't able to process the message. +`to` | [`Address{:tact}`][p] | Receiver internal [`Address{:tact}`][p] in TON blockchain. +`value` | [`Int{:tact}`][int] | The amount of [nanoToncoins][nano] you want to send with the message. This value is usually used to cover [forward fees][fwdfee], unless the optional flag [`SendPayGasSeparately{:tact}`](/book/message-mode#optional-flags) is used. +`mode` | [`Int{:tact}`][int] | An 8-bit value that configures how to send a message, defaults to $0$. See: [Message `mode`](/book/message-mode). +`body` | [`Cell?{:tact}`][cell] | [Optional][opt] message body as a [`Cell{:tact}`][cell] +`code` | [`Cell?{:tact}`][cell] | [Optional][opt] initial code of the contract (the compiled bytecode) +`data` | [`Cell?{:tact}`][cell] | [Optional][opt] initial data of the contract (arguments of [`init(){:tact}` function](/book/contracts#init-function) of the contract) Fields `code` and `data` are what's called an [init package](/book/expressions#initof), which is used in deployments of new contracts. @@ -149,6 +149,7 @@ There, the second message won't actually be sent: [p]: /book/types#primitive-types [int]: /book/integers +[cell]: /book/cells#cells [opt]: /book/optionals [phases]: https://docs.ton.org/learn/tvm-instructions/tvm-overview#transactions-and-phases diff --git a/pages/book/structs-and-messages.mdx b/pages/book/structs-and-messages.mdx index 27b29e41..ab510f39 100644 --- a/pages/book/structs-and-messages.mdx +++ b/pages/book/structs-and-messages.mdx @@ -189,7 +189,7 @@ fun example() { ### Convert to a `Cell`, `.toCell()` [#tocell] -It's possible to convert an arbitrary [Struct](#structs) or [Message](#messages) to the [`Cell{:tact}`][p] type by using the `.toCell(){:tact}` [extension function](/book/functions#extension-function): +It's possible to convert an arbitrary [Struct](#structs) or [Message](#messages) to the [`Cell{:tact}`][cell] type by using the `.toCell(){:tact}` [extension function](/book/functions#extension-function): ```tact struct Big { @@ -219,9 +219,9 @@ fun conversionFun() { ### Obtain from a `Cell` or `Slice`, `.fromCell()` and `.fromSlice()` [#fromcellslice] -Instead of manually parsing a [`Cell{:tact}`][p] or [`Slice{:tact}`][p] via a series of relevant `.loadSomething(){:tact}` function calls, one can use `.fromCell(){:tact}` and `.fromSlice(){:tact}` [extension functions](/book/functions#extension-function) for converting the provided [`Cell{:tact}`][p] or [`Slice{:tact}`][p] into the needed [Struct](#structs) or [Message](#messages). +Instead of manually parsing a [`Cell{:tact}`][cell] or [`Slice{:tact}`][slice] via a series of relevant `.loadSomething(){:tact}` function calls, one can use `.fromCell(){:tact}` and `.fromSlice(){:tact}` [extension functions](/book/functions#extension-function) for converting the provided [`Cell{:tact}`][cell] or [`Slice{:tact}`][slice] into the needed [Struct](#structs) or [Message](#messages). -Those extension functions only attempt to parse a [`Cell{:tact}`][p] or [`Slice{:tact}`][p] according to the structure of your [Struct](#structs) or [Message](#messages). In case layouts don't match, various exceptions may be thrown — make sure to wrap your code in [`try...catch{:tact}`](/book/statements#try-catch) blocks to prevent unexpected results. +Those extension functions only attempt to parse a [`Cell{:tact}`][cell] or [`Slice{:tact}`][slice] according to the structure of your [Struct](#structs) or [Message](#messages). In case layouts don't match, various exceptions may be thrown — make sure to wrap your code in [`try...catch{:tact}`](/book/statements#try-catch) blocks to prevent unexpected results. ```tact struct Fizz { foo: Int } @@ -248,7 +248,7 @@ fun constructThenParse() { ### Conversion laws -Whenever one converts between [`Cell{:tact}`][p]/[`Slice{:tact}`][p] and [Struct](#structs)/[Message](#messages) via `.toCell(){:tact}` and `.fromCell(){:tact}` functions, the following laws hold: +Whenever one converts between [`Cell{:tact}`][cell]/[`Slice{:tact}`][slice] and [Struct](#structs)/[Message](#messages) via `.toCell(){:tact}` and `.fromCell(){:tact}` functions, the following laws hold: * For any instance of type [Struct](#structs)/[Message](#messages), calling `.toCell(){:tact}` on it, then applying `Struct.fromCell(){:tact}` (or `Message.fromCell(){:tact}`) to the result gives back the copy of the original instance: @@ -270,7 +270,7 @@ fun lawOne() { } ``` -* For any [`Cell{:tact}`][p] with the same [TL-B](https://docs.ton.org/develop/data-formats/tl-b-language) layout as a given [Struct](#structs)/[Message](#messages), calling `Struct.fromCell(){:tact}` (or `Message.fromCell(){:tact}`) on it, and then converting the result to a [`Cell{:tact}`][p] via `.toCell(){:tact}` would give the copy of the original [`Cell{:tact}`][p]: +* For any [`Cell{:tact}`][cell] with the same [TL-B](https://docs.ton.org/develop/data-formats/tl-b-language) layout as a given [Struct](#structs)/[Message](#messages), calling `Struct.fromCell(){:tact}` (or `Message.fromCell(){:tact}`) on it, and then converting the result to a [`Cell{:tact}`][cell] via `.toCell(){:tact}` would give the copy of the original [`Cell{:tact}`][cell]: ```tact {9-10,15-16} struct ArbitraryStruct { val: Int as uint32 } @@ -298,3 +298,5 @@ fun lawTwo() { [msg-fs]: /ref/core-cells#messagefromslice [p]: /book/types#primitive-types +[cell]: /book/cells#cells +[slice]: /book/cells#slices diff --git a/pages/book/types.mdx b/pages/book/types.mdx index caaea1c3..422046fc 100644 --- a/pages/book/types.mdx +++ b/pages/book/types.mdx @@ -13,14 +13,14 @@ Additionally, many of those types [can be made nullable](#optionals). Tact supports a number of primitive data types that are tailored for smart contract use: -* [`Int{:tact}`][ints] — all numbers in Tact are $257$-bit signed integers, but [smaller representations](/book/integers#serialization) can be used to reduce storage costs. +* [`Int{:tact}`](/book/integers) — all numbers in Tact are $257$-bit signed integers, but [smaller representations](/book/integers#serialization) can be used to reduce storage costs. * [`Bool{:tact}`](#booleans) — classical boolean with `true{:tact}` and `false{:tact}` values. * `Address{:tact}` — standard [smart contract address](https://docs.ton.org/learn/overviews/addresses#address-of-smart-contract) in TON Blockchain. -* `Slice{:tact}`, `Cell{:tact}`, `Builder{:tact}` — low-level primitives of TON VM. -* `String{:tact}` — represents text strings in TON VM. +* [`Cell{:tact}`](/book/cells#cells), [`Builder{:tact}`](/book/cells#builders), [`Slice{:tact}`](/book/cells#slices) — low-level primitives of [TVM][tvm]. +* `String{:tact}` — immutable text strings. * `StringBuilder{:tact}` — helper type that allows you to concatenate strings in a gas-efficient way. -[ints]: /book/integers +[tvm]: https://docs.ton.org/learn/tvm-instructions/tvm-overview ### Booleans [#booleans] diff --git a/pages/cookbook/single-communication.mdx b/pages/cookbook/single-communication.mdx index 6755b1c9..fc1e44cc 100644 --- a/pages/cookbook/single-communication.mdx +++ b/pages/cookbook/single-communication.mdx @@ -89,7 +89,7 @@ send(SendParameters{ **Useful links:**\ ["Sending messages" in the Book](/book/send#send-message)\ - ["Message `mode`" in the Book](/book/message-mode) + ["Message `mode`" in the Book](/book/message-mode)\ [`StringBuilder{:tact}` in the Book](/book/types#primitive-types)\ [`Cell{:tact}` in Core library](/ref/core-cells) diff --git a/pages/ref/core-cells.mdx b/pages/ref/core-cells.mdx index 0ebad2eb..9be84752 100644 --- a/pages/ref/core-cells.mdx +++ b/pages/ref/core-cells.mdx @@ -2,13 +2,17 @@ import { Callout } from 'nextra-theme-docs' -Cells is a low level primitive that represents data in TON blockchain. Cell consists of a 1023 bits of data with up to 4 references to another Cells. Cells are read-only and immutable. Builders are immutable structures that can be used to construct Cells. Slices are a way to parse cells. +[`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. - Be very careful when constructing and parsing cells, and always make sure to document their desired layout: a strict order of values and types for serialization and deserialization. + Be very careful when constructing and parsing cells manually, and always make sure to document their desired layout: a strict order of values and types for serialization and deserialization. + + To do so, advanced users are recommended to use [Type Language - Binary (TL-B) schemas][tlb]. - To do so, advanced users are recommended to use [Type Language - Binary (`TL-B`) schemas](https://docs.ton.org/develop/data-formats/tl-b-language). + And every user is recommended to use [Structs][struct] and their [methods](/book/functions#extension-function) like [`Struct.toCell(){:tact}`](structtocell) and [`Struct.fromCell(){:tact}`](structfromcell) instead of manually constructing and parsing cells, because [Structs][struct] and [Messages][message] are closest to being the [living TL-B schemas of your contracts](/book/cells#cnp-structs). @@ -18,7 +22,7 @@ Cells is a low level primitive that represents data in TON blockchain. Cell cons fun beginCell(): Builder ``` -Creates a new empty [`Builder{:tact}`][p]. +Creates a new empty [`Builder{:tact}`][builder]. Usage example: @@ -26,15 +30,100 @@ Usage example: let fizz: Builder = beginCell(); ``` +## emptyCell + +```tact +fun emptyCell(): Cell; +``` + +Creates and returns an empty [`Cell{:tact}`][cell] (without data and references). Alias to `beginCell().endCell(){:tact}`. + +Usage example: + +```tact +let fizz: Cell = emptyCell(); +let buzz: Cell = beginCell().endCell(); + +fizz == buzz; // true +``` + +## emptySlice + +```tact +fun emptySlice(): Slice; +``` + +Creates and returns an empty [`Slice{:tact}`][slice] (without data and references). Alias to `emptyCell().asSlice(){:tact}`. + +Usage example: + +```tact +let fizz: Slice = emptySlice(); +let buzz: Slice = emptyCell().asSlice(); + +fizz == buzz; // true +``` + +## Cell.beginParse + +```tact +extends fun beginParse(self: Cell): Slice; +``` + +Extension function for the [`Cell{:tact}`][cell]. + +Opens the [`Cell{:tact}`][cell] for parsing and returns it as a [`Slice{:tact}`][slice]. + +Usage example: + +```tact +let c: Cell = emptyCell(); +let fizz: Slice = c.beginParse(); +``` + +## Cell.hash + +```tact +extends fun hash(self: Cell): Int; +``` + +Extension function for the [`Cell{:tact}`][cell]. + +Calculates and returns an [`Int{:tact}`][int] value of the [SHA-256][sha-2] hash of the [standard `Cell{:tact}` representation][std-repr] of the given [`Cell{:tact}`][cell]. + +Usage example: + +```tact +let c: Cell = emptyCell(); +let fizz: Int = c.hash(); +``` + +## Cell.asSlice + +```tact +extends fun asSlice(self: Cell): Slice; +``` + +Extension function for the [`Cell{:tact}`][cell]. + +Converts the Cell to a [`Slice{:tact}`][slice] and returns it. Alias to `self.beginParse(){:tact}`. + +Usage example: + +```tact +let c: Cell = emptyCell(); +let fizz: Slice = c.asSlice(); +``` + ## Builder.endCell ```tact extends fun endCell(self: Builder): Cell; ``` -Extension function for the [`Builder{:tact}`][p]. +Extension function for the [`Builder{:tact}`][builder]. -Converts a [`Builder{:tact}`][p] into an ordinary [`Cell{:tact}`][p]. +Converts a [`Builder{:tact}`][builder] into an ordinary [`Cell{:tact}`][cell]. Usage example: @@ -49,9 +138,9 @@ let fizz: Cell = b.endCell(); extends fun storeUint(self: Builder, value: Int, bits: Int): Builder; ``` -Extension function for the [`Builder{:tact}`][p]. +Extension function for the [`Builder{:tact}`][builder]. -Stores an unsigned `bits`-bit `value` into the copy of the [`Builder{:tact}`][p] for $0 ≤$ `bits` $≤ 256$. Returns that copy. +Stores an unsigned `bits`-bit `value` into the copy of the [`Builder{:tact}`][builder] for $0 ≤$ `bits` $≤ 256$. Returns that copy. Attempts to store a negative `value` or provide an insufficient or out-of-bounds `bits` number throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. @@ -68,9 +157,9 @@ let fizz: Builder = b.storeUint(42, 6); extends fun storeInt(self: Builder, value: Int, bits: Int): Builder; ``` -Extension function for the [`Builder{:tact}`][p]. +Extension function for the [`Builder{:tact}`][builder]. -Stores a signed `bits`-bit `value` into the copy of the [`Builder{:tact}`][p] for $0 ≤$ `bits` $≤ 257$. Returns that copy. +Stores a signed `bits`-bit `value` into the copy of the [`Builder{:tact}`][builder] for $0 ≤$ `bits` $≤ 257$. Returns that copy. Attempts to provide an insufficient or out-of-bounds `bits` number throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. @@ -87,9 +176,9 @@ let fizz: Builder = b.storeUint(42, 7); extends fun storeBool(self: Builder, value: Bool): Builder; ``` -Extension function for the [`Builder{:tact}`][p]. +Extension function for the [`Builder{:tact}`][builder]. -Stores a [`Bool{:tact}`][bool] `value` into the copy of the [`Builder{:tact}`][p]. Writes $1$ as a single bit if `value` is `true{:tact}`, and writes $0$ otherwise. Returns that copy of the [`Builder{:tact}`][p]. +Stores a [`Bool{:tact}`][bool] `value` into the copy of the [`Builder{:tact}`][builder]. Writes $1$ as a single bit if `value` is `true{:tact}`, and writes $0$ otherwise. Returns that copy of the [`Builder{:tact}`][builder]. Usage example: @@ -105,9 +194,9 @@ let buzz: Builder = b.storeBool(false); // writes 0 extends fun storeSlice(self: Builder, cell: Slice): Builder; ``` -Extension function for the [`Builder{:tact}`][p]. +Extension function for the [`Builder{:tact}`][builder]. -Stores a [`Slice{:tact}`][p] `cell` into the copy of the [`Builder{:tact}`][p]. Returns that copy. +Stores a [`Slice{:tact}`][slice] `cell` into the copy of the [`Builder{:tact}`][builder]. Returns that copy. Usage example: @@ -123,9 +212,9 @@ let fizz: Builder = b.storeSlice(s); extends fun storeCoins(self: Builder, value: Int): Builder; ``` -Extension function for the [`Builder{:tact}`][p]. +Extension function for the [`Builder{:tact}`][builder]. -Stores (serializes) an unsigned [`Int{:tact}`][int] `value` in the range $0 .. 2^{120} − 1$ into the copy of the [`Builder{:tact}`][p]. The serialization of `value` consists of a $4$-bit unsigned big-endian integer $l$, which is the smallest integer $l ≥ 0$, such that `value` $< 2^{8 * l}$, followed by an $8 * l$-bit unsigned big-endian representation of `value`. If `value` does not belong to the supported range, a range check exception is thrown. Returns that copy of the [`Builder{:tact}`][p]. +Stores (serializes) an unsigned [`Int{:tact}`][int] `value` in the range $0 .. 2^{120} − 1$ into the copy of the [`Builder{:tact}`][builder]. The serialization of `value` consists of a $4$-bit unsigned big-endian integer $l$, which is the smallest integer $l ≥ 0$, such that `value` $< 2^{8 * l}$, followed by an $8 * l$-bit unsigned big-endian representation of `value`. Returns that copy of the [`Builder{:tact}`][builder]. Attempts to store an out-of-bounds `value` throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. @@ -151,9 +240,9 @@ let fizz: Builder = b.storeCoins(42); extends fun storeAddress(self: Builder, address: Address): Builder; ``` -Extension function for the [`Builder{:tact}`][p]. +Extension function for the [`Builder{:tact}`][builder]. -Stores the `address` in the copy of the [`Builder{:tact}`][p]. Returns that copy. +Stores the `address` in the copy of the [`Builder{:tact}`][builder]. Returns that copy. Usage example: @@ -168,11 +257,11 @@ let fizz: Builder = b.storeAddress(myAddress()); extends fun storeRef(self: Builder, cell: Cell): Builder; ``` -Extension function for the [`Builder{:tact}`][p]. +Extension function for the [`Builder{:tact}`][builder]. -Stores a reference `cell` into the copy of the [`Builder{:tact}`][p]. Returns that copy. +Stores a reference `cell` into the copy of the [`Builder{:tact}`][builder]. Returns that copy. -As a single [`Cell{:tact}`][p] can store up to $4$ references, attempts to store more throw an exception with [exit code 8](/book/exit-codes#8): `Cell overflow`. +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: @@ -187,9 +276,9 @@ let fizz: Builder = b.storeRef(emptyCell()); extends fun refs(self: Builder): Int; ``` -Extension function for the [`Builder{:tact}`][p]. +Extension function for the [`Builder{:tact}`][builder]. -Returns the number of cell references already stored in the [`Builder{:tact}`][p] as an [`Int{:tact}`][int]. +Returns the number of cell references already stored in the [`Builder{:tact}`][builder] as an [`Int{:tact}`][int]. Usage example: @@ -204,9 +293,9 @@ let fizz: Int = b.refs(); // 0 extends fun bits(self: Builder): Int; ``` -Extension function for the [`Builder{:tact}`][p]. +Extension function for the [`Builder{:tact}`][builder]. -Returns the number of data bits already stored in the [`Builder{:tact}`][p] as an [`Int{:tact}`][int]. +Returns the number of data bits already stored in the [`Builder{:tact}`][builder] as an [`Int{:tact}`][int]. Usage example: @@ -221,9 +310,9 @@ let fizz: Int = b.bits(); // 0 extends fun asSlice(self: Builder): Slice; ``` -Extension function for the [`Builder{:tact}`][p]. +Extension function for the [`Builder{:tact}`][builder]. -Converts the [`Builder{:tact}`][p] to a [`Slice{:tact}`][p] and returns it. Alias to `self.endCell().beginParse(){:tact}`. +Converts the [`Builder{:tact}`][builder] to a [`Slice{:tact}`][slice] and returns it. Alias to `self.endCell().beginParse(){:tact}`. Usage example: @@ -238,9 +327,9 @@ let fizz: Slice = b.asSlice(); extends fun asCell(self: Builder): Cell; ``` -Extension function for the [`Builder{:tact}`][p]. +Extension function for the [`Builder{:tact}`][builder]. -Converts the [`Builder{:tact}`][p] to a [`Cell{:tact}`][p] and returns it. Alias to `self.endCell(){:tact}`. +Converts the [`Builder{:tact}`][builder] to a [`Cell{:tact}`][cell] and returns it. Alias to `self.endCell(){:tact}`. Usage example: @@ -249,70 +338,19 @@ let b: Builder = beginCell(); let fizz: Cell = b.asCell(); ``` -## Cell.beginParse - -```tact -extends fun beginParse(self: Cell): Slice; -``` - -Extension function for the [`Cell{:tact}`][p]. - -Opens the [`Cell{:tact}`][p] for parsing and returns it as a [`Slice{:tact}`][p]. - -Usage example: - -```tact -let c: Cell = emptyCell(); -let fizz: Slice = c.beginParse(); -``` - -## Cell.hash - -```tact -extends fun hash(self: Cell): Int; -``` - -Extension function for the [`Cell{:tact}`][p]. - -Calculates and returns a hash of the [`Cell{:tact}`][p] as an [`Int{:tact}`][int]. - -Usage example: - -```tact -let c: Cell = emptyCell(); -let fizz: Int = c.hash(); -``` - -## Cell.asSlice - -```tact -extends fun asSlice(self: Cell): Slice; -``` - -Extension function for the [`Cell{:tact}`][p]. - -Converts the Cell to a [`Slice{:tact}`][p] and returns it. Alias to `self.beginParse(){:tact}`. - -Usage example: - -```tact -let c: Cell = emptyCell(); -let fizz: Slice = c.asSlice(); -``` - ## Slice.loadUint ```tact extends mutates fun loadUint(self: Slice, l: Int): Int; ``` -Extension mutation function for the [`Slice{:tact}`][p]. +Extension mutation function for the [`Slice{:tact}`][slice]. -Loads and returns an unsigned `l`-bit [`Int{:tact}`][int] from the [`Slice{:tact}`][p] for $0 ≤$ `l` $≤ 256$. +Loads and returns an unsigned `l`-bit [`Int{:tact}`][int] from the [`Slice{:tact}`][slice] for $0 ≤$ `l` $≤ 256$. Attempts to specify an out-of-bounds `l` value throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. -Attempts to load more data than [`Slice{:tact}`][p] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. +Attempts to load more data than [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. Usage example: @@ -327,13 +365,13 @@ let fizz: Int = s.loadUint(7); extends fun preloadUint(self: Slice, l: Int): Int; ``` -Extension function for the [`Slice{:tact}`][p]. +Extension function for the [`Slice{:tact}`][slice]. -Preloads and returns an unsigned `l`-bit [`Int{:tact}`][int] from the [`Slice{:tact}`][p] for $0 ≤$ `l` $≤ 256$. Doesn't modify the [`Slice{:tact}`][p]. +Preloads and returns an unsigned `l`-bit [`Int{:tact}`][int] from the [`Slice{:tact}`][slice] for $0 ≤$ `l` $≤ 256$. Doesn't modify the [`Slice{:tact}`][slice]. Attempts to specify an out-of-bounds `l` value throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. -Attempts to preload more data than [`Slice{:tact}`][p] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. +Attempts to preload more data than [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. Usage example: @@ -348,13 +386,13 @@ let fizz: Int = s.preloadUint(7); extends mutates fun loadInt(self: Slice, l: Int): Int; ``` -Extension mutation function for the [`Slice{:tact}`][p]. +Extension mutation function for the [`Slice{:tact}`][slice]. -Loads and returns a signed `l`-bit [`Int{:tact}`][int] from the [`Slice{:tact}`][p] for $0 ≤$ `l` $≤ 257$. +Loads and returns a signed `l`-bit [`Int{:tact}`][int] from the [`Slice{:tact}`][slice] for $0 ≤$ `l` $≤ 257$. Attempts to specify an out-of-bounds `l` value throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. -Attempts to load more data than [`Slice{:tact}`][p] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. +Attempts to load more data than [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. Usage example: @@ -369,13 +407,13 @@ let fizz: Int = s.loadInt(7); extends fun preloadInt(self: Slice, l: Int): Int; ``` -Extension function for the [`Slice{:tact}`][p]. +Extension function for the [`Slice{:tact}`][slice]. -Preloads and returns a signed `l`-bit [`Int{:tact}`][int] from the [`Slice{:tact}`][p] for $0 ≤$ `l` $≤ 257$. Doesn't modify the [`Slice{:tact}`][p]. +Preloads and returns a signed `l`-bit [`Int{:tact}`][int] from the [`Slice{:tact}`][slice] for $0 ≤$ `l` $≤ 257$. Doesn't modify the [`Slice{:tact}`][slice]. Attempts to specify an out-of-bounds `l` value throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. -Attempts to preload more data than [`Slice{:tact}`][p] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. +Attempts to preload more data than [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. Usage example: @@ -390,13 +428,13 @@ let fizz: Int = s.preloadInt(7); extends mutates fun loadBits(self: Slice, l: Int): Slice; ``` -Extension mutation function for the [`Slice{:tact}`][p]. +Extension mutation function for the [`Slice{:tact}`][slice]. -Loads $0 ≤$ `l` $≤ 1023$ bits from the [`Slice{:tact}`][p], and returns them as a separate [`Slice{:tact}`][p]. +Loads $0 ≤$ `l` $≤ 1023$ bits from the [`Slice{:tact}`][slice], and returns them as a separate [`Slice{:tact}`][slice]. Attempts to specify an out-of-bounds `l` value throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. -Attempts to load more data than [`Slice{:tact}`][p] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. +Attempts to load more data than [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. Usage example: @@ -411,13 +449,13 @@ let fizz: Slice = s.loadBits(7); extends fun preloadBits(self: Slice, l: Int): Slice; ``` -Extension function for the [`Slice{:tact}`][p]. +Extension function for the [`Slice{:tact}`][slice]. -Preloads $0 ≤$ `l` $≤ 1023$ bits from the [`Slice{:tact}`][p], and returns them as a separate [`Slice{:tact}`][p]. Doesn't modify the original [`Slice{:tact}`][p]. +Preloads $0 ≤$ `l` $≤ 1023$ bits from the [`Slice{:tact}`][slice], and returns them as a separate [`Slice{:tact}`][slice]. Doesn't modify the original [`Slice{:tact}`][slice]. Attempts to specify an out-of-bounds `l` value throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. -Attempts to preload more data than [`Slice{:tact}`][p] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. +Attempts to preload more data than [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. Usage example: @@ -432,13 +470,13 @@ let fizz: Slice = s.preloadBits(7); extends mutates fun skipBits(self: Slice, l: Int); ``` -Extension mutation function for the [`Slice{:tact}`][p]. +Extension mutation function for the [`Slice{:tact}`][slice]. -Loads all but the first $0 ≤$ `l` $≤ 1023$ bits from the [`Slice{:tact}`][p]. +Loads all but the first $0 ≤$ `l` $≤ 1023$ bits from the [`Slice{:tact}`][slice]. Attempts to specify an out-of-bounds `l` value throw an exception with [exit code 5](/book/exit-codes#5): `Integer out of expected range`. -Attempts to load more data than [`Slice{:tact}`][p] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. +Attempts to load more data than [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. Usage example: @@ -454,13 +492,13 @@ let fizz: Slice = s.loadBits(1); // load only 1 bit extends mutates fun loadBool(self: Slice): Bool; ``` -Extension mutation function for the [`Slice{:tact}`][p]. +Extension mutation function for the [`Slice{:tact}`][slice]. -Loads a single bit and returns a [`Bool{:tact}`][bool] value from the [`Slice{:tact}`][p]. Reads `true{:tact}` if the loaded bit is equal to $1$, and reads `false{:tact}` otherwise. +Loads a single bit and returns a [`Bool{:tact}`][bool] value from the [`Slice{:tact}`][slice]. Reads `true{:tact}` if the loaded bit is equal to $1$, and reads `false{:tact}` otherwise. -Attempts to load such [`Bool{:tact}`][bool] when [`Slice{:tact}`][p] doesn't contain it throw an exception with [exit code 8](/book/exit-codes#8): `Cell overflow`. +Attempts to load such [`Bool{:tact}`][bool] when [`Slice{:tact}`][slice] doesn't contain it throw an exception with [exit code 8](/book/exit-codes#8): `Cell overflow`. -Attempts to load more data than [`Slice{:tact}`][p] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. +Attempts to load more data than [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. Usage example: @@ -475,13 +513,13 @@ let fizz: Bool = s.loadBool(); // true extends mutates fun loadCoins(self: Slice): Int; ``` -Extension mutation function for the [`Slice{:tact}`][p]. +Extension mutation function for the [`Slice{:tact}`][slice]. -Loads and returns [serialized](#builderstorecoins) an unsigned [`Int{:tact}`][int] value in the range $0 .. 2^{120} - 1$ from the [`Slice{:tact}`][p]. This value usually represents the amount in [nanoToncoins](/book/integers#nanotoncoin). +Loads and returns [serialized](#builderstorecoins) an unsigned [`Int{:tact}`][int] value in the range $0 .. 2^{120} - 1$ from the [`Slice{:tact}`][slice]. This value usually represents the amount in [nanoToncoins](/book/integers#nanotoncoin). -Attempts to load such [`Int{:tact}`][int] when [`Slice{:tact}`][p] doesn't contain it throw an exception with [exit code 8](/book/exit-codes#8): `Cell overflow`. +Attempts to load such [`Int{:tact}`][int] when [`Slice{:tact}`][slice] doesn't contain it throw an exception with [exit code 8](/book/exit-codes#8): `Cell overflow`. -Attempts to load more data than [`Slice{:tact}`][p] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. +Attempts to load more data than [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. Usage example: @@ -503,13 +541,13 @@ let fizz: Int = s.loadCoins(); extends mutates fun loadAddress(self: Slice): Address; ``` -Extension mutation function for the [`Slice{:tact}`][p]. +Extension mutation function for the [`Slice{:tact}`][slice]. -Loads and returns an [`Address{:tact}`][p] from the [`Slice{:tact}`][p]. +Loads and returns an [`Address{:tact}`][p] from the [`Slice{:tact}`][slice]. -Attempts to load such [`Address{:tact}`][p] when [`Slice{:tact}`][p] doesn't contain it throw an exception with [exit code 8](/book/exit-codes#8): `Cell overflow`. +Attempts to load such [`Address{:tact}`][p] when [`Slice{:tact}`][slice] doesn't contain it throw an exception with [exit code 8](/book/exit-codes#8): `Cell overflow`. -Attempts to load more data than [`Slice{:tact}`][p] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. +Attempts to load more data than [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. Usage example: @@ -524,13 +562,13 @@ let fizz: Address = s.loadAddress(); extends mutates fun loadRef(self: Slice): Cell; ``` -Extension mutation function for the [`Slice{:tact}`][p]. +Extension mutation function for the [`Slice{:tact}`][slice]. -Loads the next reference from the [`Slice{:tact}`][p] as a [`Cell{:tact}`][p]. +Loads the next reference from the [`Slice{:tact}`][slice] as a [`Cell{:tact}`][cell]. -Attempts to load such reference [`Cell{:tact}`][p] when [`Slice{:tact}`][p] doesn't contain it throw an exception with [exit code 8](/book/exit-codes#8): `Cell overflow`. +Attempts to load such reference [`Cell{:tact}`][cell] when [`Slice{:tact}`][slice] doesn't contain it throw an exception with [exit code 8](/book/exit-codes#8): `Cell overflow`. -Attempts to load more data than [`Slice{:tact}`][p] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. +Attempts to load more data than [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. Usage examples: @@ -552,9 +590,9 @@ let ref2: Cell = s.loadRef(); extends fun refs(self: Slice): Int; ``` -Extension function for the [`Slice{:tact}`][p]. +Extension function for the [`Slice{:tact}`][slice]. -Returns the number of references in the [`Slice{:tact}`][p] as an [`Int{:tact}`][int]. +Returns the number of references in the [`Slice{:tact}`][slice] as an [`Int{:tact}`][int]. Usage example: @@ -569,9 +607,9 @@ let fizz: Int = s.refs(); extends fun bits(self: Slice): Int; ``` -Extension function for the [`Slice{:tact}`][p]. +Extension function for the [`Slice{:tact}`][slice]. -Returns the number of data bits in the [`Slice{:tact}`][p] as an [`Int{:tact}`][int]. +Returns the number of data bits in the [`Slice{:tact}`][slice] as an [`Int{:tact}`][int]. Usage example: @@ -586,9 +624,9 @@ let fizz: Int = s.bits(); extends fun empty(self: Slice): Bool; ``` -Extension function for the [`Slice{:tact}`][p]. +Extension function for the [`Slice{:tact}`][slice]. -Checks whether the [`Slice{:tact}`][p] is empty (i.e., contains no bits of data and no cell references). Returns `true{:tact}` if it's empty, `false{:tact}` otherwise. +Checks whether the [`Slice{:tact}`][slice] is empty (i.e., contains no bits of data and no cell references). Returns `true{:tact}` if it's empty, `false{:tact}` otherwise. Usage example: @@ -600,7 +638,7 @@ let buzz: Bool = beginCell().asSlice().empty(); // true - Unlike [`Slice.endParse(){:tact}`](#sliceendparse), this function doesn't throw any exceptions even when the [`Slice{:tact}`][p] is empty. + Unlike [`Slice.endParse(){:tact}`](#sliceendparse), this function doesn't throw any exceptions even when the [`Slice{:tact}`][slice] is empty. @@ -610,9 +648,9 @@ let buzz: Bool = beginCell().asSlice().empty(); // true extends fun dataEmpty(slice: Slice): Bool; ``` -Extension function for the [`Slice{:tact}`][p]. +Extension function for the [`Slice{:tact}`][slice]. -Checks whether the [`Slice{:tact}`][p] has no bits of data. Returns `true{:tact}` if it has no data, `false{:tact}` otherwise. +Checks whether the [`Slice{:tact}`][slice] has no bits of data. Returns `true{:tact}` if it has no data, `false{:tact}` otherwise. Usage example: @@ -630,9 +668,9 @@ let buzz: Bool = s2.dataEmpty(); // false extends fun refsEmpty(slice: Slice): Bool; ``` -Extension function for the [`Slice{:tact}`][p]. +Extension function for the [`Slice{:tact}`][slice]. -Checks whether the [`Slice{:tact}`][p] has no references. Returns `true{:tact}` if it has no references, `false{:tact}` otherwise. +Checks whether the [`Slice{:tact}`][slice] has no references. Returns `true{:tact}` if it has no references, `false{:tact}` otherwise. Usage example: @@ -648,9 +686,9 @@ let buzz: Bool = beginCell().asSlice().refsEmpty(); // true extends fun endParse(self: Slice); ``` -Extension function for the [`Slice{:tact}`][p]. +Extension function for the [`Slice{:tact}`][slice]. -Checks whether the [`Slice{:tact}`][p] is empty (i.e., contains no bits of data and no cell references). If it's not, throws an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. +Checks whether the [`Slice{:tact}`][slice] is empty (i.e., contains no bits of data and no cell references). If it's not, throws an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. Usage examples: @@ -670,9 +708,9 @@ try { extends fun hash(self: Slice): Int; ``` -Extension function for the [`Slice{:tact}`][p]. +Extension function for the [`Slice{:tact}`][slice]. -Calculates and returns a hash of the [`Slice{:tact}`][p] as an [`Int{:tact}`][int]. +Calculates and returns an [`Int{:tact}`][int] value of the [SHA-256][sha-2] hash of the [standard `Cell{:tact}` representation][std-repr] of the given [`Slice{:tact}`][slice]. Usage example: @@ -687,9 +725,9 @@ let fizz: Int = s.hash(); extends fun asCell(self: Slice): Cell; ``` -Extension function for the [`Slice{:tact}`][p]. +Extension function for the [`Slice{:tact}`][slice]. -Converts the [`Slice{:tact}`][p] to a [`Cell{:tact}`][p] and returns it. Alias to `beginCell().storeSlice(self).endCell(){:tact}`. +Converts the [`Slice{:tact}`][slice] to a [`Cell{:tact}`][cell] and returns it. Alias to `beginCell().storeSlice(self).endCell(){:tact}`. Usage example: @@ -709,7 +747,7 @@ extends fun asSlice(self: Address): Slice; Extension function for the [`Address{:tact}`][p]. -Converts the [`Address{:tact}`][p] to a [`Slice{:tact}`][p] and returns it. Alias to `beginCell().storeAddress(self).asSlice(){:tact}`. +Converts the [`Address{:tact}`][p] to a [`Slice{:tact}`][slice] and returns it. Alias to `beginCell().storeAddress(self).asSlice(){:tact}`. Usage example: @@ -729,7 +767,7 @@ extends fun toCell(self: Struct): Cell; Extension function for any structure type [Struct][struct]. -Converts the [Struct][struct] to a [`Cell{:tact}`][p] and returns it. +Converts the [Struct][struct] to a [`Cell{:tact}`][cell] and returns it. Usage example: @@ -755,9 +793,9 @@ extends fun fromCell(self: Struct, cell: Cell): Struct; Extension function for any structure type [Struct][struct]. -Converts a [`Cell{:tact}`][p] into the specified [Struct][struct] and returns that [Struct][struct]. +Converts a [`Cell{:tact}`][cell] into the specified [Struct][struct] and returns that [Struct][struct]. -Attempts to pass a [`Cell{:tact}`][p] with layout different from the specified [Struct][struct] or to load more data than a [`Cell{:tact}`][p] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. +Attempts to pass a [`Cell{:tact}`][cell] with layout different from the specified [Struct][struct] or to load more data than a [`Cell{:tact}`][cell] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. Usage examples: @@ -790,9 +828,9 @@ extends fun fromSlice(self: Struct, cell: Slice): Struct; Extension function for any structure type [Struct][struct]. -Converts a [`Slice{:tact}`][p] into the specified [Struct][struct] and returns that [Struct][struct]. +Converts a [`Slice{:tact}`][slice] into the specified [Struct][struct] and returns that [Struct][struct]. -Attempts to pass a [`Slice{:tact}`][p] with layout different from the specified [Struct][struct] or to load more data than a [`Slice{:tact}`][p] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. +Attempts to pass a [`Slice{:tact}`][slice] with layout different from the specified [Struct][struct] or to load more data than a [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. Usage examples: @@ -825,7 +863,7 @@ extends fun toCell(self: Message): Cell; Extension function for any message type [Message][message]. -Converts the [Message][message] to a [`Cell{:tact}`][p] and returns it. +Converts the [Message][message] to a [`Cell{:tact}`][cell] and returns it. Usage example: @@ -851,9 +889,9 @@ extends fun fromCell(self: Message, cell: Cell): Message; Extension function for any message type [Message][message]. -Converts a [`Cell{:tact}`][p] into the specified [Message][message] and returns that [Message][message]. +Converts a [`Cell{:tact}`][cell] into the specified [Message][message] and returns that [Message][message]. -Attempts to pass a [`Cell{:tact}`][p] with layout different from the specified [Message][message] or to load more data than a [`Cell{:tact}`][p] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. +Attempts to pass a [`Cell{:tact}`][cell] with layout different from the specified [Message][message] or to load more data than a [`Cell{:tact}`][cell] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. Usage examples: @@ -886,9 +924,9 @@ extends fun fromSlice(self: Message, cell: Slice): Message; Extension function for any message type [Message][message]. -Converts a [`Slice{:tact}`][p] into the specified [Message][message] and returns that [Message][message]. +Converts a [`Slice{:tact}`][slice] into the specified [Message][message] and returns that [Message][message]. -Attempts to pass a [`Slice{:tact}`][p] with layout different from the specified [Message][message] or to load more data than a [`Slice{:tact}`][p] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. +Attempts to pass a [`Slice{:tact}`][slice] with layout different from the specified [Message][message] or to load more data than a [`Slice{:tact}`][slice] contains throw an exception with [exit code 9](/book/exit-codes#9): `Cell underflow`. Usage examples: @@ -912,43 +950,17 @@ fun cautiousParse(payload: Slice): TripleAxe? { } ``` -## emptyCell - -```tact -fun emptyCell(): Cell; -``` - -Creates and returns an empty [`Cell{:tact}`][p] (without data and references). Alias to `beginCell().endCell(){:tact}`. - -Usage example: - -```tact -let fizz: Cell = emptyCell(); -let buzz: Cell = beginCell().endCell(); - -fizz == buzz; // true -``` - -## emptySlice - -```tact -fun emptySlice(): Slice; -``` - -Creates and returns an empty [`Slice{:tact}`][p] (without data and references). Alias to `emptyCell().asSlice(){:tact}`. - -Usage example: - -```tact -let fizz: Slice = emptySlice(); -let buzz: Slice = emptyCell().asSlice(); - -fizz == buzz; // true -``` - [p]: /book/types#primitive-types [bool]: /book/types#booleans [int]: /book/integers +[cell]: /book/cells#cells +[builder]: /book/cells#builders +[slice]: /book/cells#slices [map]: /book/maps [struct]: /book/structs-and-messages#structs [message]: /book/structs-and-messages#messages + +[std-repr]: /book/cells#cells-representation + +[tlb]: https://docs.ton.org/develop/data-formats/tl-b-language +[sha-2]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard diff --git a/pages/ref/core-common.mdx b/pages/ref/core-common.mdx index aea32e14..167e55f5 100644 --- a/pages/ref/core-common.mdx +++ b/pages/ref/core-common.mdx @@ -95,7 +95,7 @@ Field | Type | Description `bounced` | [`Bool{:tact}`][bool] | [Bounced](https://ton.org/docs/learn/overviews/addresses#bounceable-vs-non-bounceable-addresses) flag of the incoming message. `sender` | [`Address{:tact}`][p] | Internal address of the sender on the TON blockchain. `value` | [`Int{:tact}`][int] | Amount of [nanoToncoins](/book/integers#nanotoncoin) in a message. -`raw` | [`Slice{:tact}`][p] | The remainder of the message as a [`Slice{:tact}`][p]. It follows [internal message layout](https://docs.ton.org/develop/smart-contracts/messages#message-layout) of TON starting from the destination [`Address{:tact}`][p] (`dest:MsgAddressInt ` in [TL-B notation](https://docs.ton.org/develop/data-formats/tl-b-language)). +`raw` | [`Slice{:tact}`][slice] | The remainder of the message as a [`Slice{:tact}`][slice]. It follows [internal message layout](https://docs.ton.org/develop/smart-contracts/messages#message-layout) of TON starting from the destination [`Address{:tact}`][p] (`dest:MsgAddressInt ` in [TL-B notation](https://docs.ton.org/develop/data-formats/tl-b-language)). Usage example: @@ -238,9 +238,10 @@ emit("Catch me if you can, Mr. Holmes".asComment()); // asComment() converts a S To analyze `emit(){:tact}` calls, one has to look at [external messages](/book/external) produced by the contract. Read more: [Logging via `emit(){:tact}`](/book/debug#logging). - + [p]: /book/types#primitive-types [bool]: /book/types#booleans [int]: /book/integers +[slice]: /book/cells#slices diff --git a/pages/ref/core-comptime.mdx b/pages/ref/core-comptime.mdx index f092976c..1f539442 100644 --- a/pages/ref/core-comptime.mdx +++ b/pages/ref/core-comptime.mdx @@ -28,7 +28,7 @@ contract Example { fun cell(bocBase64: String): Cell; ``` -A compile-time function that embeds a base64-encoded [BoC](https://docs.ton.org/develop/data-formats/cell-boc#bag-of-cells) `bocBase64` as a [`Cell{:tact}`][p] into the contract. +A compile-time function that embeds a base64-encoded [BoC](https://docs.ton.org/develop/data-formats/cell-boc#bag-of-cells) `bocBase64` as a [`Cell{:tact}`][cell] into the contract. Usage example: @@ -71,3 +71,4 @@ contract Example { [p]: /book/types#primitive-types [bool]: /book/types#booleans [int]: /book/integers +[cell]: /book/cells#cells diff --git a/pages/ref/core-debug.mdx b/pages/ref/core-debug.mdx index 66d6abac..f992b722 100644 --- a/pages/ref/core-debug.mdx +++ b/pages/ref/core-debug.mdx @@ -54,7 +54,7 @@ Can be applied to the following list of types and values: * [`Int{:tact}`][int] * [`Bool{:tact}`][bool] * [`Address{:tact}`][p] -* [`Builder{:tact}`][p], [`Cell{:tact}`][p] or [`Slice{:tact}`][p] +* [`Cell{:tact}`][cell], [`Builder{:tact}`][builder] or [`Slice{:tact}`][slice] * [`String{:tact}`][p] or [`StringBuilder{:tact}`][p] * [`map{:tact}`](/book/maps) * [Optionals and `null{:tact}` value](/book/optionals) @@ -73,10 +73,10 @@ dump(false); // Address dump(myAddress()); -// Builder, Cell or Slice -dump(beginCell()); // Builder -dump(emptyCell()); // Cell -dump(emptyCell().asSlice()); // Slice +// Cell, Builder or Slice +dump(emptyCell()); // Cell +dump(beginCell()); // Builder +dump(emptySlice()); // Slice // String or StringBuilder dump("Hello, my name is..."); // String @@ -194,3 +194,6 @@ fun butThisDoesNot() { [p]: /book/types#primitive-types [bool]: /book/types#booleans [int]: /book/integers +[cell]: /book/cells#cells +[builder]: /book/cells#builders +[slice]: /book/cells#slices diff --git a/pages/ref/core-math.mdx b/pages/ref/core-math.mdx index 81bc9680..5d698a61 100644 --- a/pages/ref/core-math.mdx +++ b/pages/ref/core-math.mdx @@ -235,7 +235,7 @@ contract Showcase { fun checkDataSignature(data: Slice, signature: Slice, public_key: Int): Bool; ``` -Checks the [Ed25519][ed] `signature` of the `data` using a `public_key`, similar to [`checkSignature(){:tact}`](#checksignature). If the bit length of `data` is not divisible by $8$, this functions throws an error with [exit code 9](/book/exit-codes#9): `Cell underflow`. Verification itself is being done indirectly: on a [SHA-256][sha2] hash of the `data`. +Checks the [Ed25519][ed] `signature` of the `data` using a `public_key`, similar to [`checkSignature(){:tact}`](#checksignature). If the bit length of `data` is not divisible by $8$, this functions throws an error with [exit code 9](/book/exit-codes#9): `Cell underflow`. Verification itself is being done indirectly: on a [SHA-256][sha-2] hash of the `data`. Returns `true{:tact}` if the signature is valid, `false{:tact}` otherwise. @@ -256,9 +256,9 @@ fun sha256(data: Slice): Int; fun sha256(data: String): Int; ``` -Computes and returns the [SHA-256](https://en.wikipedia.org/wiki/SHA-2#Hash_standard) hash as an $256$-bit unsigned [`Int{:tact}`][int] from a passed [`Slice{:tact}`][p] or [`String{:tact}`][p] `data`. +Computes and returns the [SHA-256][sha-2] hash as an $256$-bit unsigned [`Int{:tact}`][int] from a passed [`Slice{:tact}`][slice] or [`String{:tact}`][p] `data`. -In case `data` is a [`String{:tact}`][p] it should have a number of bits divisible by $8$, and in case it's a [`Slice{:tact}`][p] it must **also** have no references (i.e. only up to 1023 bits of data in total). +In case `data` is a [`String{:tact}`][p] it should have a number of bits divisible by $8$, and in case it's a [`Slice{:tact}`][slice] it must **also** have no references (i.e. only up to 1023 bits of data in total). This function tries to resolve constant string values in [compile-time](/ref/core-comptime) whenever possible. @@ -274,6 +274,7 @@ sha256(someVariableElsewhere); // will try to resolve at compile-time, [p]: /book/types#primitive-types [bool]: /book/types#booleans [int]: /book/integers +[slice]: /book/cells#slices [ed]: https://en.wikipedia.org/wiki/EdDSA#Ed25519 [sha-2]: https://en.wikipedia.org/wiki/SHA-2#Hash_standard diff --git a/pages/ref/core-strings.mdx b/pages/ref/core-strings.mdx index 0e171a6d..d8fdc101 100644 --- a/pages/ref/core-strings.mdx +++ b/pages/ref/core-strings.mdx @@ -2,7 +2,7 @@ import { Callout } from 'nextra-theme-docs' -Strings are immutable sequences of characters, which means that once a [`String{:tact}`][p] is created, it cannot be changed. Strings are useful to store text, and so they can be converted to [`Cell{:tact}`][p] type to be used as message bodies. +Strings are immutable sequences of characters, which means that once a [`String{:tact}`][p] is created, it cannot be changed. Strings are useful to store text, and so they can be converted to [`Cell{:tact}`][cell] type to be used as message bodies. To be able to concatenate strings in a gas-efficient way, use a [`StringBuilder{:tact}`][p]. @@ -56,7 +56,7 @@ let fizz: StringBuilder = beginTailString(); fun beginStringFromBuilder(b: StringBuilder): StringBuilder; ``` -Creates and returns a new [`StringBuilder{:tact}`][p] from existing [`StringBuilder{:tact}`][p] `b`. Useful when you need to serialize an existing [`String{:tact}`][p] to a [`Cell{:tact}`][p] with some other data. +Creates and returns a new [`StringBuilder{:tact}`][p] from existing [`StringBuilder{:tact}`][p] `b`. Useful when you need to serialize an existing [`String{:tact}`][p] to a [`Cell{:tact}`][cell] with some other data. Usage example: @@ -127,7 +127,7 @@ extends fun toCell(self: StringBuilder): Cell; Extension function for the [`StringBuilder{:tact}`][p]. -Returns an assembled [`Cell{:tact}`][p] from a [`StringBuilder{:tact}`][p]. +Returns an assembled [`Cell{:tact}`][cell] from a [`StringBuilder{:tact}`][p]. Usage example: @@ -144,7 +144,7 @@ extends fun toSlice(self: StringBuilder): Slice; Extension function for the [`StringBuilder{:tact}`][p]. -Returns an assembled [`Cell{:tact}`][p] as a [`Slice{:tact}`][p] from a [`StringBuilder{:tact}`][p]. Alias to [`self.toCell().asSlice(){:tact}`](/ref/core-cells#cellasslice). +Returns an assembled [`Cell{:tact}`][cell] as a [`Slice{:tact}`][slice] from a [`StringBuilder{:tact}`][p]. Alias to [`self.toCell().asSlice(){:tact}`](/ref/core-cells#cellasslice). Usage example: @@ -164,9 +164,9 @@ extends fun asSlice(self: String): Slice; Extension function for the [`String{:tact}`][p]. -Returns a [`Slice{:tact}`][p] from a [`String{:tact}`][p] by trying to pack all of its bits into a continuous list of [Cells][p], each referencing the next one and opening them all for future parsing. +Returns a [`Slice{:tact}`][slice] from a [`String{:tact}`][p] by trying to pack all of its bits into a continuous list of [Cells][p], each referencing the next one and opening them all for future parsing. -Note, that there's no indication of how many bytes a particular character could take in the [`Slice{:tact}`][p] or how deep the list of references is going to be, so use this function only if you know what you're doing. +Note, that there's no indication of how many bytes a particular character could take in the [`Slice{:tact}`][slice] or how deep the list of references is going to be, so use this function only if you know what you're doing. Usage example: @@ -192,7 +192,7 @@ extends fun asComment(self: String): Cell; Extension function for the [`String{:tact}`][p]. -Returns a [`Cell{:tact}`][p] from a [`String{:tact}`][p] by prefixing the latter with four null bytes. This format is used for passing text comments as message bodies. +Returns a [`Cell{:tact}`][cell] from a [`String{:tact}`][p] by prefixing the latter with four null bytes. This format is used for passing text comments as message bodies. Usage example: @@ -215,7 +215,7 @@ extends fun fromBase64(self: String): Slice; Extension function for the [`String{:tact}`][p]. -Returns a [`Slice{:tact}`][p] out of the decoded [Base64](https://en.wikipedia.org/wiki/Base64) [`String{:tact}`][p]. Alias to `self.asSlice().fromBase64(){:tact}`. +Returns a [`Slice{:tact}`][slice] out of the decoded [Base64](https://en.wikipedia.org/wiki/Base64) [`String{:tact}`][p]. Alias to `self.asSlice().fromBase64(){:tact}`. Note, that this function is limited and only takes the first $1023$ bits of data from the given [`String{:tact}`][p], without throwing an exception when the [`String{:tact}`][p] is larger (i.e. contains more than $1023$ bits of data). @@ -235,9 +235,9 @@ fizz == buzz; // true extends fun asString(self: Slice): String; ``` -Extension function for the [`Slice{:tact}`][p]. +Extension function for the [`Slice{:tact}`][slice]. -Returns a [`String{:tact}`][p] from a [`Slice{:tact}`][p] by trying to load all of its bits without looking for its references, if any. +Returns a [`String{:tact}`][p] from a [`Slice{:tact}`][slice] by trying to load all of its bits without looking for its references, if any. Note, that this function doesn't look at the references at all and is truncates its output to $1023$ bits, so use it only if you know what you're doing. @@ -257,11 +257,11 @@ fizz == buzz; // true, but be careful as it's not always the case extends fun fromBase64(self: Slice): Slice; ``` -Extension function for the [`Slice{:tact}`][p]. +Extension function for the [`Slice{:tact}`][slice]. -Returns a new [`Slice{:tact}`][p] out of the decoded [Base64](https://en.wikipedia.org/wiki/Base64) [`Slice{:tact}`][p]. +Returns a new [`Slice{:tact}`][slice] out of the decoded [Base64](https://en.wikipedia.org/wiki/Base64) [`Slice{:tact}`][slice]. -Note, that this function is limited and only takes the first $1023$ bits of data from the given [`Slice{:tact}`][p], without throwing an exception if the [`Slice{:tact}`][p] has more data (i.e., when it has any references). +Note, that this function is limited and only takes the first $1023$ bits of data from the given [`Slice{:tact}`][slice], without throwing an exception if the [`Slice{:tact}`][slice] has more data (i.e., when it has any references). Usage example: @@ -346,3 +346,5 @@ let fizz: String = community.toString(); [p]: /book/types#primitive-types [bool]: /book/types#booleans [int]: /book/integers +[cell]: /book/cells#cells +[slice]: /book/cells#slices diff --git a/pages/ref/standard-libraries.mdx b/pages/ref/standard-libraries.mdx index 8cdf9027..2dfcbd21 100644 --- a/pages/ref/standard-libraries.mdx +++ b/pages/ref/standard-libraries.mdx @@ -16,7 +16,7 @@ import "@stdlib/deploy"; Library | Description | Commonly used APIs :----------------------- | :--------------------------------------------------------------- | :----------------- [`@stdlib/config`][1] | Config and elector address retrieval. | [`getConfigAddress(){:tact}`][gca], [`getElectorAddress(){:tact}`][gea] -[`@stdlib/content`][2] | Encoding off-chain link [strings][p] to a [`Cell{:tact}`][p]. | [`createOffchainContent(){:tact}`][coff] +[`@stdlib/content`][2] | Encoding off-chain link [strings][p] to a [`Cell{:tact}`][cell]. | [`createOffchainContent(){:tact}`][coff] [`@stdlib/deploy`][3] | Unified mechanism for deployments. | [`Deployable{:tact}`][dep], [`FactoryDeployable{:tact}`][fcd] [`@stdlib/dns`][4] | Resolution of [DNS][dns] names. | [`DNSResolver{:tact}`][dnsr], [`dnsInternalVerify(){:tact}`][dnsi] [`@stdlib/ownable`][5] | Traits for ownership management. | [`Ownable{:tact}`][own], [`OwnableTransferable{:tact}`][ownt] @@ -46,4 +46,5 @@ Library | Description [res]: /ref/stdlib-stoppable#resumable [p]: /book/types#primitive-types +[cell]: /book/cells#cells [dns]: https://docs.ton.org/participate/web3/dns diff --git a/pages/ref/stdlib-content.mdx b/pages/ref/stdlib-content.mdx index ff26b3da..c0bc918a 100644 --- a/pages/ref/stdlib-content.mdx +++ b/pages/ref/stdlib-content.mdx @@ -1,6 +1,6 @@ # @stdlib/content -Provides a function for encoding an off-chain link from a [`String{:tact}`][p] to a [`Cell{:tact}`][p]. +Provides a function for encoding an off-chain link from a [`String{:tact}`][p] to a [`Cell{:tact}`][cell]. To use this library, import `@stdlib/content`: @@ -16,7 +16,7 @@ import "@stdlib/content"; fun createOffchainContent(link: String): Cell; ``` -Encodes an off-chain `link` from a [`String{:tact}`][p] to a [`Cell{:tact}`][p]. +Encodes an off-chain `link` from a [`String{:tact}`][p] to a [`Cell{:tact}`][cell]. Source code: @@ -33,4 +33,4 @@ fun createOffchainContent(link: String): Cell { * [content.tact](https://github.com/tact-lang/tact/blob/61541b7783098e1af669faccd7d2334c10981c72/stdlib/libs/content.tact) [p]: /book/types#primitive-types - +[cell]: /book/cells#cells diff --git a/pages/ref/stdlib-dns.mdx b/pages/ref/stdlib-dns.mdx index f4812c9c..a0a8e577 100644 --- a/pages/ref/stdlib-dns.mdx +++ b/pages/ref/stdlib-dns.mdx @@ -28,7 +28,7 @@ struct DNSResolveResult { native dnsStringToInternal(str: String): Slice?; ``` -Converts a DNS string to a [`Slice{:tact}`][p] or [`null{:tact}`](/book/optionals), if it's impossible. +Converts a DNS string to a [`Slice{:tact}`][slice] or [`null{:tact}`](/book/optionals), if it's impossible. Source code (FunC): [dns.fc#L1](https://github.com/tact-lang/tact/blob/61541b7783098e1af669faccd7d2334c10981c72/stdlib/libs/dns.fc#L1) @@ -39,7 +39,7 @@ Source code (FunC): [dns.fc#L1](https://github.com/tact-lang/tact/blob/61541b778 native dnsInternalNormalize(src: Slice): Slice; ``` -Normalizes the internal DNS representation of the [`Slice{:tact}`][p]. +Normalizes the internal DNS representation of the [`Slice{:tact}`][slice]. Source code (FunC): [dns.fc#L125](https://github.com/tact-lang/tact/blob/61541b7783098e1af669faccd7d2334c10981c72/stdlib/libs/dns.fc#L125) @@ -50,7 +50,7 @@ Source code (FunC): [dns.fc#L125](https://github.com/tact-lang/tact/blob/61541b7 native dnsInternalVerify(subdomain: Slice): Bool; ``` -Verifies the internal DNS representation of the subdomain [`Slice{:tact}`][p]. +Verifies the internal DNS representation of the subdomain [`Slice{:tact}`][slice]. Source code (FunC): [dns.fc#L81](https://github.com/tact-lang/tact/blob/61541b7783098e1af669faccd7d2334c10981c72/stdlib/libs/dns.fc#L81) @@ -60,7 +60,7 @@ Source code (FunC): [dns.fc#L81](https://github.com/tact-lang/tact/blob/61541b77 fun dnsExtractTopDomainLength(subdomain: Slice): Int; ``` -Calculates length of a top domain in the `subdomain` [`Slice{:tact}`][p]. +Calculates length of a top domain in the `subdomain` [`Slice{:tact}`][slice]. Source code: @@ -86,7 +86,7 @@ fun dnsExtractTopDomainLength(subdomain: Slice): Int { fun dnsExtractTopDomain(subdomain: Slice): Slice; ``` -Extracts top domain from a `subdomain` [`Slice{:tact}`][p]. +Extracts top domain from a `subdomain` [`Slice{:tact}`][slice]. Source code: @@ -103,7 +103,7 @@ fun dnsExtractTopDomain(subdomain: Slice): Slice { fun dnsResolveNext(address: Address): Cell; ``` -Resolves an `address` [`Address{:tact}`][p] into a [`Cell{:tact}`][p]. +Resolves an `address` [`Address{:tact}`][p] into a [`Cell{:tact}`][cell]. Source code: @@ -122,7 +122,7 @@ fun dnsResolveNext(address: Address): Cell { fun dnsResolveWallet(address: Address): Cell; ``` -Resolves a wallet `address` [`Address{:tact}`][p] into a [`Cell{:tact}`][p]. +Resolves a wallet `address` [`Address{:tact}`][p] into a [`Cell{:tact}`][cell]. Source code: @@ -143,7 +143,7 @@ fun dnsResolveWallet(address: Address): Cell { Trait `DNSResolver` provides two helper functions for DNS resolution: 1. [getter function](/book/functions#getter-functions) `dnsresolve(){:tact}`, which corresponds to its [FunC variant](https://docs.ton.org/develop/howto/subresolvers#dnsresolve-code). -2. virtual function `doResolveDNS(){:tact}`, which creates a struct [DNSResolveResult](#dnsresolveresult) out of subdomain [`Slice{:tact}`][p] bits. +2. virtual function `doResolveDNS(){:tact}`, which creates a struct [DNSResolveResult](#dnsresolveresult) out of subdomain [`Slice{:tact}`][slice] bits. Source code: @@ -188,3 +188,5 @@ contract ExampleContract with DNSResolver { * [dns.fc](https://github.com/tact-lang/tact/blob/61541b7783098e1af669faccd7d2334c10981c72/stdlib/libs/dns.fc) [p]: /book/types#primitive-types +[cell]: /book/cells#cells +[slice]: /book/cells#slices