Skip to content

Commit

Permalink
tests: Equality on addresses, slices, cells (#1279)
Browse files Browse the repository at this point in the history
* Semantics tests for equality on addresses, slices, cells

* feat(docs): equality of `myAddress()` and `contractAddress(initOf CurrentContract())`

And small updates of similar descriptions on the Operators page of the
Book

* Tests of equality of slices with references to cells

* Tests of equality of cells manually built using builders (with cells having references and without)

---------

Co-authored-by: Novus Nota <[email protected]>
  • Loading branch information
jeshecdom and novusnota authored Jan 8, 2025
1 parent b19662f commit 408995b
Show file tree
Hide file tree
Showing 4 changed files with 510 additions and 4 deletions.
23 changes: 21 additions & 2 deletions docs/src/content/docs/book/expressions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ contract ExampleContract {

## `initOf`

Expression `initOf{:tact}` computes initial state (`StateInit{:tact}`) of a [contract](/book/contracts):
Expression `initOf{:tact}` computes initial state, i.e. `StateInit{:tact}` of a [contract](/book/contracts):

```tact
// argument values for the init() function of the contract
Expand All @@ -263,13 +263,32 @@ initOf ExampleContract(
);
```

Where `StateInit{:tact}` is a built-in [Struct][s], that consists of:
The `StateInit{:tact}` is a built-in [Struct][s], that consists of:

Field | Type | Description
:----- | :----------------- | :----------
`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)

:::note

For workchain $0$, the [`Address{:tact}`][p] of the current contract obtained by calling the [`myAddress(){:tact}`](/ref/core-common#myaddress) function is identical to the one that can be obtained by calling the [`contractAddress(){:tact}`](/ref/core-common#contractaddress) function with the initial state of the current contract computed via `initOf{:tact}`:

```tact {6}
contract TheKingPrawn {
receive("keeping the address") {
let myAddr1 = myAddress();
let myAddr2 = contractAddress(initOf TheKingPrawn());
myAddr1 == myAddr2; // true
}
}
```

However, if you only need the address of the current contract at runtime and not its `StateInit{:tact}`, use the [`myAddress(){:tact}`](/ref/core-common#myaddress) function, as it consumes **significantly** less gas.

:::

[p]: /book/types#primitive-types
[cell]: /book/cells#cells
[s]: /book/structs-and-messages#structs
Expand Down
16 changes: 14 additions & 2 deletions docs/src/content/docs/book/operators.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ two / 1; // 2

:::note

Note that the following relationship between the division and modulo operators always holds for `Int{:tact}` type:
The following relationship between the division and [modulo](#binary-modulo) operators always holds for `Int{:tact}` type:

```tact
a / b * b + a % b == a; // true for any Int values of `a` and `b`,
Expand All @@ -247,12 +247,24 @@ two % 1; // 1
-1 % -5; // -1
```

The simplest way to avoid confusion between the two is to prefer using positive values via [`abs(x: Int){:tact}`](/ref/core-math#abs):
The simplest way to avoid confusing getting the modulo with getting the remainder is to [use only unsigned integers](/book/security-best-practices#misuse-of-signed-integers). Alternatively, consider using [`abs(){:tact}`](/ref/core-math#abs) function to ensure non-negative values:

```tact
abs(-1) % abs(-5); // 1
```

:::note

The following relationship between the [division](#binary-divide) and modulo operators always holds for `Int{:tact}` type:

```tact
a / b * b + a % b == a; // true for any Int values of `a` and `b`,
// except when `b` is equal to 0 and we divide `a` by 0,
// which is an attempt to divide by zero resulting in an error
```

:::

:::note

Did you know, that in JavaScript `%{:tact}` works as a _remainder_ operator, but not _modulo_ operator (like in Tact)?\
Expand Down
Loading

0 comments on commit 408995b

Please sign in to comment.