Skip to content

Commit 9b69403

Browse files
committed
Updates
1 parent 19288b3 commit 9b69403

File tree

23 files changed

+151
-68
lines changed

23 files changed

+151
-68
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
2. The terminal output is located in `src/routes/(examples)/+layout.svelte` file.
1010
3. Run `npm run tact-build` to compile the Tact code you just added.
1111

12+
### About the Examples Order
13+
14+
1. Check the order in the `src/routes/(examples)/examples.json` file.
15+
2. The `id` determines the sequence of the examples in the app.
16+
1217
### Running the project
1318

1419
Once you've run `npm install` start a development server:

src/routes/(examples)/01-a-simple-counter/content.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ State variables should be initialized in `init()` that runs on deployment of the
88

99
## Receiving messages
1010

11-
This contract can receive *messages* from users. Unlike getters that are just read-only, messages can do write operations and change the contract's persistent state. Incoming messages are processed in `receive()` methods as transactions and cost gas for the sender.
11+
This contract can receive **_messages_** from users.
12+
13+
Unlike getters that are just read-only, messages can do write operations and change the contract's persistent state. Incoming messages are processed in `receive()` methods as transactions and cost gas for the sender.
1214

1315
After deploying the contract, send the `increment` message by pressing the <span class="mdButton grape">Send increment</span> button in order to increase the counter value by one. Afterwards, call the getter `value()` to see that the value indeed changed.
16+
17+
<div style="padding-left: 1em; margin: 1em 0; position: relative;">
18+
<div style="position: absolute; top: 0; bottom: 0%; left: 0; width: 3px; background-color: green;"></div>
19+
<strong>Info</strong>: We will learn more in details about "getter" functions in the next example.
20+
</div>
Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
# The Deployable Trait
22

3-
Tact doesn't support classical class inheritance, but contracts can implement *traits*. One of the commonly used traits is `Deployable`. It implements a simple receiver for the `Deploy` message which helps deploy contracts in a standard way.
3+
Tact doesn't support classical class inheritance, but contracts can implement **_traits_**.
44

5-
All contracts are deployed by sending them a message. This can be any message, but best practice is to designate the special `Deploy` message for this purpose.
5+
One commonly used trait is `Deployable`, which implements a simple receiver for the `Deploy` message. This helps deploy contracts in a standardized manner.
66

7-
This message has a single field, `queryId`, which is provided by the deployer (normally zero). If the deploy succeeds, the contract will reply with the message `DeployOk` and echo the same `queryId` in the response.
7+
All contracts are deployed by sending them a message. While any message can be used for this purpose, best practice is to use the special `Deploy` message.
8+
9+
This message has a single field, `queryId`, provided by the deployer (usually set to zero). If the deployment succeeds, the contract will reply with a `DeployOk` message and echo the same `queryId` in the response.
10+
11+
---
812

913
If you're using Tact's [auto-generated](https://docs.tact-lang.org/tools/typescript#tact-contract-in-typescript) TypeScript classes to deploy, sending the deploy message should look like:
1014

1115
```ts
1216
const msg = { $$type: "Deploy", queryId: 0n };
13-
await contract.send(sender, { value: toNano(1) }, msg);
17+
await contract.send(sender, { value: toNano(1) }, msg);
1418
```
1519

16-
You can see the implementation of the trait [here](https://github.com/tact-lang/tact/blob/main/stdlib/libs/deploy.tact). Notice that the file *deploy.tact* needs to be imported from the standard library using the `import` keyword.
20+
You can see the implementation of the trait [here](https://github.com/tact-lang/tact/blob/main/stdlib/libs/deploy.tact). Notice that the file **_deploy.tact_** needs to be imported from the standard library using the `import` keyword.

src/routes/(examples)/02-addresses/content.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
`Address` is another primitive data type. It represents standard addresses on the TON blockchain. Every smart contract on TON is identifiable by its address. Think of this as a unique id.
44

5-
TON is divided into multiple chains called *workchains*. This allows to balance the load more effectively. One of the internal fields of the address is the workchain id:
5+
TON is divided into multiple chains called _workchains_. This allows to balance the load more effectively. One of the internal fields of the address is the workchain id:
66

7-
* `0` - The standard workchain, for regular users. Your contracts will be here.
7+
- `0` - The standard workchain, for regular users. Your contracts will be here.
88

9-
* `-1` - The masterchain, usually for validators. Gas on this chain is significantly more expensive, but you'll probably never use it.
9+
- `-1` - The masterchain, usually for validators. Gas on this chain is significantly more expensive, but you'll probably never use it.
1010

1111
There are multiple ways on TON to [represent](https://docs.ton.org/learn/overviews/addresses#bounceable-vs-non-bounceable-addresses) the same address. Notice in the contract that the bouncable and non-bouncable representations of the same address actually generate the exact same value. Inside the contract, it doesn't matter which representation you use.
1212

1313
## State costs
1414

15-
Most addresses take 264-bit to store (8-bit for the workchain id and 256-bit for the account id). This means that storing 1000 addresses [costs](https://ton.org/docs/develop/smart-contracts/fees#how-to-calculate-fees) about 0.189 TON per year.
15+
Most addresses take 264-bit to store (8-bit for the workchain id and 256-bit for the account id). **This means that storing 1000 addresses [costs](https://ton.org/docs/develop/smart-contracts/fees#how-to-calculate-fees) about 0.189 TON per year.**

src/routes/(examples)/02-bools/content.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ The only supported operations with booleans are `&&` `||` `!` - if you try to ad
88

99
## State costs
1010

11-
Persisting bools to state is very space-efficient, they only take 1-bit. Storing 1000 bools in state [costs](https://ton.org/docs/develop/smart-contracts/fees#how-to-calculate-fees) about 0.00072 TON per year.
11+
Persisting bools to state is very space-efficient, they only take 1-bit. **Storing 1000 bools in state [costs](https://ton.org/docs/develop/smart-contracts/fees#how-to-calculate-fees) about 0.00072 TON per year.**
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# Constants
22

3-
Unlike variables, constants cannot change. Their values are calculated in *compile-time* and cannot change during execution.
3+
Unlike variables, constants cannot change. Their values are calculated in _compile-time_ and cannot change during execution.
44

55
Constant initializations must be relatively simple and only rely on values known during compilation. If you add two numbers for example, the compiler will calculate the result during build and put the result in your compiled code.
66

7-
You can read constants both in *receivers* and in *getters*.
7+
You can read constants both in **_receivers_** and in **_getters_**.
88

9-
Unlike contract variables, constants don't consume space in persistent state. Their values are stored directly in the code cell.
9+
Unlike contract variables, **constants don't consume space in persistent state. Their values are stored directly in the code cell.**
1010

11-
There isn't much difference between constants defined outside of a contract and inside the contract. Those defined outside can be used by other contracts in your project.
11+
There isn't much difference between constants defined outside of a contract and inside the contract. Those defined outside can be used by other contracts in your project.
Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
# Integer Operations
22

3-
Since all runtime calculations with integers are done at 257-bit, overflows are quite rare. An overflow can happen if the result of a math operation is too big to fit. For example, multiplying 2^256 by 2^256 will not fit within 257-bit.
3+
Since all runtime calculations with integers are done at 257-bit, overflows are quite rare. An overflow can happen if the result of a math operation is too big to fit.
44

5-
Nevertheless, if any math operation overflows, an exception will be thrown and the transaction will fail. You can say that Tact's math is safe by default.
5+
**For example, multiplying 2^256 by 2^256 will not fit within 257-bit.**
66

7-
There's no problem with mixing variables of different state sizes in the same calculation. In runtime, they are all the same type - always 257-bit signed. This is the largest supported integer type, so they all fit.
7+
Nevertheless, if any math operation overflows, an exception will be thrown, and the transaction will fail. You could say that Tact's math is safe by default.
88

9-
## Decimal point with integers
9+
There is no problem with mixing variables of different state sizes in the same calculation. At runtime, they are all the same type—**always 257-bit signed**. This is the largest supported integer type, so they all fit.
1010

11-
Arithmetics with dollars, for example, requires 2 decimal places. How can we represent the number `1.25` if we can only work with integers? The answer is to work with *cents*. So `1.25` becomes `125`. We just remember that the two lowest digits are coming after the decimal point.
11+
## Decimal Point with Integers
1212

13-
In the same way, working with TON coins has 9 decimal places instead of 2. So the amount 1.25 TON which can be coded in Tact as `ton("1.25")` is actually the number `1250000000` - we call these *nano-tons* instead of cents.
13+
Arithmetic with dollars, for example, requires two decimal places. How can we represent the number `1.25` if we are only able to work with integers? The solution is to work with _cents_. In this way, `1.25` becomes `125`. We simply remember that the two rightmost digits represent the numbers after the decimal point.
14+
15+
Similarly, working with TON coins requires nine decimal places instead of two. Therefore, the amount of 1.25 TON, which can be represented in Tact as `ton("1.25")`, is actually the number `1250000000`.
16+
17+
**We refer to these as _nano-tons_ rather than cents.**

src/routes/(examples)/02-integers/content.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ Tact supports a number of primitive data types that are tailored for smart contr
44

55
`Int` is the primary number type. Math in smart contracts is always done with integers and never with floating points since floats are [unpredictable](https://learn.microsoft.com/en-us/cpp/build/why-floating-point-numbers-may-lose-precision).
66

7-
The runtime type `Int` is *always* 257-bit signed, so all runtime calculations are done at 257-bit. This should be large enough for pretty much anything you need as it's large enough to hold the number of atoms in the universe.
7+
The runtime type `Int` is _always_ 257-bit signed, so all runtime calculations are done at 257-bit. This should be large enough for pretty much anything you need as it's large enough to hold the number of atoms in the universe.
88

99
Persistent state variables can be initialized inline or inside `init()`. If you forget to initialize a state variable, the code will not compile.
1010

1111
## State costs
1212

1313
When encoding `Int` to persistent state, we will usually use smaller representations than 257-bit to reduce storage cost. The persistent state size is specified in every declaration of a state variable after the `as` keyword.
1414

15-
Storing 1000 257-bit integers in state [costs](https://ton.org/docs/develop/smart-contracts/fees#how-to-calculate-fees) about 0.184 TON per year. Storing 1000 32-bit integers only costs 0.023 TON per year by comparison.
15+
- Storing 1000 257-bit integers in state [costs](https://ton.org/docs/develop/smart-contracts/fees#how-to-calculate-fees) about **0.184 TON** per year.
16+
- Storing 1000 32-bit integers only costs **0.023 TON** per year by comparison.

src/routes/(examples)/02-variables/content.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ The most important variables are those that are persisted in state and retain th
44

55
Persisting data in state costs gas. The contract must pay rent periodically from its balance. State storage is expensive, about [4 TON per MB per year](https://ton.org/docs/develop/smart-contracts/fees#how-to-calculate-fees). If the contract runs out of balance, the data will be deleted. If you need to store large amounts of data, like images, a service like [TON Storage](https://ton.org/docs/participate/ton-storage/storage-faq) would be more suitable.
66

7-
Persistent state variables can only change in *receivers* by sending messages as transactions. Sending these transactions will cost gas to users.
7+
Persistent state variables can only change in _receivers_ by sending messages as transactions. **Sending these transactions will cost gas to users.**
88

9-
Executing *getters* is read-only, they can access all variables, but cannot change state variables. They are free to execute and don't cost any gas.
9+
Executing _getters_ is read-only, they can access all variables, but cannot change state variables. They are free to execute and don't cost any gas.
1010

11-
Local variables like `localVar1` are temporary. They're not persisted to state. You can define them in any function and they will only exist in run-time during the execution of the function. You can change their value in *getters* too.
11+
Local variables like `localVar1` are temporary. They're not persisted to state. You can define them in any function and they will only exist in run-time during the execution of the function. You can change their value in _getters_ too.

src/routes/(examples)/03-getters/content.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Getters are special contract functions that allow users to query information from the contract.
44

5-
Contract methods starting with the prefix `get fun` are all getters. You can define as many getters are you want. Each getter must also specify its return type - `counter()` for example returns an `Int`.
5+
Contract methods starting with the prefix `get fun` are all getters. You can define as many getters are you want. Each getter must also specify its return type - `counter()` for example returns an `Int`.
66

77
Calling getters is free and does not cost gas. The call is executed by a full node and doesn't go through consensus with all the validators nor is added to a new block.
88

@@ -12,6 +12,15 @@ If we were to omit the `get` keyword from the function declaration of a getter,
1212

1313
## Getters between contracts
1414

15-
A contract cannot execute a getter of another contract. Getters are only executable by end-users off-chain. Since contracts are running on-chain, they do not have access to each other's getters.
15+
**A contract cannot execute a getter of another contract.**
1616

17-
So, if you can't call a getter, how can two contracts communicate? The only way for contracts to communicate on-chain is by sending messages to each other. Messages are handled in *receivers*.
17+
Getters are only executable by end-users off-chain. Since contracts are running on-chain, they do not have access to each other's getters.
18+
19+
So, if you can't call a getter, how can two contracts communicate?
20+
21+
The only way for contracts to communicate on-chain is by sending messages to each other. Messages are handled in _receivers_.
22+
23+
<div style="padding-left: 1em; margin: 1em 0; position: relative;">
24+
<div style="position: absolute; top: 0; bottom: 0%; left: 0; width: 3px; background-color: green;"></div>
25+
<strong>Info</strong>: TON Blockchain is an asynchronous blockchain, which means that smart contracts can interact with each other only by sending messages.
26+
</div>

0 commit comments

Comments
 (0)