├── .github
├── temp-archive
│ ├── description-of-guides.mdx
│ ├── guides
│ │ ├── _meta.js
│ │ ├── getting-started.mdx
│ │ └── getting-started
│ │ │ ├── _meta.js
│ │ │ ├── deploy.mdx
│ │ │ ├── first.mdx
│ │ │ └── test.mdx
│ └── learn
│ │ ├── _meta.json
│ │ ├── cookbook.mdx
│ │ ├── design.mdx
│ │ ├── hello
│ │ ├── _meta.json
│ │ ├── hello-1.mdx
│ │ ├── hello-2.mdx
│ │ ├── hello-3.mdx
│ │ ├── hello-4.mdx
│ │ ├── hello-5.mdx
│ │ └── hello-6.mdx
│ │ ├── jetton
│ │ ├── _meta.json
│ │ ├── jetton-1.mdx
│ │ ├── jetton-2.mdx
│ │ └── jetton-3.mdx
│ │ └── wallet
│ │ ├── _meta.json
│ │ ├── wallet-1.mdx
│ │ ├── wallet-2.mdx
│ │ └── wallet-3.mdx
└── workflows
│ ├── nextjs.yml
│ └── test-build-nextjs.yml
├── .gitignore
├── README.md
├── components
└── icons
│ ├── arrow-right.svg
│ ├── box.svg
│ ├── brush.svg
│ ├── cards.svg
│ ├── chevron-right.svg
│ ├── cloud.svg
│ ├── code.svg
│ ├── diagram.svg
│ ├── dropper.svg
│ ├── file.svg
│ ├── files.svg
│ ├── folder-tree.svg
│ ├── formula.svg
│ ├── gear.svg
│ ├── globe.svg
│ ├── id-card.svg
│ ├── index.ts
│ ├── lightning.svg
│ ├── link.svg
│ ├── markdown.svg
│ ├── newsletter.svg
│ ├── one.svg
│ ├── picture.svg
│ ├── rows.svg
│ ├── stars.svg
│ ├── switch.svg
│ ├── table.svg
│ ├── tailwind.svg
│ ├── terminal.svg
│ └── warning.svg
├── cspell.json
├── grammars
├── grammar-func.json
├── grammar-ohm.json
└── grammar-tact.json
├── next-env.d.ts
├── next.config.js
├── package.json
├── pages
├── _app.mdx
├── _document.tsx
├── _meta.js
├── book
│ ├── _meta.js
│ ├── bounced.mdx
│ ├── cells.mdx
│ ├── config.mdx
│ ├── constants.mdx
│ ├── contracts.mdx
│ ├── cs
│ │ ├── _meta.js
│ │ ├── from-func.mdx
│ │ └── from-solidity.mdx
│ ├── debug.mdx
│ ├── deploy.mdx
│ ├── exit-codes.mdx
│ ├── expressions.mdx
│ ├── external.mdx
│ ├── func.mdx
│ ├── functions.mdx
│ ├── import.mdx
│ ├── index.mdx
│ ├── integers.mdx
│ ├── lifecycle.mdx
│ ├── maps.mdx
│ ├── masterchain.mdx
│ ├── message-mode.mdx
│ ├── operators.mdx
│ ├── optionals.mdx
│ ├── programmatic.mdx
│ ├── receive.mdx
│ ├── send.mdx
│ ├── statements.mdx
│ ├── structs-and-messages.mdx
│ ├── types.mdx
│ └── upgrades.mdx
├── cookbook
│ ├── _meta.js
│ ├── access.mdx
│ ├── algo.mdx
│ ├── data-structures.mdx
│ ├── dexes
│ │ ├── _meta.js
│ │ ├── dedust.mdx
│ │ └── stonfi.mdx
│ ├── index.mdx
│ ├── jettons.mdx
│ ├── misc.mdx
│ ├── multi-communication.mdx
│ ├── nfts.mdx
│ ├── random.mdx
│ ├── single-communication.mdx
│ ├── time.mdx
│ └── type-conversion.mdx
├── ecosystem
│ ├── _meta.js
│ ├── index.mdx
│ └── tools
│ │ ├── _meta.js
│ │ ├── jetbrains.mdx
│ │ ├── misti.mdx
│ │ ├── overview.mdx
│ │ ├── typescript.mdx
│ │ └── vscode.mdx
├── index.mdx
└── ref
│ ├── _meta.js
│ ├── core-advanced.mdx
│ ├── core-base.mdx
│ ├── core-cells.mdx
│ ├── core-common.mdx
│ ├── core-comptime.mdx
│ ├── core-debug.mdx
│ ├── core-math.mdx
│ ├── core-random.mdx
│ ├── core-strings.mdx
│ ├── evolution
│ ├── OTP-001.mdx
│ ├── OTP-002.mdx
│ ├── OTP-003.mdx
│ ├── OTP-004.mdx
│ ├── OTP-005.mdx
│ ├── OTP-006.mdx
│ ├── _meta.js
│ └── overview.mdx
│ ├── index.mdx
│ ├── spec.mdx
│ ├── standard-libraries.mdx
│ ├── stdlib-config.mdx
│ ├── stdlib-content.mdx
│ ├── stdlib-deploy.mdx
│ ├── stdlib-dns.mdx
│ ├── stdlib-ownable.mdx
│ └── stdlib-stoppable.mdx
├── public
├── abi-and-tlb
│ └── tact-abi-tlb-1.png
├── banner.jpeg
├── favicon.png
├── tact-hello-world
│ ├── tact-compile-success.jpg
│ ├── tact-compiler-scheme.png
│ ├── tact-deployment-process-1.png
│ ├── tact-deployment-process-2.png
│ ├── tact-deployment-process-3.png
│ ├── tact-deployment-process-4-b.png
│ ├── tact-hello-world-1.png
│ ├── tact-hello-world-3.png
│ ├── tact-hello-world-4.png
│ ├── tact-hello-world-5.png
│ ├── tact-hello-world-6.png
│ └── tact-hello-world-7.png
├── tact-jetton
│ ├── tact-jetton-1.png
│ ├── tact-jetton-10.png
│ ├── tact-jetton-11.png
│ ├── tact-jetton-2.png
│ ├── tact-jetton-5.png
│ ├── tact-jetton-6-b.png
│ ├── tact-jetton-6.png
│ ├── tact-jetton-7.png
│ ├── tact-jetton-8.png
│ └── tact-jetton-9.png
└── tact-wallet
│ ├── tact-deployment-1.png
│ └── tact-deployment-2.png
├── scripts
├── proposals-generate.js
└── redirects-generate.js
├── theme.config.jsx
├── tsconfig.json
└── yarn.lock
/.github/temp-archive/description-of-guides.mdx:
--------------------------------------------------------------------------------
1 | import { Steps } from 'nextra/components'
2 |
3 | [Guides](/book/guides/getting-started) are in-depth articles describing how to make a specific project or explore certain ideas of Tact and TON with respect to their implications and applications in real-life contracts.
4 |
5 |
6 |
11 |
12 |
--------------------------------------------------------------------------------
/.github/temp-archive/guides/_meta.js:
--------------------------------------------------------------------------------
1 | export default {
2 | 'getting-started': 'Getting started',
3 | }
4 |
--------------------------------------------------------------------------------
/.github/temp-archive/guides/getting-started.mdx:
--------------------------------------------------------------------------------
1 | # Welcome to Tact
2 |
3 | There are two ways to start with Tact: using a template or starting from scratch.
4 |
5 | We recommend using a template, as it contains a **simple contract** that can be deployed to the TON blockchain, along with examples of implementing unit tests and helper functions for contract deployment.
6 |
7 | ## Getting started from template
8 |
9 | To get started, you can use the template project. It contains a simple contract that can be deployed to the TON blockchain, as well as examples of implementing unit tests and helper functions for contract deployment.
10 |
11 | > To create a project from the template, simply create a new repository from the template project: https://github.com/tact-lang/tact-template.
12 |
13 | ## Getting started from scratch
14 |
15 | Tact is distributed via `npm` package manager and is meant to be installed to TypeScript/JavaScript projects:
16 |
17 | ```bash
18 | yarn add @tact-lang/compiler
19 | ```
20 |
21 | Then you need to create a `tact.config.json` file in the root of your project. It should contain the following:
22 |
23 | ```json
24 | {
25 | "projects": [
26 | {
27 | "name": "sample",
28 | "path": "./sources/contract.tact",
29 | "output": "./sources/output"
30 | }
31 | ]
32 | }
33 | ```
34 |
35 | Add an example contract to `./sources/contract.tact`:
36 |
37 | ```tact
38 | import "@stdlib/deploy";
39 |
40 | message Add {
41 | amount: Int as uint32;
42 | }
43 |
44 | contract SampleTactContract with Deployable {
45 |
46 | owner: Address;
47 | counter: Int as uint32;
48 |
49 | init(owner: Address) {
50 | self.owner = owner;
51 | self.counter = 0;
52 | }
53 |
54 | fun add(v: Int) {
55 |
56 | // Check sender
57 | let ctx: Context = context();
58 | require(ctx.sender == self.owner, "Invalid sender");
59 |
60 | // Update counter
61 | self.counter = (self.counter + v);
62 | }
63 |
64 | receive(msg: Add) {
65 | self.add(msg.amount);
66 | }
67 |
68 | receive("increment") {
69 | self.add(1);
70 | }
71 |
72 | get fun counter(): Int {
73 | return self.counter;
74 | }
75 | }
76 | ```
77 |
78 | Add a build script to `package.json`:
79 |
80 | ```json
81 | {
82 | "scripts": {
83 | "build": "tact --config ./tact.config.json"
84 | }
85 | }
86 | ```
87 |
88 | Now you can run `yarn build` and get the compiled contract in `./sources/output` folder.
89 |
--------------------------------------------------------------------------------
/.github/temp-archive/guides/getting-started/_meta.js:
--------------------------------------------------------------------------------
1 | export default {
2 | first: 'Writing your first contract',
3 | deploy: 'Deploying your contract',
4 | test: 'Writing Tests'
5 | }
--------------------------------------------------------------------------------
/.github/temp-archive/guides/getting-started/deploy.mdx:
--------------------------------------------------------------------------------
1 | # Deploy your contract
2 |
3 | Template project provides a handy way to deploy contracts, but you can do it yourself as well.
4 |
5 | ## Deploying with typescript and deploy link
6 |
7 | To deploy a smart contract in TON you need to send a message with `init` data attached to it. The easiest way to get an `init` for your contract is using a generated typescript bindings that would help to call an init function.
8 |
9 | ```typescript
10 | import base64url from 'base64url';
11 | import qs from 'qs';
12 | import { Address, beginCell, storeStateInit, contractAddress, toNano } from '@ton/core';
13 | import { Counter } from './output/sample_Counter';
14 |
15 | // Forming an init package
16 | let owner = Address.parse("some-address");
17 | let init = await Counter.init(owner);
18 | let testnet = true;
19 |
20 | // Contract address
21 | let address = contractAddress(0, init);
22 |
23 | // Amount of TONs to attach to a deploy message
24 | let deployAmount = toNano("0.5");
25 |
26 | // Create string representation of an init package
27 | let initStr = base64url(
28 | beginCell().store(storeStateInit(init)).endCell().toBoc({ idx: false })
29 | );
30 |
31 | // Create a deploy link
32 | console.log(
33 | `ton://transfer/` +
34 | address.toString({ testOnly: testnet }) +
35 | "?" +
36 | qs.stringify({
37 | text: "Deploy",
38 | amount: deployAmount.toString(10),
39 | init: initStr,
40 | })
41 | );
42 | ```
43 |
44 | After running this code you will get a link that you can open in your favorite TON wallet. It will open a transfer page with a deploy message already filled in. You can change the amount of TONs to attach to a deploy message and click on the `Send` button. After a few seconds your contract will be deployed and you will see a transaction in your wallet.
45 |
--------------------------------------------------------------------------------
/.github/temp-archive/guides/getting-started/first.mdx:
--------------------------------------------------------------------------------
1 | # Writing your first contract
2 |
3 | TON contract is an isolated object that have state and code, can send and receive messages and export get-methods for off-chain reading of a contract state.
4 |
5 | The code of the contract dictates how:
6 |
7 | - it manipulates it's own state
8 | - it reacts to incoming messages
9 | - exposes it's state to off-chain world
10 |
11 | ## Contract example
12 |
13 | This contract allows to increment counter by anyone in the network, stores the owner of the contract and exposes counter value and owner address to off-chain world.
14 |
15 | ```tact
16 | contract Counter {
17 |
18 | owner: Address;
19 | counter: Int as uint32;
20 |
21 | init(owner: Address) {
22 | self.owner = owner;
23 | self.counter = 0;
24 | }
25 |
26 | receive("increment") {
27 | self.counter = (self.counter + 1);
28 | }
29 |
30 | get fun counter(): Int {
31 | return self.counter;
32 | }
33 |
34 | get fun owner(): Address {
35 | return self.owner;
36 | }
37 | }
38 | ```
39 |
40 | ## Contract state and init
41 |
42 | This contract has two state variables that persisted between contract calls: `owner` and `counter`. The state variables are declared in the contract header and initialized in the `init` function. The `init` function is called **before** contract is deployed.
43 |
44 | `counter` variable is declared as `Int as uint32` which means that it will be stored as `uint32` in the contract state. The `Int` type is used to represent integer numbers in the contract code. `Int` is 257-bit signed integer. Size checks are performed only when storing. Overflowing `Int` causes an exception and aborting the transaction.
45 |
46 | ## Receiver
47 |
48 | Notation `receive("increment")` means declaration of a `receiver` function that will be called when a text with value `"increment"` is sent to the contract. The function body can modify the state of the contract and send messages to other contracts. It is impossible to call `receiver` directly. If you need to reuse some logic you can declare a function and call it from `receiver`.
49 |
50 | There are several receiver functions. All receiver functions are processed in the order they are listed below:
51 |
52 | - `receive()` - called when an empty message is sent to the contract
53 | - `receive("message")` - called when a text message with a specific comment is sent to the contract
54 | - `receive(str: String)` - called when an arbitrary text message is sent to the contract
55 | - `receive(msg: MyMessage)` - called when binary message of type `MyMessage` is sent to the contract
56 | - `receive(msg: Slice)` - called when binary message of unknown type is sent to the contract
57 | - `bounced(msg: Slice)` - called when outgoing message bounced
58 |
59 | ## Getters
60 |
61 | There are two getters in this contract `counter` and `owner` that returns current counter value and `owner` of a contract. Getters are **not accessible from other contracts** and exported only to off-chain world.
62 |
--------------------------------------------------------------------------------
/.github/temp-archive/guides/getting-started/test.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from 'nextra-theme-docs'
2 |
3 | # Writing Tests with Blueprint
4 |
5 | ## Overview
6 |
7 | Test toolkit (usually, sandbox) already included to the TypeScript SDK named [Blueprint](https://github.com/ton-org/blueprint). You can create demo project and launch default test with two steps:
8 |
9 | 1. Create a new Blueprint project:
10 | ```bash
11 | npm create ton@latest MyProject
12 | ```
13 |
14 | 2. Run a test:
15 | ```bash
16 | cd MyProject
17 | npx blueprint test
18 | ```
19 |
20 | As a result you'll see corresponding output in the terminal window:
21 |
22 | ```bash
23 | % npx blueprint test
24 |
25 | > MyProject@0.0.1 test
26 | > jest
27 |
28 | PASS tests/Main.spec.ts
29 | Main
30 | ✓ should deploy (127 ms)
31 |
32 | Test Suites: 1 passed, 1 total
33 | Tests: 1 passed, 1 total
34 | Snapshots: 0 total
35 | Time: 1.224 s, estimated 2 s
36 | Ran all test suites.
37 | ```
38 |
39 | ## Basic Usage
40 | Testing of smart contracts allows for the coverage of security, optimization of gas spending, and examination of edge cases.
41 | Writing tests in Blueprint (that based on [Sandbox](https://github.com/ton-org/sandbox)) works through defining arbitrary actions with the contract and comparing their results with the expected result, for example:
42 |
43 | ```typescript
44 | it('should execute with success', async () => { // description of the test case
45 | const res = await main.sendMessage(sender.getSender(), toNano('0.05')); // performing an action with contract main and saving result in res
46 |
47 | expect(res.transactions).toHaveTransaction({ // configure the expected result with expect() function
48 | from: main.address, // set expected sender for transaction we want to test matcher properties from
49 | success: true // set the desirable result using matcher property success
50 | });
51 |
52 | printTransactionFees(res.transactions); // print table with details on spent fees
53 | });
54 | ```
55 |
56 |
57 | ### Writing Tests for Complex Assertion
58 |
59 | The basic workflow of creating a test is:
60 | 1. Create a specific wrapped `Contract` entity using `blockchain.openContract()`.
61 | 2. Describe the actions your `Contract` should perform and save the execution result in `res` variable.
62 | 3. Verify the properties using the `expect()` function and the matcher `toHaveTransaction()`.
63 |
64 | The `toHaveTransaction` matcher expects an object with any combination of fields from the `FlatTransaction` type defined with the following properties
65 |
66 | | Name | Type | Description |
67 | |----------------------|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
68 | | from | Address? | Contract address of the message sender |
69 | | on | Address | Contract address of the message destination (Alternative name of the property `to`). |
70 | | value | bigint? | Amount of Toncoins in the message in nanotons |
71 | | body | Cell | Message body defined as a Cell |
72 | | op | number? | Op code is the operation identifier number (crc32 from TL-B usually). Expected in the first 32 bits of a message body. |
73 | |success| boolean? | Custom Sandbox flag that defines the resulting status of a certain transaction. True - if both the compute and the action phase succeeded. Otherwise - False. |
74 |
75 | You can omit those that you're not interested in, and you can also pass in functions accepting those types returning booleans (`true` meaning good) to check for example number ranges, message opcodes, etc. Note however that if a field is optional (like `from?: Address`), then the function needs to accept the optional type, too.
76 |
77 |
78 |
79 | Learn the whole list of matcher fields from the [Sandbox documentation](https://github.com/ton-org/sandbox#test-a-transaction-with-matcher).
80 |
--------------------------------------------------------------------------------
/.github/temp-archive/learn/_meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello": "Hello World",
3 | "wallet": "Wallet contract",
4 | "jetton": "Jetton contract",
5 | "design": "Contract's designing",
6 | "cookbook": "Cookbook"
7 | }
8 |
--------------------------------------------------------------------------------
/.github/temp-archive/learn/cookbook.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from 'nextra-theme-docs'
2 |
3 | # Tact Cookbook
4 |
5 | Tact Cookbook is to provide a centralized repository of valuable information and experience from experienced Tact developers for future developers.
6 |
7 | This article is more focused on every day tasks Tact developer resolve during the development of smart contracts.
8 |
9 |
10 | This is a concept article. We're still looking for someone experienced to write it. Read more about contributing on [Tact Cookbook ton-footstep](https://github.com/ton-society/ton-footsteps/issues/143).
11 |
12 |
13 |
14 | ## Basics
15 | ### How to write exception statements
16 |
17 | To declare exceptions in Tact suggested to use special function `require(condition, error message)`
18 |
19 | ```tact
20 | // throw "Empty counter" message when condition is equal True
21 |
22 | require(ok1 && ok2 && ok3, "Invalid signature");
23 |
24 | require(ctx.value >= ton("1"), "Invalid value");
25 | ```
26 |
27 | Highly recommended to avoid native Func functions like `nativeThrow()`.
28 |
29 |
30 |
31 | ## Receivers
32 | ### How to declare a unified Tact receiver for comments
33 | ```tact
34 | TODO
35 | // throw "Empty counter" message when condition is equal True
36 | receive()
37 | ```
38 |
39 | **Warning template**
40 |
41 |
42 |
43 | **Info template**
44 |
--------------------------------------------------------------------------------
/.github/temp-archive/learn/design.mdx:
--------------------------------------------------------------------------------
1 | # Contract's design
2 |
3 | ### General approach for designing
4 |
5 | #### What is main stages in contract developing?
6 | The developer of a smart contract has a lot of responsibility. Any vulnerability in the logic could attract a malicious attacker or leak its funds because of bad gas management.
7 |
8 | At the beginning of the journey, the developer needs to take care that it is well thought out:
9 | - coins management
10 | - safety of your contract
11 | - gas usage
12 | - storage architecture
13 |
14 | In terms of storage it’s good practice to have it fixed size and not to use growing (specially by users) dict’s, since const of operations with dict’s depend’s on the dict size you can easily got out of gas if your dict is too big.
15 |
16 | [source](https://t.me/hackatonx/3078/3699)
17 |
18 | #### We have an event in Ethereum, do we have such a tool in TON?
19 |
20 |
--------------------------------------------------------------------------------
/.github/temp-archive/learn/hello/_meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello-1": "Tact and TON terms",
3 | "hello-2": "Tact project structure",
4 | "hello-3": "Tact contract structure",
5 | "hello-4": "Receivers and Getters",
6 | "hello-5": "Contract deployment",
7 | "hello-6": "Get data from contract"
8 | }
9 |
--------------------------------------------------------------------------------
/.github/temp-archive/learn/hello/hello-1.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from 'nextra-theme-docs'
2 |
3 | # Tact Hello World
4 |
5 | ## Tact and TON terms
6 |
7 | In this guide, we will walk through the process of creating and deploying a simple smart contract using the Tact program language.
8 | The main goal is trying and touch the smart contract developing process and find out what you should learn next.
9 | You need to spend about one-two hours, depending on your background knowledge.
10 |
11 |
12 | Did you notice something unclear, incorrect or get stuck with some issue in this guide? Please ask a question in the Telegram [chat](https://t.me/tactlang) or text me directly [@iftryalexg](https://t.me/iftryalexg).
13 | Guide will be updated ASAP and all unclear points will be clarified 🚒💦🔥.
14 |
15 |
16 | ### Tact's facts #1
17 |
18 | Five things you need to know in the beginning:
19 |
20 | * Smart contract is a computer program that stores and executes in blockchain.
21 | * Blockchain is a shared and structured way to keep data. Data stored in blockchain is impossible to edit and be replaced with fake.
22 | * TON Blockchain works on its own special program software, called the Ton Virtual Machine (TVM).
23 | * Tact is a computer language for developing smart contracts on the TON blockchain.
24 | * Tact uses JavaScript frameworks, so basic knowledge of them helps you learn it faster. However, if you are just a newcomer it is possible to learn from the scratch.
25 |
26 |
27 |
28 | **Blockchain** is like a digital notebook where important information is written down and shared with many people. Once something is written in the notebook, it can't be changed or erased. It's like a permanent record that everyone can trust. But instead of a notebook, it is stored on multiple servers. And instead of just one person writing in it, many people can write in it at the same time. This way, everyone can see and agree on the information that is written in the blockchain. And because it's placed on a multiple servers, it's safe and can't be lost or changed by accident.
29 |
30 |
31 |
32 | ### Tactical practice #1
33 | #### Set up your environment
34 |
35 | Get ready to build your own blockchain creation! First, you'll need to gather a few tools to help you along the way.
36 |
37 | - **Git** is like a magic toolbox for developers. It helps you keep track of all the different parts of your project, so you can work on them together with your team. You can download it [here](https://git-scm.com/downloads).
38 | - **NodeJS** is a central tool in JavaScript world. We'll be using JavaScript and its special version called TypeScript to create our smart contract. You can download it [here](https://nodejs.org/en/download/).
39 | - **JavaScript IDE** is like your own personal workshop. It's where you'll be building and designing your code, a text editor for code with highlighting. A popular choice is [VS Code](https://code.visualstudio.com/download), for example. Get it now and let's get building!
40 | - **Tact language** extension for IDE makes it more comfortable to work. For example, in VS Code you can install an [extension](https://marketplace.visualstudio.com/items?itemName=ton-community.tact-vscode).
41 |
42 | After the preparation of developer tools is done, download *tact-guide-template* project and open it in your IDE.
43 |
44 | ```bash
45 | git clone https://github.com/ton-community/tact-guide-template
46 | cd tact-guide-template
47 | ```
48 |
--------------------------------------------------------------------------------
/.github/temp-archive/learn/hello/hello-2.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from 'nextra-theme-docs'
2 |
3 | # Tact Hello World
4 |
5 | ## Tact contract structure
6 |
7 | ### Tact's facts #2
8 |
9 | **tact-guide-template** is basic demo project for developing smart contract on Tact language. Let's learn general things about this:
10 |
11 | * By default, this project has a number of additional frameworks used in it, that specified in `yarn`.
12 | * Most important directory for us placed in `tact-guide-template/sources/` directory and contents following:
13 | ```
14 | +--tact-guide-template
15 | | +--sources
16 | | | +-- contract.deploy.ts
17 | | | +-- contract.spec.ts
18 | | | +-- contract.tact
19 |
20 | ```
21 | * `contract.tact` - Tact language smart contract will be written here.
22 | * `contract.spec.ts` - contents tests for using `yarn tests` for launching local tests. Not necessary part for deployment.
23 | * `contract.deploy.ts` - contents instructions to generate a deployment link. This link includes all necessary information to deploy our smart contract in blockchain.
24 |
25 | When a smart contract is delivered in TON Blockchain as bytecode he becomes **deployed**.
26 |
27 |
28 | As a result we will use three yarn commands to work with Tact project:
29 | ```bash
30 | yarn build # To build contract
31 | yarn test # To test contract
32 | yarn deploy # To deploy contract
33 | ```
34 |
35 | ### Tactical practice #2
36 | #### Get template from GitHub
37 |
38 | Update dependencies in project via yarn:
39 | ```bash
40 | yarn install
41 | ```
42 |
43 | Now check, that everything is ok, input command:
44 |
45 | ```bash
46 | yarn build
47 | ```
48 | This command will initiate the Tact compiler to build the current `tact.contract`.
49 | Currently, the contract has no content, but the compiler should work.
50 | The result of success executing this should be seen in your terminal window like the following:
51 |
52 | 
53 |
--------------------------------------------------------------------------------
/.github/temp-archive/learn/hello/hello-4.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from 'nextra-theme-docs'
2 |
3 | # Tact Hello World
4 |
5 | ## Receivers and Getters
6 |
7 | ### Tact's facts #4
8 | Here we will learn more about existing tools in Tact for defining contract's behavior in general.
9 | `init()` - is one of them, and below listed all of them:
10 |
11 |
12 | | Entity | Description |
13 | |-------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
14 | | `fun` | Special Tact keyword for declaring function. Functions serve for the convenient abstraction of logic and optimization that helps code be more readable. |
15 | | `init()` | Function that declares initial values will be stored in contract's data. It will be use in Deployment process, when contract creates in Blockchain. It is mandatory to be defined for the contract. |
16 | | `context()` | Tact stdlib helper that gets common properties about current incoming messages such as sender's Address, message's body and message value. |
17 | | `receive()` | Special function of contract serves to declare behavior of contract with messages. |
18 | | `get fun` | Special keywords of contract serves to declare get functions. According to name, this uses to get information from its data. |
19 |
20 |
21 |
22 | ### Tactical Practice #4
23 | #### Declare fun
24 |
25 | Ok, one more time, we need extend our contract's behaviour
26 |
27 | ```tact
28 | //previous code
29 |
30 | fun add(v: Int) {
31 |
32 | let ctx: Context = context();
33 | require(ctx.sender == self.owner, "Invalid sender");
34 |
35 | self.counter = (self.counter + v);
36 | }
37 | ```
38 |
39 | Declare function `add` that will do following things:
40 | 1. Get incoming integer argument `v`.
41 | 2. Check current incoming message `sender` is equal to `owner` we set for contract in deployment process.
42 | 3. If this check passed add to current `counter` value `v` and update `counter` value in contract. If required is not pass, throw exception message "Invalid sender".
43 |
44 | #### Declare receivers
45 | ```tact
46 | //previous code
47 |
48 | receive(msg: Add) {
49 | self.add(msg.amount);
50 | }
51 | }
52 |
53 | receive("increment") {
54 | self.add(1);
55 | }
56 | }
57 | ```
58 | Here we are specified two receive functions. This means, that if we get message in contract that correspond of one the receiver contract execute one of them. In other case, contract will do nothing.
59 | `receive()` function expects an incoming argument of String type, Message struct or custom Tact Struct.
60 | Take a look our receivers:
61 | * `receive(msg: Add)` - specifies actions with messages defined in the beginning by Message add. It will content only one integer number of 32-bits length, that we called amount and nothing else. This receiver invokes function `add(amount)`.
62 | * `receive("increment")` - specifies actions with messages, that contents comment string "increment" in its body. Here we invoke function `add(v)` with `v = 1`, so we increment contract's counter by one.
63 |
64 |
65 | #### Declare getter
66 |
67 | Last function we need to specifier is get function counter, that will return value of current counter value from contract.
68 | Now our contract is ready, we need compile this, so run:
69 |
70 | ```tact
71 |
72 | contract SampleTactContract with Deployable {
73 | //previous code
74 |
75 | get fun counter(): Int {
76 | return self.counter;
77 | }
78 |
79 | ```
80 |
81 |
82 | **Getters** are not accessible from other contracts and exported only to off-chain world.
83 |
84 |
85 |
86 | #### Build contract
87 |
88 | Command `yarn build` will compile `contract.tact` and place result in `tact-template/src/output`.
89 |
90 | 
91 |
92 | Run yarn command from terminal:
93 |
94 | ```bash
95 | yarn build
96 | ```
97 |
98 |
99 | If you faced some compile issue and can't figure out what is wrong, just compare with target contract placed in `sources/example/increment.tact` or [here](https://github.com/ton-community/tact-guide-template/blob/main/sources/example/increment.tact).
100 |
--------------------------------------------------------------------------------
/.github/temp-archive/learn/hello/hello-5.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from 'nextra-theme-docs'
2 |
3 | # Tact Hello World
4 |
5 | ## Contract deployment
6 |
7 | ### Tact's facts #5
8 |
9 | Now we on finale stage. We need to deploy our contract to Blockchain. To do this, we will use Ton wallet application.
10 |
11 | In this way, we avoid a lot of details about the deployment process, but you can find more details about this in followed low-level guides.
12 |
13 |
14 | * To deploy our new contract we need send message with init information in its to address of our contract.
15 | * We can know destination address of contract because of definition of Address depends on only from contract's data and code. We know both.
16 | * To send message in blockchain it is necessary to communicate with TON blockchain nodes. Wallet application will do this with own API, so we will avoid this details in current lesson.
17 | * To send outgoing message in TON, sender should pay fees. In our case, we need some funds on Ton wallet to pay this action.
18 |
19 |
20 | 
21 |
22 |
23 | Note, this design of deployment is used just for clarity. Deploying via Wallet App, Working with public API is convenient for learning purposes and does not best practice for projects in the production environment.
24 |
25 |
26 |
27 | ### Tactical Practice #5
28 | #### Deploy the contract
29 |
30 | Before deployment, according to said before we need to prepare Ton wallet contract with funds. We will use test environment, that maintained with test nodes and called testnet(production calls mainnet).
31 |
32 | 1. To do this we need install one of ton wallet for testnet:
33 |
34 | * Sandbox - separate application for testnet - [Android](https://play.google.com/store/apps/details?id=com.tonhub.wallet.testnet)/[iOS](https://apps.apple.com/app/ton-development-wallet/id1607857373)/[MacOS](https://apps.apple.com/app/ton-development-wallet/id1607857373)
35 | * Tonkeeper(to switch on testnet, open dev menu tap several times in settings on diamond icon) - [Android](https://play.google.com/store/apps/details?id=com.ton_keeper)/[iOS](https://apps.apple.com/us/app/tonkeeper/id1587742107)/[MacOS](https://apps.apple.com/us/app/tonkeeper/id1587742107)
36 |
37 | 2. Create wallet in application according native wallet apps instructions.
38 |
39 | 3. Get test Toncoins for your wallet from Telegram [testgiver bot](https://t.me/testgiver_ton_bot).
40 |
41 | 4. Get address from your wallet and input it in deployment script - `contract.deploy.ts`.
42 | For me, it was `kQDND6yHEzKB82ZGRn58aY9Tt_69Ie_uz73e2VuuJ3fVVcxf`:
43 |
44 | ```tact"
45 | //previous code
46 | // Parameters
47 | let owner = Address.parse('kQDND6yHEzKB82ZGRn58aY9Tt_69Ie_uz73e2VuuJ3fVVcxf'); // Replace owner with your address
48 | ```
49 |
50 | 5. Run `contract.deploy.ts` script to get deployment link in terminal with following command in terminal:
51 |
52 | ```bash
53 | yarn deploy
54 | ```
55 | It will ask from you wallet you want use, choose what you used before(Tonkeeper/Sandbox).
56 |
57 | 6. Read deployment link through reading QR or open URL link via your testnet TON wallet, confirm outgoing message in wallet application.
58 |
59 | 
60 |
61 |
62 | If you faced some compile issue and can't figure out what is wrong, just compare it with the target contract placed in `sources/example/increment.tact` or [here](https://github.com/ton-community/tact-guide-template/blob/main/sources/example/increment.tact).
63 |
64 |
--------------------------------------------------------------------------------
/.github/temp-archive/learn/hello/hello-6.mdx:
--------------------------------------------------------------------------------
1 | # Tact Hello World
2 |
3 | ## Get data from contract
4 |
5 | ### Last Tact and next steps
6 |
7 | We sent deployment message and deploy our Contract. We can check result with blockchain [testnet explorer](https://testnet.tonapi.io/).
8 | Take your deployed contract address from terminal window or follow ready-made link and check result of sent message in explorer.
9 | In the case of tutorial, deployed contract address was `kQAd00TX4YPxBfyWjArkionTZJVMoRzFQUM2ntQBcFycWYr4`.
10 | If you saw in blockchain explorer same for your contract...
11 |
12 | 
13 |
14 | Yes! You successfully created and deployed your own smart contract, congrats!
15 |
16 | Let's try to find out how it works now?
17 | Another blockchain explorer allows to use get function. Let's check current Total value in our contract:
18 | 1. Find your deployed contract again in another blockchain explorer testnet - [ton.cx](https://testnet.ton.cx/). In the tutorial it is: `kQAd00TX4YPxBfyWjArkionTZJVMoRzFQUM2ntQBcFycWYr4`.
19 | 2. Open Get methods tab.
20 | 3. Input get method name - `counter` in _Arbitrary method_ field. Run this and check result (it shows in hexadecimal format).
21 |
22 | 
23 |
24 | Now, lets try to send `Add(1)` message, according to our plan we should send common message with "increment" comment to our contract.
25 |
26 | All you need open Wallet app(Sandbox/Tonkeeper) you used before, input your deployed contract address in destination address and type "increment" text in comment(message) field and send it.
27 | Check your `counter` value after this, make sure that counter value changed.
28 |
29 | #### What to read next?
30 |
31 | * [Wallet.tact contract deployment through public API](../wallet)
32 | * [Jetton.tact contract overview and deployment](../jetton)
33 |
34 | #### Useful social
35 | * [Tact Telegram chat](https://t.me/tactlang)
36 | * [Ton Dev News](https://t.me/tondevnews)
37 | * [Ton Dev chat](https://t.me/tondev_eng)
38 |
39 |
40 | #### Useful TON links
41 | * [Tact main repository](https://github.com/ton-core/tact)
42 | * [Ton official documentation](https://ton.org/docs/)
43 | * [FunC journey](https://blog.ton.org/func-journey)
44 | * [Ton Tutorials](https://ton-community.github.io/tutorials/01-wallet/)
--------------------------------------------------------------------------------
/.github/temp-archive/learn/jetton/_meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "jetton-1": "Digital token issue",
3 | "jetton-2": "Jetton standard explanation",
4 | "jetton-3": "Jetton deployment"
5 | }
6 |
--------------------------------------------------------------------------------
/.github/temp-archive/learn/jetton/jetton-1.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from 'nextra-theme-docs'
2 |
3 | # Jetton contract
4 |
5 | ## Digital token issue
6 |
7 |
8 | Did you notice something unclear, incorrect or get stuck with some issue in this guide? Please ask a question in the Telegram [chat](https://t.me/tactlang) or text me directly [@iftryalexg](https://t.me/iftryalexg).
9 | Guide will be updated ASAP and all unclear points will be clarified 🚒💦🔥.
10 |
11 |
12 | ### Jetton is a part of TON
13 |
14 | Jettons is implementation fungible tokens on the TON Blockchain. Fungible Tokens means that they have a property that makes each Token be exactly the same (in type and value) as another Token. From the side of users - it's digital tool in blockchain, that allow to organize business process of distribution and keeping funds with zero trust functions in transaction.
15 | In TON Blockchain Jettons declared according to [Jetton standard](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md). This standard already fully successfully
16 | implemented with FunC language and support in libraries in various languages. Some of them, you can find and research [here](docs/develop/dapps/defi/tokens).
17 |
18 | The scope of this article are:
19 | * Remind how Fungible Tokens works in TON blockchain.
20 | * Research how jetton standard could be implemented in the Tact language.
21 |
22 |
23 | Note, that jetton.tact is used for learning goals and was not thoroughly tested. It should test necessary before use in production.
24 |
25 |
26 | ### Jetton as example of designing architecture
27 |
28 | Implementation of jetton demonstrate how relationships between contracts could be implemented. Idea of scaling in TON allows to think about Jetton standard as a workable process even if userbase will grow in digits.
29 | It becomes possible, because in Jetton standard we have no any parts, that could slow down. But why does this possible and what the price?
30 | - This is possible, because every part of jetton processing become independent element(smart contract) of the whole jetton wallets. No matter how many users will come, it's just increase quantity of smart contracts, shards and will not slow down blockchain.
31 | - Price we have to pay is increasing of complexity of development. Asynchronous messages increase number of cases, we have to handle in smart contracts. Developers of smart contract have to solve this during at very first steps of designing smart-contract.
32 |
33 | ### Classic issue of fungible token
34 |
35 | Suppose we have amount of users with wallets(wallet smart contract) with funds on them in native Blockchain currency. Now, we want somehow to add tokens to user's wallet.
36 |
37 | In the [ERC20](https://ethereum.org/ru/developers/docs/standards/tokens/erc-20/) standard we keep balance and processing transaction in special token contract. This contract stores a map of wallet addresses and their token balances.
38 | If we want to deliver to user information about his token balance, we read data from his wallet and token contract.
39 | 
40 | Both actions will be delivered to off-chain space, where we will display and use it in our application.
41 | Here, Wallet A, Wallet B - regular wallet contracts.
42 |
43 |
44 | Then, how to implement token transfer? We can use special transfers between wallet contracts, that will update their balance in Token Master.
45 |
46 | 
47 |
48 | With sharding paradigms in TON blockchain we can without problem support a million of users and millions of transactions. But for Token Master will always live in one shard, and become unscalable now.
49 |
50 | 
51 |
52 | And what we can do, to solve this issue? Redesign our solution to case, where every atomic part(smart contract) of our process is a small blockchain, that will never grow to infinity.
--------------------------------------------------------------------------------
/.github/temp-archive/learn/jetton/jetton-2.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from 'nextra-theme-docs'
2 |
3 | # Jetton contract
4 |
5 | ## Jetton standard explanation
6 |
7 | ### Reveal the Jetton
8 | In TON digital tokens was named Jettons. Now, we will walk through the Jetton standard and see how problems we met previously were solved.
9 |
10 | Because of sharding, where payload on Blockchain will split to different nodes, we need keep our contracts as small blockchains.
11 |
12 |
13 | Every time you noticed, that your contract keep growing to infinity map in your contract-like-big-monolith - something in designing of service went wrong.
14 |
15 |
16 | To keep possibility make our smart contracts split shards we want keep all smart contracts as small blockchain.
17 |
18 | Let's take a look how regular transfer Jetton works according to standard.
19 | 
20 |
21 | Here scheme of transfer tokens from user of _Wallet App A_ to user _Wallet App B_:
22 | 1. _Wallet App A_ requests _Wallet A_ to send Jetton transfer request message.
23 | 2. _Wallet A_ sends to _Jetton_A_ wallet message with request of sending jettons.
24 | 3. _Jetton A_ sends to _Jetton B_ value of jetton we want to transfer. Decrease his own balance of jettons.
25 | 4. _Jetton B_ get incoming message, increase its jetton balance, send notification to wallet contract _Wallet B_.
26 |
27 |
28 | **Notification** necessary to find out what is balance of Jetton contract, because you have no option to get(use get method) information from contract.
29 |
30 |
31 | If we will scale our user base, we just get growing of little blockchains. THere will not appear big monolith entity now.
32 | 
33 |
34 | When quantity of actual contracts become to large, they will split to different shardchains.
35 | Each of these contracts has fixed size state and each contract may live in own shardchain. In this way contracts can live in one shardchain(i.e. Shard 1) and never touch other smart contracts.
36 |
37 | 
38 |
39 |
--------------------------------------------------------------------------------
/.github/temp-archive/learn/wallet/_meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "wallet-1": "What is wallet",
3 | "wallet-2": "Wallet structure",
4 | "wallet-3": "Deployment with API"
5 | }
6 |
--------------------------------------------------------------------------------
/.github/temp-archive/learn/wallet/wallet-1.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from 'nextra-theme-docs'
2 |
3 | # Tact wallet contract
4 | ## What is wallet
5 |
6 | This article explains how wallet contract works in Tact, how to deploy and test this.
7 |
8 |
9 | Did you notice something unclear, incorrect or get stuck with some issue in this guide? Please ask a question in the Telegram [chat](https://t.me/tactlang) or text me directly [@iftryalexg](https://t.me/iftryalexg).
10 | Guide will be updated ASAP and all unclear points will be clarified 🚒💦🔥.
11 |
12 |
13 | ### Set up your environment
14 |
15 | For this project you should install
16 |
17 |
18 | * **Git**. Essential tool for every developer to work with repositories. Download it [here](https://git-scm.com/downloads).
19 | * **NodeJS**. We will use JavaScript with TypeScript mode as the most popular choice for dApp development on TON. Download it [here](https://nodejs.org/en/download/).
20 | * **JavaScript IDE**. Your normal choice for development. [VSCode](https://code.visualstudio.com/download), for example.
21 | * **Wallet app**. You need one of TON noncustodial testnet [wallet app](docs/participate/wallets/apps) (better with support Walletv4), for example [Sandbox](https://apps.apple.com/app/ton-development-wallet/id1607857373)/[Tonkeeper](https://tonkeeper.com/). This is as part of simplify demonstration, you also can get access to your wallet from code, example added in demo.
22 |
23 | - [Tact SDK and libraries full list](docs/develop/tact/introduce/tact-sdk)
24 |
25 |
26 | ### Tact wallet demo project
27 | Get tact-wallet project from git:
28 |
29 | ```bash
30 | git clone https://github.com/ton-community/tact-wallet
31 | cd tact-wallet
32 | ```
33 |
34 | This project has ready to use TACT compiler, typescript + jest with [@tact-lang/emulator](https://github.com/tact-lang/tact-emulator), example how to test and deploy.
35 | You have ready-to-use commands configured for contract. Try to input them in terminal and look how it works:
36 |
37 | ```bash
38 | yarn test # To test contract
39 | yarn build # To build contract
40 | yarn deploy # To deploy contract via deployment link
41 | yarn deploy-api # To deploy through API(need to input deployment wallet in wallet.deploy-api.ts before using)
42 | ```
43 |
44 | ### Briefing for Tact project structure
45 |
46 | In the `tact-wallet/sources/` directory placed core project files, that defines what `yarn` commands will do:
47 |
48 | 1. File `wallet.tact` contract on Tact language, that will be compiled with Tact compiler in `yarn build`
49 | 2. File `wallet.spec.ts` contents unit tests for `yarn tests` command. This command allow to launch local tests on your local IDE. Not necessary for deployment.
50 | 3. File `wallet.deploy.ts` is a helper, that allow to deploy your `wallet.tact` compiled file(src/output) with deployment link. From the beginning you can deploy your smart contract via [Sandbox](https://apps.apple.com/app/ton-development-wallet/id1607857373)/[Tonkeeper](https://tonkeeper.com/) application.
51 | 4. Describes alternative deployment script `wallet.deploy-api.ts` for `yarn deploy-api` according to your `contract.tact` to send deployment message from deployment wallet. You need to input your deployment wallet 24 words [here](sources/wallet.deploy-api.ts#L19).
52 |
53 |
54 | ### What is wallet contract general idea?
55 |
56 | Wallet similar to usual smart contract serve as a platform for managing and transferring funds in a decentralized and secure manner. However, it is important to note that while a smart contract may have built-in features for handling funds, additional steps may be necessary to make the user experience more convenient and secure. This may involve handling additional user stories and implementing additional features to meet real-life requirements.
57 |
58 | Let's describe small list of feature for wallet contract:
59 | * Deployment of smart contract where placed information of its owner with public key.
60 | * Requests for action with funds by owner.
61 | * Get and handle messages from other smart-contracts, including incoming transfer of funds.
62 |
63 |
64 |
65 | Explorers recognize contract's type by hash of the smart contract's code or/and by interfaces founded in smart contract. If you check your common wallet contract with [explorer](https://tonscan.org/)([testnet explorer](https://testnet.tonscan.org/)), you will see that it recognized with type "wallet". From this side, tact-wallet contract is a new version, and it will have different hash(because of original FunC contract and FunC compiled from Tact will be absolutely different). On the same reason current wallet application will not support Tact contract until they add its tact version to their applications.
66 |
67 |
68 |
--------------------------------------------------------------------------------
/.github/temp-archive/learn/wallet/wallet-3.mdx:
--------------------------------------------------------------------------------
1 | # Tact wallet contract
2 | ## Deployment with API
3 |
4 |
5 | ### Wallet deployment
6 |
7 | For deployment wallet we have two demo options to run:
8 |
9 | ```bash
10 | yarn deploy
11 | yarn deploy-api
12 | ```
13 |
14 | #### Deployment with user wallet application
15 |
16 | As simple way offered to deploy smart contract with usual wallet application. The trick is that we just need specify our outgoing message with data we need(we've already done this) and input this data in message.
17 | Wallet applications supports transfer links and QR, so we can use it for our deployment message.
18 | The following scheme shows how deployment process via wallet applications works.
19 |
20 | 
21 |
22 | Step list here:
23 | 1. Install wallet application on device from which we will do deployment.
24 | 2. Get test Toncoins on our wallet application with bot.
25 | 3. Run deployment script for deployment:
26 | ```bash
27 | yarn deploy
28 | ```
29 | 4. Use deployment link or QR with wallet application and confirm the sending of outgoing message.
30 | 5. Notice our new smart contract deployed on the address we sent the message.
31 |
32 | #### Deployment with TON public API
33 |
34 | The way, some applications in production uses is public API. It is acceptable solution for services that not requires operative updating data and just need sometimes send messages.
35 | Demo script for this process needs to fill with your wallet 24 words of wallet in testnet, you also can use your wallet from previous step.
36 | So, this wallet will call _deployment wallet_ and will be use in similar to wallet application way.
37 |
38 | 
39 |
40 | Step list here:
41 | 1. Install wallet application on device from which we will do deployment and get toncoins.(Using same wallet from previous step)
42 | 2. Input your test wallet 24 words in deployment script `source/wallet.deploy-api.ts`.
43 | 3. Run deployment with script:
44 | ```bash
45 | yarn deploy-api
46 | ```
47 | 4. Notice in blockchain explorer our new smart contract deployed according address in console log where we sent the deployment message.
48 |
49 | ### Wallet tests overview
50 |
51 | From the beginning example of unit tests distributed with contract in wallet.spec.contract.
52 | You can launch test via `yarn test` or specify your own with help of jest and `@tact-lang/emulator` library.
53 |
54 |
55 | ### Summary about Tact wallet
56 |
57 | Currently TON explorers uses interfaces(getters) and(sometimes) code hash as identifier of contract type, and wallet contract will absolutely different hash for its, so it will not work from the box.
58 | This contract is generic FunC contract, so in production all application already set up for using original FunC contract, but still it is most used contract so it was used for learning and explanation purposes of how it works.
59 | You can learn more about launching and testing your own tact contract from Jetton Tact article.
60 |
61 | ## What to read next?
62 |
63 | ### Useful materials
64 | * [Jetton.tact contract overview and deployment](../jetton)
65 | * [TON Hello World part 1: Step by step guide for working with your first TON wallet](https://ton-community.github.io/tutorials/01-wallet/)
66 |
67 | ### Useful social
68 | * [Tact Telegram chat](https://t.me/tactlang)
69 | * [Ton Dev News](https://t.me/tondevnews)
70 | * [Ton Dev chat](https://t.me/tondev_eng)
71 |
72 | ### Useful TON links
73 | * [Tact main repository](https://github.com/ton-core/tact)
74 | * [Ton official documentation](https://ton.org/docs/)
75 | * [FunC journey](https://blog.ton.org/func-journey)
76 | * [Ton Tutorials](https://ton-community.github.io/tutorials/01-wallet/)
--------------------------------------------------------------------------------
/.github/workflows/nextjs.yml:
--------------------------------------------------------------------------------
1 | # Sample workflow for building and deploying a Next.js site to GitHub Pages
2 | #
3 | # To get started with Next.js see: https://nextjs.org/docs/getting-started
4 | #
5 | name: Deploy tact-docs to Pages
6 |
7 | on:
8 | # Runs on pushes targeting the default branch
9 | # push:
10 | # branches: ["main"]
11 |
12 | # Allows you to run this workflow manually from the Actions tab
13 | workflow_dispatch:
14 |
15 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
16 | permissions:
17 | contents: read
18 | pages: write
19 | id-token: write
20 |
21 | # Allow one concurrent deployment
22 | concurrency:
23 | group: "pages"
24 | cancel-in-progress: true
25 |
26 | jobs:
27 | # Build job
28 | build:
29 | runs-on: ubuntu-latest
30 | steps:
31 | - name: Checkout
32 | uses: actions/checkout@v3
33 | with:
34 | fetch-depth: 0
35 |
36 | - name: Setup Node
37 | uses: actions/setup-node@v3
38 | with:
39 | node-version: "18"
40 | cache: yarn
41 |
42 | - name: Setup Pages
43 | uses: actions/configure-pages@v2
44 | with:
45 | # Automatically inject basePath in your Next.js configuration file and disable
46 | # server side image optimization (https://nextjs.org/docs/api-reference/next/image#unoptimized).
47 | #
48 | # You may remove this line if you want to manage the configuration yourself.
49 | static_site_generator: next
50 |
51 | - name: Restore cache
52 | uses: actions/cache@v3
53 | with:
54 | path: |
55 | .next/cache
56 | # Generate a new cache whenever packages or source files change.
57 | key: ${{ runner.os }}-nextjs-${{ hashFiles('**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}
58 | # If source files changed but packages didn't, rebuild from a prior cache.
59 | restore-keys: |
60 | ${{ runner.os }}-nextjs-${{ hashFiles('**/yarn.lock') }}-
61 |
62 | - name: Install dependencies
63 | run: yarn install --frozen-lockfile
64 |
65 | - name: Build documentation
66 | run: yarn build-pages
67 |
68 | - name: Upload artifact
69 | uses: actions/upload-pages-artifact@v1
70 | with:
71 | path: ./out
72 |
73 | # Deployment job
74 | deploy:
75 | environment:
76 | name: github-pages
77 | url: ${{ steps.deployment.outputs.page_url }}
78 | runs-on: ubuntu-latest
79 | needs: build
80 | steps:
81 | - name: Deploy to GitHub Pages
82 | id: deployment
83 | uses: actions/deploy-pages@v1
--------------------------------------------------------------------------------
/.github/workflows/test-build-nextjs.yml:
--------------------------------------------------------------------------------
1 | # To not merge, if build fails
2 | name: Test Next.js build
3 |
4 | on:
5 | # For new PRs, or those who are ready and/or request a review
6 | pull_request:
7 | types: ["opened", "edited", "reopened", "synchronize", "ready_for_review", "review_requested"]
8 | branches: ["main"]
9 |
10 | # Allows you to run this workflow manually from the Actions tab
11 | workflow_dispatch:
12 |
13 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
14 | permissions:
15 | contents: read
16 | pages: write
17 | id-token: write
18 |
19 | # Allow simultaneous checks
20 | concurrency:
21 | group: ${{ github.workflow }}-${{ github.ref }}
22 | cancel-in-progress: true
23 |
24 | jobs:
25 | test-build:
26 | runs-on: ubuntu-latest
27 | steps:
28 | - name: Checkout
29 | uses: actions/checkout@v3
30 | with:
31 | fetch-depth: 0
32 |
33 | - name: Setup Node
34 | uses: actions/setup-node@v3
35 | with:
36 | node-version: "18"
37 | cache: yarn
38 |
39 | - name: Setup Pages
40 | uses: actions/configure-pages@v2
41 | with:
42 | # Automatically inject basePath in your Next.js configuration file and disable
43 | # server side image optimization (https://nextjs.org/docs/api-reference/next/image#unoptimized).
44 | #
45 | # You may remove this line if you want to manage the configuration yourself.
46 | static_site_generator: next
47 |
48 | - name: Restore cache
49 | uses: actions/cache@v3
50 | with:
51 | path: |
52 | .next/cache
53 | # Generate a new cache whenever packages or source files change.
54 | key: ${{ runner.os }}-nextjs-${{ hashFiles('**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}
55 | # If source files changed but packages didn't, rebuild from a prior cache.
56 | restore-keys: |
57 | ${{ runner.os }}-nextjs-${{ hashFiles('**/yarn.lock') }}-
58 |
59 | - name: Install dependencies
60 | run: yarn install --frozen-lockfile
61 |
62 | - name: Build documentation
63 | run: yarn build-pages
64 |
65 | - name: Spell check documentation
66 | run: yarn spell
67 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .next
2 | node_modules
3 | out
4 | package-lock.json
5 | yarn-error.log
6 |
7 | # Editors
8 | .vscode/
9 | .idea/
10 | .helix/
11 | .vim/
12 | .gitpod.yml
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ARCHIVED! The actual docs are moved to the compiler repo, see: https://github.com/tact-lang/tact/tree/main/docs
2 |
3 |
4 |
5 |
6 | ## Welcome to Tact Documentation 🌈
7 |
8 | Hello there! This is the community-driven repository for Tact Language Documentation.
9 |
10 | Latest documentation is always available at: [docs.tact-lang.org](https://docs.tact-lang.org)
11 |
12 | Our goal here is to create a welcoming and rich resource that benefits all Tact developers, from beginners to experts.
13 |
14 | ## Join the Tact Community 🌟
15 |
16 | Tact is not just a technology; it's a growing community of developers like you! Whether you are just starting out or have tons of experience, your contributions are valuable.
17 |
18 | Here's how you can contribute:
19 |
20 | - Organize or clarify information 📝
21 | - Make Pull Requests to improve the code or docs 🚀
22 | - Share tutorials, guides, and articles 📚
23 |
24 | Join our community chats to stay updated and collaborate:
25 | * [Tact Telegram Community](https://t.me/tactlang)
26 |
27 | ## How Can You Contribute?
28 |
29 | Contributing is not just encouraged; it's easy!
30 |
31 | If you've solved a challenging problem or found a better way to explain a complex topic, share it:
32 |
33 | — Got an idea? [Open an Issue](https://github.com/tact-lang/tact-docs/issues/new/choose).
34 | — Ready to contribute? [Set up your Development Environment](#set-up-your-development-environment).
35 |
36 | ## Set Up Your Development Environment
37 |
38 | Before you submit your amazing contributions, ensure they work seamlessly.
39 |
40 | ### Quick Cloud Setup 🌩️
41 |
42 | Use Gitpod for a hassle-free cloud-based IDE experience:
43 |
44 | [](https://gitpod.io/#https://github.com/tact-lang/tact-docs)
45 |
46 | ### Local Setup 🏠
47 |
48 | 1. Clone this GitHub repository.
49 | 2. Make sure to have the latest version of [NodeJS LTS](https://nodejs.org/en/download/) installed.
50 | 3. Open your terminal in the project directory.
51 | 4. Install dependencies without modifying the `yarn.lock`:
52 |
53 | ```
54 | yarn deps
55 | ```
56 |
57 | 5. Start your local development server:
58 |
59 | ```
60 | yarn dev
61 | ```
62 |
63 | This will open a new browser window displaying your local version of the documentation. Most updates are automatically reflected.
64 |
65 | ## License 📄
66 |
67 | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)
68 |
--------------------------------------------------------------------------------
/components/icons/arrow-right.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/components/icons/box.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/brush.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/cards.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/chevron-right.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/cloud.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/code.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/diagram.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/components/icons/dropper.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/file.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/files.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/folder-tree.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/components/icons/formula.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/gear.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/globe.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/id-card.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/components/icons/index.ts:
--------------------------------------------------------------------------------
1 | export { default as FilesIcon } from './files.svg'
2 | export { default as MarkdownIcon } from './markdown.svg'
3 | export { default as TailwindIcon } from './tailwind.svg'
4 | export { default as LinkIcon } from './link.svg'
5 | export { default as LightningIcon } from './lightning.svg'
6 | export { default as GlobeIcon } from './globe.svg'
7 | export { default as PictureIcon } from './picture.svg'
8 | export { default as CodeIcon } from './code.svg'
9 | export { default as BrushIcon } from './brush.svg'
10 | export { default as DropperIcon } from './dropper.svg'
11 | export { default as StarsIcon } from './stars.svg'
12 | export { default as FormulaIcon } from './formula.svg'
13 | export { default as WarningIcon } from './warning.svg'
14 | export { default as ChevronRightIcon } from './chevron-right.svg'
15 | export { default as BoxIcon } from './box.svg'
16 | export { default as GearIcon } from './gear.svg'
17 | export { default as RowsIcon } from './rows.svg'
18 | export { default as CardsIcon } from './cards.svg'
19 | export { default as OneIcon } from './one.svg'
20 | export { default as CloudIcon } from './cloud.svg'
21 | export { default as TableIcon } from './table.svg'
22 | export { default as FileIcon } from './file.svg'
23 | export { default as NewsletterIcon } from './newsletter.svg'
24 | export { default as ArrowRightIcon } from './arrow-right.svg'
25 | export { default as SwitchIcon } from './switch.svg'
26 | export { default as TerminalIcon } from './terminal.svg'
27 | export { default as DiagramIcon } from './diagram.svg'
28 | export { default as FolderTreeIcon } from './folder-tree.svg'
29 | export { default as IdCardIcon } from './id-card.svg'
30 |
--------------------------------------------------------------------------------
/components/icons/lightning.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/components/icons/link.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/markdown.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/components/icons/newsletter.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/one.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/components/icons/picture.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/rows.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/stars.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/switch.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/components/icons/table.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/tailwind.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/components/icons/terminal.svg:
--------------------------------------------------------------------------------
1 |
31 |
--------------------------------------------------------------------------------
/components/icons/warning.svg:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/cspell.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json",
3 | "version": "0.2",
4 | "language": "en",
5 | "words": [
6 | "basechain",
7 | "bounceable",
8 | "cheatsheet",
9 | "Cheatsheet",
10 | "cheatsheets",
11 | "Cheatsheets",
12 | "comptime",
13 | "Comptime",
14 | "Decompilation",
15 | "decompilation",
16 | "decompiles",
17 | "decompiling",
18 | "dnsresolve",
19 | "Epva", // part of a base64 string
20 | "Fift",
21 | "ipfs",
22 | "IPFS",
23 | "jetton",
24 | "Jetton",
25 | "Jettons",
26 | "jettons",
27 | "jojo",
28 | "masterchain",
29 | "Masterchain",
30 | "mathrm",
31 | "nanotons",
32 | "nextra",
33 | "omelander", // some superhero
34 | "Offchain",
35 | "quadtree",
36 | "quadtrees",
37 | "RAWRESERVE",
38 | "respecifying",
39 | "Satoshi",
40 | "seamus",
41 | "Seamus",
42 | "seqno",
43 | "shardchains",
44 | "stdlibs",
45 | "STON.fi",
46 | "TIMELOCK",
47 | "timeouted",
48 | "Timeouted",
49 | "Toncoin",
50 | "Toncoins",
51 | "Uninit",
52 | "vogons", // 42 vogons
53 | "workchain",
54 | "workchains",
55 | "xtwitter"
56 | ],
57 | "ignoreRegExpList": [
58 | "\\(#.*\\)",
59 | "^\\[.+\\]: .+", // link declarations like [foo]: /ref/stdlib-ownable#bar
60 | "\\[.+\\]\\[.+\\]", // links like [`Resumable{:tact}`][res]
61 | "\\[.+\\]\\(.+\\)", // links like [`self.toCell().asSlice(){:tact}`](/ref/core-cells#cellasslice)
62 | "address\\(\".+\"\\)", // Ton addresses
63 | "mathrm\\{.+\\}", // LaTeX subset
64 | "\\[#.+\\]", // [#nativereserve-combining-modes-with-flags]
65 | "href=\".+\"", // href="/cookbook/dexes/stonfi"
66 | "\".+\": \".+\"", // "from": "kQBrSAP2y7QIUw4_1q0qciHfqdFmOYR9CC1oinn7kyWWRuoV",
67 | "Urls"
68 | ],
69 | "flagWords": [],
70 | "ignorePaths": [
71 | ".github/temp-archive",
72 | "components/icons",
73 | "dist",
74 | "grammars/grammar-ohm.json",
75 | "grammars/grammar-tact.json",
76 | "next.config.js",
77 | "node_modules",
78 | "out",
79 | "package.json",
80 | "pages/cookbook/dexes/_meta.js",
81 | "pages/ref/spec.mdx"
82 | ]
83 | }
84 |
--------------------------------------------------------------------------------
/grammars/grammar-func.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
3 | "name": "FunC",
4 | "foldingStartMarker": "\\{\\s*$",
5 | "foldingStopMarker": "^\\s*\\}",
6 | "patterns": [
7 | {
8 | "include": "#keywords"
9 | },
10 | {
11 | "include": "#strings"
12 | },
13 | {
14 | "include": "#directives"
15 | },
16 | {
17 | "include": "#numeric"
18 | },
19 | {
20 | "include": "#comments"
21 | },
22 | {
23 | "include": "#storage"
24 | },
25 | {
26 | "include": "#functions"
27 | },
28 | {
29 | "include": "#variables"
30 | }
31 | ],
32 | "repository": {
33 | "keywords": {
34 | "patterns": [
35 | {
36 | "name": "keyword.control.",
37 | "match": "\\b(if|ifnot|else|elseif|elseifnot|while|do|until|repeat|return|impure|method_id|forall|asm|inline|inline_ref)\\b"
38 | },
39 | {
40 | "name": "keyword.operator",
41 | "match": "(?<=\\s)(<=>|>=|<=|!=|==|\\^>>|\\~>>|>>|<<|\\/%|\\^%|\\~%|\\^\\/|\\~\\/|\\+=|-=|\\*=|\\/=|~\\/=|\\^\\/=|%=|\\^%=|<<=|>>=|~>>=|\\^>>=|&=|\\|=|\\^=|\\^|=|~|\\/|%|-|\\*|\\+|>|<|&|\\||:|\\?)(?=\\s)"
42 | },
43 | {
44 | "name": "keyword.other",
45 | "match": "\\b(false|true)\\b"
46 | }
47 | ]
48 | },
49 | "directives": {
50 | "name": "storage.modifier.import",
51 | "begin": "#include|#pragma",
52 | "end": ";",
53 | "patterns": [
54 | {
55 | "begin": "\"",
56 | "end": "\"",
57 | "name": "string.quoted.double"
58 | },
59 | {
60 | "match": "(>=|<=|=|>|<|\\^)?([0-9]+)(.[0-9]+)?(.[0-9]+)?",
61 | "name": "constant.numeric"
62 | }
63 | ]
64 | },
65 | "strings": {
66 | "name": "string.quoted.double.",
67 | "begin": "\"",
68 | "end": "\"(H|h|c|u|s|a)?"
69 | },
70 | "numeric": {
71 | "name": "constant.numeric",
72 | "match": "(-?([\\d]+|0x[\\da-fA-F]+))\\b"
73 | },
74 | "comments": {
75 | "patterns": [
76 | {
77 | "name": "comment.line",
78 | "match": ";;(.*)"
79 | },
80 | {
81 | "name": "comment.block",
82 | "begin": "{-",
83 | "end": "-}"
84 | }
85 | ]
86 | },
87 | "storage": {
88 | "patterns": [
89 | {
90 | "name": "storage.type",
91 | "match": "\\b(var|int|slice|tuple|cell|builder|cont|_)(?=[\\s\\),\\[\\]])"
92 | },
93 | {
94 | "name": "storage.modifier",
95 | "match": "\\b(global|const)\\s"
96 | }
97 | ]
98 | },
99 | "variables": {
100 | "patterns": [
101 | {
102 | "match": "(?!\")(`([^`]+)`|((?=_)_|(?={){|(?=})}|(?![_`{}]))([^;,\\[\\]\\(\\)\\s~.]+))",
103 | "name": "variable.name"
104 | }
105 | ]
106 | },
107 | "functions": {
108 | "patterns": [
109 | {
110 | "match": "(?!\")(`([^`]+)`|(\\.|~)?((?=_)_|(?={){|(?=})}|(?![_`{}]))([^;,\\[\\]\\(\\)\\s~.]+))(?=[\\(])",
111 | "name": "entity.name.function"
112 | }
113 | ]
114 | }
115 | },
116 | "scopeName": "source.func"
117 | }
118 |
--------------------------------------------------------------------------------
/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | import { getHighlighter, BUNDLED_LANGUAGES } from 'shiki';
2 | import nextra from 'nextra';
3 | import fs from 'fs';
4 |
5 | const grammar_tact = JSON.parse(fs.readFileSync('./grammars/grammar-tact.json', 'utf-8'));
6 | const grammar_func = JSON.parse(fs.readFileSync('./grammars/grammar-func.json', 'utf-8'));
7 | const grammar_ohm = JSON.parse(fs.readFileSync('./grammars/grammar-ohm.json', 'utf-8'));
8 |
9 | const rehypePrettyCodeOptions = {
10 | getHighlighter: options => {
11 | return getHighlighter({
12 | ...options,
13 | // NOTE: current version of Nextra doesn't support having dual themes,
14 | // but this version of One Dark looks good enough in the light mode too.
15 | theme: 'one-dark-pro',
16 | langs: [
17 | ...BUNDLED_LANGUAGES,
18 | {
19 | id: 'tact',
20 | scopeName: 'source.tact',
21 | grammar: grammar_tact,
22 | aliases: ['tact'],
23 | },
24 | {
25 | id: 'func',
26 | scopeName: 'source.func',
27 | grammar: grammar_func,
28 | aliases: ['func'],
29 | },
30 | {
31 | id: 'ohm',
32 | scopeName: 'source.ohm',
33 | grammar: grammar_ohm,
34 | aliases: ['ohm'],
35 | },
36 | ],
37 | });
38 | },
39 | };
40 |
41 | /**
42 | * @type {import('next').NextConfig}
43 | */
44 | const withNextra = nextra({
45 | theme: 'nextra-theme-docs',
46 | themeConfig: './theme.config.jsx',
47 | mdxOptions: {
48 | rehypePrettyCodeOptions
49 | },
50 | latex: true,
51 | defaultShowCopyCode: true
52 | });
53 |
54 | /**
55 | * @type {import('next').NextConfig}
56 | */
57 | export default withNextra({
58 | output: 'export',
59 | images: {
60 | unoptimized: true
61 | },
62 | // i18n: {
63 | // // locales: ['default', 'en', 'zh'],
64 | // locales: ['default', 'en'],
65 | // defaultLocale: 'default',
66 | // // localeDetection: false,
67 | // },
68 | webpack(config) {
69 | const allowedSvgRegex = /components\/icons\/.+\.svg$/
70 |
71 | const fileLoaderRule = config.module.rules.find(rule =>
72 | rule.test?.test?.('.svg')
73 | )
74 | fileLoaderRule.exclude = allowedSvgRegex
75 |
76 | config.module.rules.push({
77 | test: allowedSvgRegex,
78 | use: ['@svgr/webpack']
79 | })
80 | return config
81 | },
82 | });
83 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "module",
3 | "dependencies": {
4 | "@vercel/analytics": "^0.1.8",
5 | "next": "^13.1.2",
6 | "nextra": "^2.13.4",
7 | "nextra-theme-docs": "^2.13.4",
8 | "react": "^18.2.0",
9 | "react-dom": "^18.2.0"
10 | },
11 | "scripts": {
12 | "clean": "rm -fr .next out",
13 | "deps": "yarn install --frozen-lockfile",
14 | "dev": "yarn deps && yarn clean && next",
15 | "build": "yarn deps && yarn clean && next build",
16 | "post-build": "echo 'spell checking, link checking, formatting'",
17 | "build-pages": "yarn build && node ./scripts/redirects-generate.js",
18 | "next": "next",
19 | "spell": "cspell \"**\""
20 | },
21 | "devDependencies": {
22 | "@svgr/webpack": "^8.1.0",
23 | "@types/node": "^18.11.19",
24 | "@types/react": "18.2.61",
25 | "cspell": "^8.8.4",
26 | "typescript": "^4.9.5"
27 | },
28 | "license": "CC-BY-4.0",
29 | "packageManager": "yarn@1.22.22"
30 | }
31 |
--------------------------------------------------------------------------------
/pages/_app.mdx:
--------------------------------------------------------------------------------
1 | {/* import '../styles.css' */}
2 |
3 | import React from "react"
4 |
5 | export default function App({ Component, pageProps }) {
6 | return
7 | }
8 |
--------------------------------------------------------------------------------
/pages/_document.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import Document, { Html, Head, Main, NextScript, DocumentContext, DocumentInitialProps } from "next/document";
3 | import { Analytics } from "@vercel/analytics/react";
4 |
5 | class MyDocument extends Document {
6 | static async getInitialProps(
7 | ctx: DocumentContext
8 | ): Promise {
9 | const initialProps = await Document.getInitialProps(ctx)
10 |
11 | return initialProps
12 | };
13 | render() {
14 | return (
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | );
24 | }
25 | }
26 |
27 | export default MyDocument;
--------------------------------------------------------------------------------
/pages/_meta.js:
--------------------------------------------------------------------------------
1 | export default {
2 | index: {
3 | title: 'Tact Documentation',
4 | type: 'page',
5 | display: 'hidden',
6 | theme: {
7 | typesetting: 'article'
8 | }
9 | },
10 | book: {
11 | title: "Book",
12 | type: 'page',
13 | },
14 | cookbook: {
15 | title: "Cookbook",
16 | type: 'page',
17 | },
18 | ref: {
19 | title: "Reference",
20 | type: 'page',
21 | },
22 | ecosystem: {
23 | title: "Ecosystem",
24 | type: 'page',
25 | },
26 | }
27 |
--------------------------------------------------------------------------------
/pages/book/_meta.js:
--------------------------------------------------------------------------------
1 | export default {
2 | index: 'Overview',
3 | cs: 'Cheatsheets',
4 | '-- 1': {
5 | type: 'separator',
6 | title: 'Fundamentals of Tact',
7 | },
8 | types: 'Type system overview',
9 | integers: 'Integers',
10 | cells: 'Cells, Builders and Slices',
11 | maps: 'Maps',
12 | 'structs-and-messages': 'Structs and Messages',
13 | optionals: 'Optionals',
14 | contracts: 'Contracts',
15 | 'exit-codes': 'Exit codes',
16 | '-- 2': {
17 | type: 'separator',
18 | title: 'Expressiveness',
19 | },
20 | operators: 'Operators',
21 | expressions: 'Expressions',
22 | statements: 'Statements',
23 | constants: 'Constants',
24 | functions: 'Functions',
25 | '-- 3': {
26 | type: 'separator',
27 | title: 'Communication',
28 | },
29 | // <- NOTE
30 | // potential place for a rather short overview page describing asynchronous & actor-model nature
31 | // of TON Blockchain with respect to Tact and exchanging messages with it
32 | receive: 'Receive messages',
33 | bounced: 'Bounced messages',
34 | external: 'External messages',
35 | lifecycle: 'Message lifecycle',
36 | send: 'Sending messages',
37 | 'message-mode': 'Message mode',
38 | '-- 4': {
39 | type: 'separator',
40 | title: 'Going places',
41 | },
42 | deploy: 'Deployment',
43 | debug: 'Debugging',
44 | upgrades: 'Contract upgrades',
45 | import: 'Importing code',
46 | config: 'Configuration',
47 | masterchain: 'Masterchain',
48 | func: 'Compatibility with FunC',
49 | programmatic: 'Programmatic API',
50 | '-- Community': {
51 | type: 'separator',
52 | },
53 | 'telegram-link': {
54 | title: '✈️ Telegram',
55 | href: 'https://t.me/tactlang',
56 | newWindow: true
57 | },
58 | 'xtwitter-link': {
59 | title: '🐦 X/Twitter',
60 | href: 'https://twitter.com/tact_language',
61 | newWindow: true
62 | },
63 | }
64 |
--------------------------------------------------------------------------------
/pages/book/bounced.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from 'nextra-theme-docs'
2 |
3 | # Bounced messages
4 |
5 | When a contract sends a message with a flag `bounce` set to `true{:tact}`, then if the message wasn't processed properly, it would bounce back to the sender. This is useful when you want to make sure that the message was processed properly and if not — revert the changes.
6 |
7 | ## Caveats
8 |
9 | Currently, bounced messages in TON have only 224 usable data bits in the message body and don't have any references. This means that you can't recover much of the data from the bounced message. This is a limitation of the TON blockchain and will be fixed in the future. Tact helps you to check if your message fits the limit and in case it doesn't — suggests using a special type constructor `bounced{:tact}` for the bounced message receiver, that would construct a partial representation of the message that fits into the required limits.
10 |
11 | ## Bounced message receiver
12 |
13 |
14 |
15 | Bounced text messages are not supported yet.
16 |
17 |
18 |
19 | To receive a bounced message, define a `bounced(){:tact}` [receiver function](/book/contracts#receiver-functions) in your [contract](/book/contracts) or a [trait](/book/types#traits):
20 |
21 | ```tact {2-4}
22 | contract MyContract {
23 | bounced(msg: bounced) {
24 | // ...
25 | }
26 | }
27 | ```
28 |
29 | 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:
30 |
31 | ```tact /rawMsg: Slice/
32 | contract MyContract {
33 | bounced(rawMsg: Slice) {
34 | // ...
35 | }
36 | }
37 | ```
38 |
--------------------------------------------------------------------------------
/pages/book/constants.mdx:
--------------------------------------------------------------------------------
1 | # Constants
2 |
3 | Constants in Tact could be a little bit more advanced than in popular languages: they could be virtual and abstract. Smart contracts often need to implement multiple traits and sometimes you need to configure some of them in compile time. Constructors in traits are prohibited due to their unpredicted behavior. So, we have to use constants and fields instead to pass values to them. It is the job of a main contract to implement values and constants for all traits.
4 |
5 | ## Simple constant
6 |
7 | Let's start with a simple constant. It is a value that is defined in compile time and cannot be changed. You can define a constant on the top level or inside a contract/trait. Let's define a constant on top level:
8 |
9 | ```tact
10 | const MY_CONSTANT: Int = 42;
11 | ```
12 |
13 | Similar for traits and contracts:
14 |
15 | ```tact
16 | trait MyTrait {
17 | const MY_CONSTANT: Int = 42;
18 | }
19 |
20 | contract MyContract {
21 | const MY_CONSTANT: Int = 42;
22 | }
23 | ```
24 |
25 | ## Virtual and abstract constants
26 |
27 | Virtual constants are the constants that could be defined in a trait but changed in a contract. It is useful when you need to configure some of the traits in compile time. Let's define a virtual constant and an abstract one:
28 |
29 | ```tact
30 | trait MyTrait {
31 | virtual const MY_FEE: Int = ton("1.0");
32 | }
33 |
34 | trait MyAbstractTrait {
35 | abstract const MY_DEV_FEE: Int;
36 | }
37 | ```
38 |
39 | Now you can overwrite defaults in the contract:
40 |
41 | ```tact
42 | contract MyContract with
43 | MyTrait,
44 | MyAbstractTrait, // trailing comma is allowed
45 | {
46 | override const MY_FEE: Int = ton("0.5");
47 | override const MY_DEV_FEE: Int = ton("1000");
48 | }
49 | ```
50 |
51 | This could be very useful to help a compiler to have some values in compile time, for example, you can enable and disable features without needing to change the code and not wasting gas.
52 |
53 | ```tact
54 | trait Treasure {
55 | virtual const ENABLE_TIMELOCK: Bool = true;
56 |
57 | receive("Execute") {
58 | if (self.ENABLE_TIMELOCK) {
59 | //
60 | // This branch would be removed in compile time if ENABLE_TIMELOCK is false
61 | //
62 | }
63 | }
64 | }
65 |
66 | contract MyContract with Treasure {
67 | override const ENABLE_TIMELOCK: Bool = false;
68 | }
69 | ```
70 |
--------------------------------------------------------------------------------
/pages/book/cs/_meta.js:
--------------------------------------------------------------------------------
1 | export default {
2 | 'from-func': 'Coming from FunC',
3 | 'from-solidity': 'Coming from Solidity',
4 | }
5 |
--------------------------------------------------------------------------------
/pages/book/cs/from-func.mdx:
--------------------------------------------------------------------------------
1 | # Coming from FunC
2 |
3 | import { Callout } from 'nextra/components'
4 |
5 |
6 | This page awaits implementation in [#54](https://github.com/tact-lang/tact-docs/issues/54)
7 |
--------------------------------------------------------------------------------
/pages/book/cs/from-solidity.mdx:
--------------------------------------------------------------------------------
1 | # Coming from Solidity
2 |
3 | import { Callout } from 'nextra/components'
4 |
5 |
6 | This page awaits implementation in [#67](https://github.com/tact-lang/tact-docs/issues/67)
7 |
--------------------------------------------------------------------------------
/pages/book/deploy.mdx:
--------------------------------------------------------------------------------
1 | # Deploy
2 |
3 | Tact Deployer is a small library that integrates with [TON Verifier](https://verifier.ton.org) that allows you to deploy your contracts safely using your favorite wallet without needing to manage keys or deploy contracts manually. Tact Deployer also automatically verifies your contract's source code and you can be sure that your compiler is not compromised.
4 |
5 | ## Requirements
6 |
7 | Your contract MUST have the `Deployer` trait from the `@stdlib/deploy` package to be able to use Tact Deployer.
8 |
9 | ## Installation
10 |
11 | To add Tact Deployer to your project, just use `yarn`:
12 |
13 | ```bash
14 | yarn add @tact-lang/deployer
15 | ```
16 |
17 | ## How to use
18 |
19 | When you build your smart contracts using Tact, it produces a package (*.pkg) file that has all the required information about the built smart contract. To deploy your smart contract, you need to create a deployer instance, pass your package file to it and provide initial data for your contract.
20 |
21 | ```typescript
22 | import * as fs from 'fs';
23 | import * as path from 'path';
24 | import { Address, contractAddress } from "ton";
25 | import { SampleTactContract } from "./output/sample_SampleTactContract";
26 | import { prepareTactDeployment } from "@tact-lang/deployer";
27 |
28 | // Parameters
29 | let testnet = true; // Flag for testnet or mainnet
30 | let packageName = 'sample_SampleTactContract.pkg'; // Name of your package to deploy
31 | let outputPath = path.resolve(__dirname, 'output'); // Path to output directory
32 | let owner = Address.parse(''); // Our sample contract has an owner
33 | let init = await SampleTactContract.init(owner); // Create initial data for our contract
34 |
35 | // Calculations
36 | let address = contractAddress(0, init); // Calculate contract address. MUST match with the address in the verifier
37 | let data = init.data.toBoc(); // Create init data
38 | let pkg = fs.readFileSync( // Read package file
39 | path.resolve(outputPath, packageName)
40 | );
41 |
42 | // Prepare deploy
43 | let link = await prepareTactDeployment({ pkg, data, testnet });
44 |
45 | // Present a deployment link and contract address
46 | console.log('Address: ' + address.toString({ testOnly: testnet }));
47 | console.log('Deploy link: ' + link);
48 | ```
49 |
50 | After following this link you will be able to deploy and verify your smart contract.
--------------------------------------------------------------------------------
/pages/book/external.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from "nextra-theme-docs";
2 |
3 | # External Messages
4 |
5 |
6 | External message support must be enabled explicitly in the project configuration.
7 | Without enabling it compilation would fail.
8 |
9 |
10 | External messages are those that don't have a sender and can be sent by anyone in the world. External messages are good tools for integrating with off-chain systems or for the general maintenance of contracts. Handling external messages is different from handling internal messages. In this section, we will cover how to handle external messages.
11 |
12 | ## How External Messages are Different
13 |
14 | External messages are different from internal messages in the following ways:
15 |
16 | ### Contracts Pay for Gas Usage Themselves
17 |
18 | When processing internal messages, the sender usually pays for gas usage. When processing external messages, the contract pays for gas usage. This means that you need to be careful with gas usage in external messages. You should always test the gas usage of your contracts and verify that everything is working as intended.
19 |
20 | ### Messages Have to Be Accepted Manually
21 |
22 | External messages are not accepted automatically. You need to accept them manually. This is done by calling the `acceptMessage` function. If you don't call the `acceptMessage` function, the message will be rejected. This is done to prevent the spamming of external messages.
23 |
24 | ### 10k Gas Limit Before Message Acceptance
25 |
26 | 10k gas is a very small limit, and Tact itself can consume a sizable amount of gas before it even reaches your code. You should always test the gas usage of your contracts and verify that everything is working as intended.
27 |
28 |
29 | The 10k gas limit for external messages is based on the parameter we set by the
30 | validator for the whole blockchain of the `gas_limit` field. You can take
31 | the reference here:
32 | - https://docs.ton.org/develop/smart-contracts/guidelines/accept#external-messages
33 | - https://docs.ton.org/develop/howto/blockchain-configs#param-20-and-21
34 |
35 |
36 |
37 | ### Unbounded Gas Usage After Message Acceptance
38 |
39 | After you accept the gas, the contract can use as much gas as it wants. This is done to allow the contract to carry out any kind of processing. You should always test the gas usage of your contracts and verify that everything is working as intended, and avoid possible vulnerabilities that could drain the contract balance.
40 |
41 | ### No Context Available
42 |
43 | When processing an external message, the `context` and `sender` functions are not available. This is because there is no context available for external messages. This means that you can't use the `context` and `sender` functions in external messages. You need to carefully test your contract to make sure that it doesn't use the `context` and `sender` functions.
44 |
45 | ## Enable External Messages Support
46 |
47 | To enable external messages support, please enable it in the project configuration file:
48 |
49 | ```json
50 | {
51 | "options": {
52 | "external": true
53 | }
54 | }
55 | ```
56 |
57 | ## External receivers
58 |
59 | External receivers are defined the same way as internal ones, but using the `external` keyword instead of `receive`:
60 |
61 | ```tact
62 | contract SampleContract {
63 | external("Check Timeout") {
64 |
65 | // Check for contract timeout
66 | require(self.timeout > now(), "Not timeouted");
67 |
68 | // Accept message
69 | acceptMessage();
70 |
71 | // Timeout processing
72 | self.onTimeouted();
73 | }
74 | }
75 | ```
76 |
--------------------------------------------------------------------------------
/pages/book/functions.mdx:
--------------------------------------------------------------------------------
1 | # Functions and their types
2 |
3 | Functions in Tact could be defined in different ways:
4 |
5 | * Global static function
6 | * Extension functions
7 | * Mutable functions
8 | * Native functions
9 | * Receiver functions
10 | * Getter functions
11 |
12 | All functions, except for [receiver functions](#receiver-functions) can have a trailing comma in their definitions (parameter lists) and calls (argument lists):
13 |
14 | ```tact
15 | fun foo(
16 | a: Int, // trailing comma in parameter lists is allowed
17 | ) {}
18 |
19 | fun bar() {
20 | foo(
21 | 5, // trailing comma in argument lists is allowed too!
22 | );
23 | }
24 | ```
25 |
26 | ## Global static functions
27 |
28 | You can define global function anywhere in your program:
29 |
30 | ```tact
31 | fun customPow(a: Int, c: Int): Int {
32 | let res: Int = 1;
33 | repeat(c) {
34 | res *= a;
35 | }
36 | return res;
37 | }
38 | ```
39 |
40 | ## Virtual and abstract functions
41 |
42 | You can allow the contract inheriting a [traits](/book/types#traits) to modify an internal function, if it has the `virtual{:tact}` keyword, using `override{:tact}`. The function can be also marked as `abstract{:tact}`, in which case the inheriting contract has to define its implementation:
43 |
44 | ```tact
45 | trait FilterTrait with Ownable {
46 | // Virtual functions can be overridden by users of this trait
47 | virtual fun filterMessage(): Bool {
48 | return sender() != self.owner;
49 | }
50 |
51 | abstract fun specialFilter(): Bool;
52 | }
53 |
54 | contract Filter with FilterTrait {
55 | // Overriding default behavior of the FilterTrait
56 | override fun filterMessage(): Bool {
57 | return true;
58 | }
59 |
60 | override fun specialFilter(): Bool {
61 | return true;
62 | }
63 | }
64 | ````
65 |
66 | ## Extension function
67 |
68 | Extension functions allow you to implement extensions for any possible type.
69 |
70 | > **Warning**
71 | > The name of the first argument MUST be named `self` and the type of this argument is the type you are extending.
72 |
73 | ```tact
74 | extends fun customPow(self: Int, c: Int): Int {
75 | let res: Int = 1;
76 | repeat(c) {
77 | res *= self;
78 | }
79 | return res;
80 | }
81 | ```
82 |
83 | ## Mutable functions
84 |
85 | Mutable functions are performing mutation of a value replacing it with an execution result. To perform mutation, the function must change the `self` value.
86 |
87 | ```tact
88 | extends mutates fun customPow(self: Int, c: Int) {
89 | let res: Int = 1;
90 | repeat(c) {
91 | res *= self;
92 | }
93 | self = res;
94 | }
95 | ```
96 |
97 | ## Native functions
98 |
99 | Native functions are direct bindings of FunC functions:
100 |
101 | > **Note**
102 | > Native functions could be also mutable and extension ones.
103 |
104 | ```tact
105 | @name(store_uint)
106 | native storeUint(s: Builder, value: Int, bits: Int): Builder;
107 |
108 | @name(load_int)
109 | extends mutates native loadInt(self: Slice, l: Int): Int;
110 | ```
111 |
112 | ## Receiver functions
113 |
114 | Receiver functions are special functions that are responsible for receiving messages in contracts and could be defined only within a contract or trait.
115 |
116 | ```tact
117 | contract Treasure {
118 | // This means that this contract can receive the comment "Increment" and this function would be called for such messages
119 | receive("Increment") {
120 | self.counter += 1;
121 | }
122 | }
123 | ```
124 |
125 | ## Getter Functions
126 |
127 | Getter functions define getters on smart contracts and can be defined only within a contract or trait.
128 |
129 | ```tact
130 | contract Treasure {
131 | get fun counter(): Int {
132 | return self.counter;
133 | }
134 | }
135 | ```
136 |
--------------------------------------------------------------------------------
/pages/book/import.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from 'nextra-theme-docs'
2 |
3 | # Importing code
4 |
5 | Tact allows you to import Tact and [FunC](https://docs.ton.org/develop/func/overview) code — any given `.tact` or `.fc`/`.func` file can be imported into your project using an `import{:tact}` keyword.
6 |
7 | Additionally, Tact compiler has a versatile set of standard libraries, which come bundled in, but not included right away, see [Standard libraries overview](/ref/standard-libraries).
8 |
9 |
10 | NOTE: All imported code is combined together with yours, so it's important to avoid name collisions and always double-check the sources!
11 |
12 |
13 | ## Import Tact code
14 |
15 | It's possible to import any Tact code using the `import{:tact}` statement and providing a relative path to the target `.tact` file like so:
16 |
17 | ```tact
18 | import "./relative/path/to/the/target/tact/file.tact";
19 | ```
20 |
21 | Specifying parent directories (`../`) is also possible:
22 |
23 | ```tact
24 | import "../subfolder/imported/file.tact";
25 | ```
26 |
27 | ## Import FunC code
28 |
29 | It's possible to import code written in FunC code directly just as it's done with Tact code imports:
30 |
31 | ```tact
32 | // Relative import
33 | import "./relative/path/to/the/target/func/file.fc";
34 |
35 | // Specifying parent directories
36 | import "../subfolder/imported/func/file.fc";
37 | ```
38 |
39 | But in order to use functions from such file, one has to declare them as `native` functions first. For example, when standard library [@stdlib/dns](/ref/stdlib-dns) uses a `dns.fc` FunC file, it maps FunC functions to Tact ones like so:
40 |
41 | ```tact
42 | // FunC code located in a file right next to the current Tact one:
43 | import "./dns.fc";
44 |
45 | // Mapping function signatures from FunC to Tact:
46 | @name(dns_string_to_internal)
47 | native dnsStringToInternal(str: String): Slice?;
48 | ```
49 |
50 | ## Standard libraries
51 |
52 | See [Standard libraries overview](/ref/standard-libraries).
53 |
--------------------------------------------------------------------------------
/pages/book/index.mdx:
--------------------------------------------------------------------------------
1 | # Book overview
2 |
3 | import { Cards, Steps } from 'nextra/components'
4 |
5 | Welcome to **The Tact Book** section (or just **The Book**), — an introductory book about the Tact language.
6 |
7 | Here are its main contents:
8 |
9 |
10 |
11 | ### Cheatsheets
12 |
13 | [Cheatsheets](/book/cs/from-func) are quick rundowns on Tact syntax and idioms with comparison to other blockchain languages, such as FunC (also on TON) and Solidity (Ethereum blockchain). Use those to transition to Tact as swiftly as possible.
14 |
15 |
16 |
21 |
22 |
23 | ### Book
24 |
25 | [**The Tact Book**](/book/types) is a cohesive and streamlined sequence of educational materials about Tact. In general, it assumes that you’re reading it in sequence from front to back. Later parts build on concepts in earlier parts, and earlier parts might not delve into details on a particular topic but will revisit the topic in a later part.
26 |
27 | Additionally, there are many references to the Language section of the documentation, where many primitives of the language are described in much more fine detail. Additionally, whenever there's an existing explanation of the broader TON concept in the main TON documentation, this Book tries to reference it as well.
28 |
29 | Book also assumes that you’ve written code in another programming language but doesn’t make any assumptions about which one. We’ve tried to make the material broadly accessible to those from a wide variety of programming backgrounds. We don’t spend a lot of time talking about what programming _is_ or how to think about it. If you’re entirely new to programming, you would be better served by reading a book that specifically provides an introduction to programming.
30 |
31 |
32 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/pages/book/lifecycle.mdx:
--------------------------------------------------------------------------------
1 | # Message Lifecycle
2 |
3 | There are several stages of message processing by a contract, there are more of them, but we would focus on the most important ones:
4 |
5 | ## Receive Phase
6 |
7 | This phase combines multiple low-level phases.
8 |
9 | It starts by adding a **message value to the contract balance**. The value of an incoming message is the maximum price that a contract can pay for gas to process this message. The contract can overwrite this limit, but it is not recommended and is suitable only for advanced developers since it could lead to a contract being drained. 1 million of gas is the maximum amount that a contract can spend in a single contract which equals 0.4 TON for basechain (currently). If the message value is zero then execution is aborted.
10 |
11 | Then some (usually small) amount of nanotons gets subtracted from the contract balance for storage. This means that you can't perfectly predict balance changes and have to adjust your code to this instability.
12 |
13 | Then it deploys a contract if it is not deployed yet and the message contains the init package. If the init package isn't present, it will be ignored.
14 |
15 | ## Compute Phase
16 |
17 | This phase executes the code of a smart contract and produces a list of actions or an exception. Currently, only two types of actions are supported: **send message** and **reserve**.
18 |
19 | Sending a message could use a fixed value or a dynamic value like **remaining value of a message** - the remaining value of the incoming message. Sending a message could be with a flag `SendIgnoreErrors` that would ignore errors during message sending and would continue to the next action. This flag is useful if you have multiple actions. When sending a message with some value, it first subtracts this value from the incoming value and only then from the contract balance (before processing).
20 |
21 | ## Action Phase
22 |
23 | Actions are executed in sequence, but bear in mind:
24 | **EXCEPTION DURING PROCESSING ACTIONS WOULDN'T REVERT THE TRANSACTION**
25 |
26 | For example, if you subtract 1 ton from a customer's balance and then send an invalid message, that could lead to a situation when the customer's balance is subtracted, but he wouldn't receive it.
27 |
--------------------------------------------------------------------------------
/pages/book/masterchain.mdx:
--------------------------------------------------------------------------------
1 | # Masterchain
2 |
3 | import { Callout } from 'nextra-theme-docs'
4 |
5 |
6 |
7 | Masterchain addresses are treated as invalid unless the `masterchain` option in the [configuration file](/book/config) is set to `true{:json}`.
8 |
9 |
10 |
11 | In TON Blockchain, a special chain called ["masterchain"](https://docs.ton.org/learn/overviews/ton-blockchain#masterchain-blockchain-of-blockchains) is used to synchronize message routing and transaction execution, so that nodes in the network can fix a particular point in a multi-chain state and reach a consensus about that state.
12 |
13 | Masterchain stores the [network configuration](/ref/core-advanced#getconfigparam) and the final state of all [workchains](https://docs.ton.org/learn/overviews/ton-blockchain#workchain-blockchain-with-your-own-rules). It carries fundamental protocol information, including current settings, a list of active validators and their stakes, active workchains, and associated [shardchains](https://docs.ton.org/develop/blockchain/shards). Most importantly, it maintains a record of the latest block hashes for all workchains and shardchains, enforcing consensus across the network.
14 |
15 | ## How contract is protected from masterchain [#protection]
16 |
17 | Tact enforces all contracts to use the [basechain](https://docs.ton.org/develop/blockchain/shards), which is the default workchain with ID $0$. This is done to prevent masterchain addresses from being used in the contract.
18 |
19 | Any attempts to point to masterchain or otherwise interact with it without [enabling masterchain support](#enable-support) throw an exception with [exit code 137](/book/exit-codes#137): `Masterchain support is not enabled for this contract`.
20 |
21 | That is, accidental deployments to the masterchain, receiving messages from masterchain accounts, sending messages to such accounts, and using masterchain addresses or its chain ID ($-1$) are all prohibited by default.
22 |
23 | ## Enabling masterchain support in compilation options [#support]
24 |
25 |
26 |
27 | Most contracts don't need to be deployed on a masterchain or have any interactions on a masterchain. That's because the masterchain is primarily used for voting or storing libraries. If you don't need to partake in those things, you don't need to enable masterchain support.
28 |
29 |
30 |
31 | If you really do need masterchain support, the simplest and recommended approach is to modify a [`tact.config.json`](/book/config) file in the root of your project (or create it if it didn't exist yet), and [set the `masterchain` property to `true{:json}`](/book/config#options-masterchain).
32 |
33 | If you're working on a [Blueprint][bp]-based project, you can enable masterchain support in the compilation configs of your contracts, which are located in a directory named `wrappers/`:
34 |
35 | ```typescript filename="wrappers/YourContractName.compile.ts" {7}
36 | import { CompilerConfig } from '@ton/blueprint';
37 |
38 | export const compile: CompilerConfig = {
39 | lang: 'tact',
40 | target: 'contracts/your_contract_name.tact',
41 | options: {
42 | masterchain: true, // ← that's the stuff!
43 | }
44 | };
45 | ```
46 |
47 | However, [`tact.config.json`](/book/config) may still be used in [Blueprint][bp] projects. In such cases values specified in [`tact.config.json`](/book/config) act as default unless modified in the `wrappers/`.
48 |
49 | [bp]: https://github.com/ton-org/blueprint
50 |
--------------------------------------------------------------------------------
/pages/book/message-mode.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from 'nextra/components'
2 |
3 | # Message `mode`
4 |
5 | As it was previously mentioned, messages are sent with the `mode` param of a struct `SendParameters{:tact}`. It's an [`Int{:tact}`][int] value, which is combined from base modes and optional flags, which are also [`Int{:tact}`][int] values.
6 |
7 | It's possible to use raw [`Int{:tact}`][int] values and manually provide them for the `mode`, but for your convenience there's a set of constants which you may use to construct the compound `mode` with ease. Take a look at the following tables for more information on base modes and optional flags.
8 |
9 | ## Base modes
10 |
11 | Mode value | Constant name | Description
12 | ---------: | :---------------------------- | -----------
13 | $0$ | - | Ordinary message (default).
14 | $64$ | `SendRemainingValue{:tact}` | Carry all the remaining value of the inbound message in addition to the value initially indicated in the new message.
15 | $128$ | `SendRemainingBalance{:tact}` | Carry all the remaining balance of the current smart contract instead of the value originally indicated in the message.
16 |
17 | ## Optional flags
18 |
19 | Flag value | Constant name | Description
20 | ---------: | :------------------------------ | -----------
21 | $+1$ | `SendPayGasSeparately{:tact}` | Pay forward fees separately from the message value.
22 | $+2$ | `SendIgnoreErrors{:tact}` | Ignore any errors arising while processing this message during the action phase.
23 | $+16$ | `SendBounceIfActionFail{:tact}` | Bounce transaction in case of any errors during action phase. Has no effect if flag $+2$, `SendIgnoreErrors{:tact}` is used.
24 | $+32$ | `SendDestroyIfZero{:tact}` | Current account must be destroyed if its resulting balance is zero (often used with mode $128$, `SendRemainingBalance{:tact}`).
25 |
26 | ## Combining modes with flags
27 |
28 | To make the [`Int{:tact}`][int] value for `mode` field of `SendParameters{:tact}`, you just have to combine base modes with optional flags by applying the [bitwise OR](/book/operators#binary-bitwise-or) operation.
29 |
30 | For example, if you want to send a regular message and pay transfer fees separately, use the mode $0$ (default) and a flag $+1$ to get `mode` $= 1$, which is equal to using `SendPayGasSeparately{:tact}` constant.
31 |
32 | Alternatively, if you want to send the whole contract balance and destroy it immediately, use the mode $128$ and flag $+32$ to get `mode` $= 160$, which is equal to `SendRemainingBalance | SendDestroyIfZero{:tact}`.
33 |
34 | Here's how the latter example would look in code:
35 |
36 | ```tact
37 | let to: Address = ...;
38 | let value: Int = ton("1");
39 | send(SendParameters{
40 | to: to,
41 | value: value,
42 | mode: SendRemainingBalance | SendDestroyIfZero,
43 | body: "Hello, World!".asComment(),
44 | });
45 | ```
46 |
47 |
48 |
49 | Note, that while adding ([`+{:tact}`](/book/operators#binary-add)) base modes together with optional flags is possible, it is discouraged due to the possibility of excess values. Use the bitwise OR ([`|{:tact}`](/book/operators#binary-bitwise-or)) instead, as it's designed to work with such flag and bit manipulations of the `mode`.
50 |
51 |
52 |
53 |
54 |
55 | Also note, that there can be only one [base mode](#base-modes), but number of [optional flags](#optional-flags) may vary: you can use them all, none or just some.
56 |
57 |
58 |
59 | [int]: /book/integers
60 |
--------------------------------------------------------------------------------
/pages/book/optionals.mdx:
--------------------------------------------------------------------------------
1 | # Optionals
2 |
3 | import { Callout } from 'nextra/components'
4 |
5 | As it was mentioned in [type system overview](/book/types#optionals), all [primitive types](/book/types#primitive-types), [Structs](/book/structs-and-messages#structs) and [Messages](/book/structs-and-messages#messages) could be nullable. That is, they don't necessarily hold any value, aside from `null{:tact}` — a special value, which represents the intentional absence of any other value.
6 |
7 | [Variables](/book/statements#let) or fields of [Structs](/book/structs-and-messages#structs) and [Messages](/book/structs-and-messages#messages) that can hold `null{:tact}` are called "optionals". They're useful to reduce state size when the variable isn't necessarily used.
8 |
9 | You can make any variable or a field an optional by adding a question mark (`?{:tact}`) after its type declaration. The only exceptions are [`map{:tact}`](/book/maps) and [`bounced{:tact}`](/book/bounced#bounced-messages-in-tact), where you can't make them, inner key/value type (in case of a map) or the inner [Message](/book/structs-and-messages#messages) (in case of a bounced) optional.
10 |
11 | Optional variables or optional fields that are not defined hold the `null{:tact}` value by default. You cannot access them without checking for `null{:tact}` first. But if you're certain they are not `null{:tact}` at a given moment, use the [non-null assertion operator `!!{:tact}`](/book/operators#unary-non-null-assert) to access their value.
12 |
13 | Trying to access the value of an optional variable or an optional field without using [`!!{:tact}`](/book/operators#unary-non-null-assert) or without checking for `null{:tact}` beforehand will result in a compilation error.
14 |
15 | Example of optionals:
16 |
17 | ```tact
18 | struct StOpt {
19 | opt: Int?; // Int or null
20 | }
21 |
22 | message MsOpt {
23 | opt: StOpt?; // Notice, how the struct StOpt is used in this definition
24 | }
25 |
26 | contract Optionals {
27 | opt: Int?;
28 | address: Address?;
29 |
30 | init(opt: Int?) { // optionals as parameters
31 | self.opt = opt;
32 | self.address = null; // explicit null value
33 | }
34 |
35 | receive(msg: MsOpt) {
36 | let opt: Int? = 12; // defining a new variable
37 | if (self.opt != null) { // explicit check
38 | self.opt = opt!!; // using !! as we know that opt value isn't null
39 | }
40 | }
41 | }
42 | ```
43 |
--------------------------------------------------------------------------------
/pages/book/programmatic.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from "nextra-theme-docs";
2 |
3 | # Programmatic API
4 |
5 | You can invoke the Tact compiler from your code in node and browser environments.
6 |
7 |
8 | This API has not been released yet. It will be released in the 1.0.0 version.
9 |
10 |
11 | ## Run compiler in browser
12 |
13 | ```ts
14 | import { run } from "@tact-lang/compiler";
15 |
16 | // Virtual FS
17 | const fs = {
18 | ["main.tact"]: Buffer.from("...").toString("base64"),
19 | };
20 |
21 | const config = {
22 | projects: [
23 | {
24 | name: "Sample",
25 | path: "main.tact",
26 | output: "./output",
27 | },
28 | ],
29 | };
30 |
31 | // Run compiler
32 | let successful = await run({ config, fs });
33 |
34 | // NOTE: Output from is written to the same fs object.
35 | ```
36 |
37 | ## Contract verification
38 |
39 | You can always verify the compiled package with the `verify` function.
40 |
41 | ```ts
42 | import { verify } from "@tact-lang/compiler";
43 | const pkg: string = '...';
44 | const res = await verify(pkg);
45 | ```
--------------------------------------------------------------------------------
/pages/book/receive.mdx:
--------------------------------------------------------------------------------
1 | # Receive messages
2 |
3 | TON is a distributed blockchain which means that communication between contracts is done by sending and receiving messages. The most common type of message is the internal message - a message sent from one contract (or a wallet) to another.
4 |
5 | ## Receive internal messages
6 |
7 | To receive a message of the required type, you need to declare a receiver function, for example, `receive("increment"){:tact}`. This notation means the declaration of a receiver function that will be called when a text with the value `"increment"{:tact}` is sent to the contract. The function body can modify the state of the contract and send messages to other contracts. It is impossible to call a receiver directly. If you need to reuse some logic you can declare a function and call it from the receiver.
8 |
9 | There are several receiver functions. All receiver functions are processed in the order they are listed below:
10 |
11 | * `receive(){:tact}` - called when an empty message is sent to the contract
12 | * `receive("message"){:tact}` - called when a text message with a specific comment is sent to the contract
13 | * `receive(str: String){:tact}` - called when an arbitrary text message is sent to the contract
14 | * `receive(msg: MyMessage){:tact}` - called when a binary message of type `MyMessage` is sent to the contract
15 | * `receive(msg: Slice){:tact}` - called when binary message of unknown type is sent to the contract
16 |
17 | ```tact
18 | message MyMessage {
19 | value: Int;
20 | }
21 |
22 | contract MyContract {
23 | receive() {
24 | // ...
25 | }
26 | receive("message") {
27 | // ...
28 | }
29 | receive(str: String) {
30 | // ...
31 | }
32 | receive(msg: MyMessage) {
33 | // ...
34 | }
35 | receive(msg: Slice) {
36 | // ...
37 | }
38 | }
39 | ```
40 |
41 | Naming a parameter of the receiver function with an underscore `_{:tact}` makes its value considered unused and discarded. This is useful when you don't need to inspect the message received and you only want it to convey a specific opcode:
42 |
43 | ```tact
44 | message(42) UniverseCalls {}
45 |
46 | contract Example {
47 | receive(_: UniverseCalls) {
48 | // Got a Message with opcode 42
49 | }
50 | }
51 | ```
52 |
--------------------------------------------------------------------------------
/pages/book/upgrades.mdx:
--------------------------------------------------------------------------------
1 | # Contracts upgrades
2 |
3 | Tact currently doesn't allow contract upgrades since Tact contracts have a more convoluted nature than the ones in FunC. It is theoretically possible, but the required tools are not here.
4 |
--------------------------------------------------------------------------------
/pages/cookbook/_meta.js:
--------------------------------------------------------------------------------
1 | export default {
2 | index: 'Overview',
3 | '-- 1': {
4 | type: 'separator',
5 | title: 'Single contract',
6 | },
7 | 'single-communication': 'Single-contract communication',
8 | 'type-conversion': 'Type conversion',
9 | 'data-structures': 'Data structures',
10 | algo: 'Algorithms',
11 | time: 'Time and date',
12 | access: 'Access control',
13 | random: 'Randomness',
14 | misc: 'Miscellaneous',
15 | '-- 2+': {
16 | type: 'separator',
17 | title: 'Multiple contracts',
18 | },
19 | 'multi-communication': 'Multi-contract communication',
20 | jettons: 'Fungible Tokens (Jettons)',
21 | nfts: 'Non-Fungible Tokens (NFTs)',
22 | dexes: 'Decentralized EXchanges (DEXes)',
23 | '-- Community': {
24 | type: 'separator',
25 | },
26 | 'telegram-link': {
27 | title: '✈️ Telegram',
28 | href: 'https://t.me/tactlang',
29 | newWindow: true
30 | },
31 | 'xtwitter-link': {
32 | title: '🐦 X/Twitter',
33 | href: 'https://twitter.com/tact_language',
34 | newWindow: true
35 | },
36 | }
37 |
--------------------------------------------------------------------------------
/pages/cookbook/access.mdx:
--------------------------------------------------------------------------------
1 | # Access control
2 |
3 | import { Callout } from 'nextra/components'
4 |
5 | This page lists common examples of working with privileges, ownership and access control.
6 |
7 | ## How to check sender privileges using Ownable trait
8 |
9 | ```tact
10 | // Ownable has to be imported from stdlib, as well as Deployable, for convenience:
11 | import "@stdlib/ownable";
12 | import "@stdlib/deploy";
13 |
14 | message FooBarMsg {
15 | newVal: Int as uint32;
16 | }
17 |
18 | // Ownable trait can limit certain actions to the owner only
19 | contract SenderChecker with Deployable, Ownable {
20 | // Persistent state variables
21 | owner: Address; // Ownable trait requires you to add this exact state variable
22 | val: Int as uint32; // some value
23 |
24 | init() {
25 | // we can initialize owner to any value we want, the deployer in this case:
26 | self.owner = sender();
27 | self.val = 0;
28 | }
29 |
30 | receive("inc") {
31 | self.requireOwner(); // throws exit code 132 if the sender isn't an owner
32 | self.val += 1;
33 | }
34 |
35 | receive(msg: FooBarMsg) {
36 | self.requireOwner(); // throws exit code 132 if the sender isn't an owner
37 | self.val = msg.newVal;
38 | }
39 | }
40 | ```
41 |
42 |
43 |
44 | **Useful link:**\
45 | [`trait Ownable{:tact}` in Core library](/ref/stdlib-ownable#ownable)
46 |
47 |
48 |
49 |
50 |
51 | Didn't find your favorite example of access control? Have cool implementations in mind? [Contributions are welcome!](https://github.com/tact-lang/tact-docs/issues)
52 |
53 |
54 |
--------------------------------------------------------------------------------
/pages/cookbook/algo.mdx:
--------------------------------------------------------------------------------
1 | # Algorithms
2 |
3 | import { Callout, Steps } from 'nextra/components'
4 |
5 | Algorithm is a finite sequence of rigorous instructions, typically used to solve a class of specific problems or to perform a computation.
6 |
7 |
8 |
9 | This page is a stub. [Contributions are welcome!](https://github.com/tact-lang/tact-docs/issues)
10 |
11 |
12 |
--------------------------------------------------------------------------------
/pages/cookbook/dexes/_meta.js:
--------------------------------------------------------------------------------
1 | export default {
2 | dedust: 'DeDust.io',
3 | stonfi: 'STON.fi',
4 | }
5 |
--------------------------------------------------------------------------------
/pages/cookbook/dexes/dedust.mdx:
--------------------------------------------------------------------------------
1 | # DeDust.io
2 |
3 | import { Callout, Steps, Tabs } from 'nextra/components'
4 |
5 | {/* See: https://nextra.site/docs/guide/built-ins */}
6 |
7 | [DeDust](https://dedust.io) is a decentralized exchange (DEX) and automated market maker (AMM) built natively on [TON Blockchain](https://ton.org) and [DeDust Protocol 2.0](https://docs.dedust.io/reference/tlb-schemes). DeDust is designed with a meticulous attention to user experience (UX), gas efficiency, and extensibility.
8 |
9 |
10 |
11 | This page is a stub until it gets new content in [#146](https://github.com/tact-lang/tact-docs/issues/146).
12 |
13 |
14 |
--------------------------------------------------------------------------------
/pages/cookbook/dexes/stonfi.mdx:
--------------------------------------------------------------------------------
1 | # STON.fi
2 |
3 | import { Callout, Steps, Tabs } from 'nextra/components'
4 |
5 | {/* See: https://nextra.site/docs/guide/built-ins */}
6 |
7 | [STON.fi](https://ston.fi) is a decentralized automated market maker (AMM) built on [TON blockchain](https://ton.org) providing virtually zero fees, low slippage, an extremely easy interface, and direct integration with TON wallets.
8 |
9 |
10 |
11 | This page is a stub until it gets new content in [#149](https://github.com/tact-lang/tact-docs/issues/149).
12 |
13 |
14 |
--------------------------------------------------------------------------------
/pages/cookbook/index.mdx:
--------------------------------------------------------------------------------
1 | # Cookbook overview
2 |
3 | import { Callout, Steps, Cards } from 'nextra/components'
4 | import { OneIcon, FormulaIcon, DiagramIcon, DropperIcon, BoxIcon, IdCardIcon, WarningIcon, StarsIcon, RowsIcon, GearIcon, LightningIcon } from '@components/icons'
5 |
6 | The main reason for making the Tact Cookbook is to gather all the experiences of Tact developers in one place so that future developers can use it. This section of the documentation is more focused on everyday tasks that every Tact developer resolves during the development of smart contracts.
7 |
8 | Use it as a recipe book for cooking up delightful smart contracts on TON Blockchain without re-inventing the wheel in the process.
9 |
10 |
11 |
12 | ### Single contract [#single-contract]
13 |
14 | Following pages focus on single-contract examples and cover a wide range of topics:
15 |
16 |
17 | }
19 | title="Single-contract communication"
20 | href="/cookbook/single-communication"
21 | />
22 | }
24 | title="Type conversion"
25 | href="/cookbook/type-conversion"
26 | />
27 | }
29 | title="Data structures"
30 | href="/cookbook/data-structures"
31 | />
32 | }
34 | title="Algorithms"
35 | href="/cookbook/algo"
36 | />
37 | }
39 | title="Time and date"
40 | href="/cookbook/time"
41 | />
42 | }
44 | title="Access control"
45 | href="/cookbook/access"
46 | />
47 | }
49 | title="Randomness"
50 | href="/cookbook/random"
51 | />
52 | }
54 | title="Miscellaneous"
55 | href="/cookbook/misc"
56 | />
57 |
58 |
59 | ### Multiple contracts [#multiple-contracts]
60 |
61 | Following pages focus on multi-contract examples, exploring the scalable nature of TON Blockchain:
62 |
63 |
64 | }
66 | title="Multi-contract communication"
67 | href="/cookbook/multi-communication"
68 | />
69 | }
71 | title="Fungible Tokens (Jettons)"
72 | href="/cookbook/jettons"
73 | />
74 | }
76 | title="Non-Fungible Tokens (NFTs)"
77 | href="/cookbook/nfts"
78 | />
79 |
80 |
81 | Additionally, there are examples of working with popular TON DEXes (Decentralized EXchanges), which often require many contracts and complex logic:
82 |
83 |
84 |
89 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/pages/cookbook/misc.mdx:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 |
3 | import { Callout } from 'nextra/components'
4 |
5 | Various niche examples which don't yet have a dedicated page, but are useful and interesting nonetheless.
6 |
7 | ## How to throw errors
8 |
9 | The `throw(){:tact}` function in a contract is useful when we don't know how often to perform a specific action.
10 |
11 | It allows intentional exception or error handling, which leads to the termination of the current transaction and reverts any state changes made during that transaction.
12 |
13 | ```tact
14 | let number: Int = 198;
15 |
16 | // the error will be triggered anyway
17 | throw(36);
18 |
19 | // the error will be triggered only if the number is greater than 50
20 | nativeThrowIf(35, number > 50);
21 |
22 | // the error will be triggered only if the number is NOT EQUAL to 198
23 | nativeThrowUnless(39, number == 198);
24 | ```
25 |
26 |
27 |
28 | **Useful links:**\
29 | [`throw(){:tact}` in Core library](/ref/core-debug#throw)\
30 | [Errors in Tact-By-Example](https://tact-by-example.org/03-errors)
31 |
32 |
33 |
34 |
35 |
36 | Didn't find your favorite example of working with something niche? Have cool implementations in mind? [Contributions are welcome!](https://github.com/tact-lang/tact-docs/issues)
37 |
38 |
39 |
--------------------------------------------------------------------------------
/pages/cookbook/multi-communication.mdx:
--------------------------------------------------------------------------------
1 | # Multi-contract communication
2 |
3 | import { Callout } from 'nextra/components'
4 |
5 |
6 |
7 | This page is a stub. [Contributions are welcome!](https://github.com/tact-lang/tact-docs/issues)
8 |
9 |
10 |
--------------------------------------------------------------------------------
/pages/cookbook/nfts.mdx:
--------------------------------------------------------------------------------
1 | # Non-Fungible Tokens (NFTs)
2 |
3 | import { Callout } from 'nextra/components'
4 |
5 |
6 |
7 | This page is a stub. [Contributions are welcome!](https://github.com/tact-lang/tact-docs/issues)
8 |
9 |
10 |
--------------------------------------------------------------------------------
/pages/cookbook/random.mdx:
--------------------------------------------------------------------------------
1 | # Randomness
2 |
3 | import { Callout } from 'nextra/components'
4 |
5 | This page lists examples of working with random numbers, uncertainty and randomness in general.
6 |
7 | ## How to generate a random number
8 |
9 | ```tact
10 | // Declare a variable to store the random number
11 | let number: Int;
12 |
13 | // Generate a new random number, which is an unsigned 256-bit integer
14 | number = randomInt();
15 |
16 | // Generate a random number between 1 and 12
17 | number = random(1, 12);
18 | ```
19 |
20 |
21 |
22 | **Useful links:**\
23 | [`randomInt(){:tact}` in Core library](/ref/core-random#randomInt)\
24 | [`random(){:tact}` in Core library](/ref/core-random#random)
25 |
26 |
27 |
28 |
29 |
30 | Didn't find your favorite example of working with randomness? Have cool implementations in mind? [Contributions are welcome!](https://github.com/tact-lang/tact-docs/issues)
31 |
32 |
33 |
--------------------------------------------------------------------------------
/pages/cookbook/single-communication.mdx:
--------------------------------------------------------------------------------
1 | # Single-contract Communication
2 |
3 | import { Callout } from 'nextra/components'
4 |
5 | This page lists examples of communication of a single deployed contract with other contracts on blockchain.
6 |
7 | For examples of communication between multiple deployed contracts see: [Multi-contract communication](/cookbook/multi-communication).
8 |
9 | ## How to make a basic reply
10 |
11 | ```tact
12 | receive() {
13 | self.reply("Hello, World!".asComment()); // asComment converts a String to a Cell with a comment
14 | }
15 | ```
16 |
17 | ## How to send a simple message
18 |
19 | ```tact
20 | send(SendParameters{
21 | bounce: true, // default
22 | to: destinationAddress,
23 | value: ton("0.01"), // attached amount of Tons to send
24 | body: "Hello from Tact!".asComment(), // comment (optional)
25 | });
26 | ```
27 |
28 | ## How to send a message with the entire balance
29 |
30 | If we need to send the whole balance of the smart contract, then we should use the `SendRemainingBalance{:tact}` send mode. Alternatively, we can use `mode: 128{:tact}`, which has the same meaning.
31 |
32 | ```tact
33 | send(SendParameters{
34 | // bounce = true by default
35 | to: sender(), // send the message back to the original sender
36 | value: 0,
37 | mode: SendRemainingBalance, // or mode: 128
38 | body: "Hello from Tact!".asComment(), // comment (optional)
39 | });
40 | ```
41 |
42 | ## How to send a message with the remaining value
43 |
44 | If we want to make a reply to the same sender, we can use the mode `SendRemainingValue{:tact}` (i.e. `mode: 64{:tact}`), which carries all the remaining value of the inbound message in addition to the value initially indicated in the new message.
45 |
46 | ```tact
47 | send(SendParameters{
48 | // bounce = true by default
49 | to: sender(), // send the message back to the original sender
50 | value: 0,
51 | mode: SendRemainingValue,
52 | body: "Hello from Tact!".asComment(), // comment (optional)
53 | });
54 | ```
55 |
56 | It's often useful to add the `SendIgnoreErrors{:tact}` flag too, in order to ignore any errors arising while processing this message during the action phaseL
57 |
58 | ```tact
59 | send(SendParameters{
60 | // bounce = true by default
61 | to: sender(), // send the message back to the original sender
62 | value: 0,
63 | mode: SendRemainingValue | SendIgnoreErrors, // prefer using | over + for the mode
64 | body: "Hello from Tact!".asComment(), // comment (optional)
65 | });
66 | ```
67 |
68 | The latter example is identical to using a [`.reply(){:tact}` function](#how-to-make-a-basic-reply).
69 |
70 | ## How to send a message with a long text comment
71 |
72 | If we need to send a message with a lengthy text comment, we should create a [`String{:tact}`](/book/types#primitive-types) that consists of more than $127$ characters. To do this, we can utilize the [`StringBuilder{:tact}`](/book/types#primitive-types) primitive type and its methods called `beginComment(){:tact}` and `append(){:tact}`. Prior to sending, we should convert this string into a cell using the `toCell(){:tact}` method.
73 |
74 | ```tact
75 | let comment: StringBuilder = beginComment();
76 | let longString = "..."; // Some string with more than 127 characters.
77 | comment.append(longString);
78 |
79 | send(SendParameters{
80 | // bounce = true by default
81 | to: sender(),
82 | value: 0,
83 | mode: SendIgnoreErrors,
84 | body: comment.toCell(),
85 | });
86 | ```
87 |
88 |
89 |
90 | **Useful links:**\
91 | ["Sending messages" in the Book](/book/send#send-message)\
92 | ["Message `mode`" in the Book](/book/message-mode)\
93 | [`StringBuilder{:tact}` in the Book](/book/types#primitive-types)\
94 | [`Cell{:tact}` in Core library](/ref/core-cells)
95 |
96 |
97 |
98 |
99 |
100 | Didn't find your favorite example of a single-contract communication? Have cool implementations in mind? [Contributions are welcome!](https://github.com/tact-lang/tact-docs/issues)
101 |
102 |
103 |
--------------------------------------------------------------------------------
/pages/cookbook/time.mdx:
--------------------------------------------------------------------------------
1 | # Time and date
2 |
3 | import { Callout } from 'nextra/components'
4 |
5 | ## How to get the current time
6 |
7 | Use the `now(){:tact}` method to obtain the current standard [Unix time](https://en.wikipedia.org/wiki/Unix_time).
8 |
9 | If you need to store the time in state or encode it in a message, use the following [serialization](/book/integers#serialization): `Int as uint32{:tact}`.
10 |
11 | ```tact
12 | let currentTime: Int = now();
13 |
14 | if (currentTime > 1672080143) {
15 | // do something
16 | }
17 | ```
18 |
19 |
20 |
21 | **Useful links:**\
22 | [`now(){:tact}` in Core library](/ref/core-common#now)\
23 | ["Current Time" in Tact-By-Example](https://tact-by-example.org/04-current-time)
24 |
25 |
26 |
27 |
28 |
29 | Didn't find your favorite example of working with time and date? Have cool implementations in mind? [Contributions are welcome!](https://github.com/tact-lang/tact-docs/issues)
30 |
31 |
32 |
--------------------------------------------------------------------------------
/pages/cookbook/type-conversion.mdx:
--------------------------------------------------------------------------------
1 | # Type conversion
2 |
3 | import { Callout, Steps } from 'nextra/components'
4 |
5 | This page shows examples of converting between [primitive types][p] and obtaining them from [composite types](/book/types#composite-types).
6 |
7 | ## `Int` ↔ `String` [#int-string]
8 |
9 | ### How to convert a `String` to an `Int`
10 |
11 | ```tact
12 | // Defining a new extension function for type String that returns value of type Int
13 | // Caution: produces unexpected results when String contains non-numeric characters!
14 | extends fun toInt(self: String): Int {
15 | // Cast the String as a Slice for parsing
16 | let string: Slice = self.asSlice();
17 |
18 | // A variable to store the accumulated number
19 | let acc: Int = 0;
20 |
21 | // Loop until the String is empty
22 | while (!string.empty()) {
23 | let char: Int = string.loadUint(8); // load 8 bits (1 byte) from the Slice
24 | acc = (acc * 10) + (char - 48); // using ASCII table to get numeric value
25 | // Note, that this approach would produce unexpected results
26 | // when the starting String contains non-numeric characters!
27 | }
28 |
29 | // Produce the resulting number
30 | return acc;
31 | }
32 |
33 | fun runMe() {
34 | let string: String = "26052021";
35 | dump(string.toInt());
36 | }
37 | ```
38 |
39 | ### How to convert an `Int` to a `String`
40 |
41 | ```tact
42 | let number: Int = 261119911;
43 |
44 | // Converting the [number] to a String
45 | let numberString: String = number.toString();
46 |
47 | // Converting the [number] to a float String,
48 | // where passed argument 3 is the exponent of 10^(-3) of resulting float String,
49 | // and it can be any integer between 0 and 76 including both ends
50 | let floatString: String = number.toFloatString(3);
51 |
52 | // Converting the [number] as coins to a human-readable String
53 | let coinsString: String = number.toCoinsString();
54 |
55 | dump(numberString); // "261119911"
56 | dump(floatString); // "261119.911"
57 | dump(coinsString); // "0.261119911"
58 | ```
59 |
60 |
61 |
62 | **Useful links:**\
63 | [`Int.toString(){:tact}` in Core library](/ref/core-strings#inttostring)\
64 | [`Int.toFloatString(){:tact}` in Core library](/ref/core-strings#inttofloatstring)\
65 | [`Int.toCoinsString(){:tact}` in Core library](/ref/core-strings#inttocoinsstring)
66 |
67 |
68 |
69 | ## `Struct` or `Message` ↔ `Cell` or `Slice` [#structmessage-cellslice]
70 |
71 | ### How to convert an arbitrary `Struct` or `Message` to a `Cell` or a `Slice`
72 |
73 | ```tact {19-20, 22-23}
74 | struct Profit {
75 | big: String?;
76 | dict: map;
77 | energy: Int;
78 | }
79 |
80 | message(0x45) Nice {
81 | maybeStr: String?;
82 | }
83 |
84 | fun convert() {
85 | let st = Profit{
86 | big: null,
87 | dict: null,
88 | energy: 42,
89 | };
90 | let msg = Nice{ maybeStr: "Message of the day!" };
91 |
92 | st.toCell();
93 | msg.toCell();
94 |
95 | st.toCell().asSlice();
96 | msg.toCell().asSlice();
97 | }
98 | ```
99 |
100 |
101 |
102 | **Useful links:**\
103 | [`Struct.toCell(){:tact}` in Core library](/ref/core-cells#structtocell)\
104 | [`Message.toCell(){:tact}` in Core library](/ref/core-cells#messagetocell)
105 |
106 |
107 |
108 | ### How to convert a `Cell` or a `Slice` to an arbitrary `Struct` or `Message`
109 |
110 | ```tact {19-20, 22-23}
111 | struct Profit {
112 | big: String?;
113 | dict: map;
114 | energy: Int;
115 | }
116 |
117 | message(0x45) Nice {
118 | maybeStr: String?;
119 | }
120 |
121 | fun convert() {
122 | let stCell = Profit{
123 | big: null,
124 | dict: null,
125 | energy: 42,
126 | }.toCell();
127 | let msgCell = Nice{ maybeStr: "Message of the day!" }.toCell();
128 |
129 | Profit.fromCell(stCell);
130 | Nice.fromCell(msgCell);
131 |
132 | Profit.fromSlice(stCell.asSlice());
133 | Nice.fromSlice(msgCell.asSlice());
134 | }
135 | ```
136 |
137 |
138 |
139 | **Useful links:**\
140 | [`Struct.fromCell(){:tact}` in Core library](/ref/core-cells#structfromcell)\
141 | [`Struct.fromSlice(){:tact}` in Core library](/ref/core-cells#structfromslice)\
142 | [`Message.fromCell(){:tact}` in Core library](/ref/core-cells#messagefromcell)\
143 | [`Message.fromSlice(){:tact}` in Core library](/ref/core-cells#messagefromslice)
144 |
145 |
146 |
147 |
148 |
149 | Didn't find your favorite example of type conversion? Have cool implementations in mind? [Contributions are welcome!](https://github.com/tact-lang/tact-docs/issues)
150 |
151 |
152 |
153 | [p]: /book/types#primitive-types
154 |
--------------------------------------------------------------------------------
/pages/ecosystem/_meta.js:
--------------------------------------------------------------------------------
1 | export default {
2 | index: 'Overview',
3 | tools: 'Tools',
4 | '-- Community': {
5 | type: 'separator',
6 | },
7 | 'telegram-link': {
8 | title: '✈️ Telegram',
9 | href: 'https://t.me/tactlang',
10 | newWindow: true
11 | },
12 | 'xtwitter-link': {
13 | title: '🐦 X/Twitter',
14 | href: 'https://twitter.com/tact_language',
15 | newWindow: true
16 | },
17 | }
18 |
--------------------------------------------------------------------------------
/pages/ecosystem/index.mdx:
--------------------------------------------------------------------------------
1 | # Ecosystem overview
2 |
3 | import { Cards, Steps } from 'nextra/components'
4 |
5 | Welcome to the **Ecosystem** section — a bird-eye overview of Tact ecosystem, tools and ways you can start contributing to those!
6 |
7 | Here are its main contents:
8 |
9 |
10 |
11 | ### Tools
12 |
13 | [Tools](/ecosystem/tools/overview) sub-section is a list of official and community-made tools made specifically for Tact, or whose that play along with the language and other tools. Each tool has a brief usage details and additional information, which sometimes is missing from the respective docs or is a convenient summary available only in the Tact documentation.
14 |
15 |
16 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/pages/ecosystem/tools/_meta.js:
--------------------------------------------------------------------------------
1 | export default {
2 | overview: 'Overview',
3 | typescript: 'Typescript',
4 | vscode: 'VS Code Extension',
5 | jetbrains: 'JetBrains IDEs Plugin'
6 | }
--------------------------------------------------------------------------------
/pages/ecosystem/tools/jetbrains.mdx:
--------------------------------------------------------------------------------
1 | # TON Development Plugin for JetBrains IDEs
2 |
3 | Supports highlighting Tact's syntax in JetBrains IDEs versioned **2023.** and later. Note, that besides support for Tact, it also includes a rich support of FunC and Fift languages of TON Blockchain, as well as TL-B schemas.
4 |
5 | Plugin on the JetBrains Marketplace: [TON Development Plugin](https://plugins.jetbrains.com/plugin/23382-ton)
6 |
7 | ## Installation manual
8 |
9 | 1. Open your JetBrains IDE (IntelliJ IDEA, PyCharm, WebStorm, etc.)
10 | 2. Navigate to the **Plugin Marketplace** by selecting `File > Settings/Preferences > Plugins`
11 | 3. In the Plugin Marketplace's search bar, type "TON Development". You will see a dropdown with the extension provided by `TON Foundation`.
12 | 4. Click the **Install** button next to the plugin name. Wait for the installation to complete.
13 | 5. Once the plugin is installed, you will be prompted to restart your JetBrains IDE. Click the **Restart** button to apply changes.
14 | 6. After restarting, the TON Development plugin should now be successfully installed in your JetBrains IDE.
15 |
16 | ## Troubleshooting
17 |
18 | If you encounter issues during the installation process, please consult the [plugin's GitHub repository](https://github.com/ton-blockchain/intellij-ton) for solutions and further information.
19 |
20 | ## References and Resources
21 |
22 | - [Plugin on GitHub](https://github.com/ton-blockchain/intellij-ton)
23 | - [Plugin on the JetBrains Marketplace](https://plugins.jetbrains.com/plugin/23382-ton)
--------------------------------------------------------------------------------
/pages/ecosystem/tools/misti.mdx:
--------------------------------------------------------------------------------
1 | # Misti
2 |
3 | [Misti](https://nowarp.github.io/tools/misti/) is a static program analysis tool that supports Tact.
4 |
5 | ## What is Misti?
6 |
7 | * **Static Program Analysis**: Misti analyzes code without executing it, scanning for [bugs and security flaws](https://nowarp.github.io/tools/misti/docs/detectors) by examining the structure and syntax. This approach catches issues early, preventing them from reaching production.
8 | * **Custom Detectors**: Customize Misti to your specific needs by creating [custom detectors](https://nowarp.github.io/tools/misti/docs/hacking/custom-detector). This helps identify vulnerabilities that generic tools might miss, ensuring a thorough review of your code.
9 | * **CI/CD Integration**: [Integrate](https://nowarp.github.io/tools/misti/docs/tutorial/ci-cd) Misti into your CI/CD pipeline to ensure continuous code quality checks, catching issues before they make it to production.
10 |
11 | ## Resources
12 |
13 | * [Github](https://github.com/nowarp/misti)
14 | * [Telegram Community](https://t.me/misti_dev)
15 | * [Misti Documentation](https://nowarp.github.io/docs/misti/)
16 | * [Misti API Reference](https://nowarp.github.io/docs/misti/api)
17 |
--------------------------------------------------------------------------------
/pages/ecosystem/tools/overview.mdx:
--------------------------------------------------------------------------------
1 | # Tools Overview
2 |
3 | import { Cards } from 'nextra/components'
4 |
5 | This sub-section contains a list of official and community-made tools made specifically for Tact, or whose that play along with the language and other tools. Each tool has a brief usage details and additional information, which sometimes is missing from the respective docs or is a convenient summary available only in the Tact documentation.
6 |
7 |
8 |
13 |
18 |
23 |
28 |
29 |
--------------------------------------------------------------------------------
/pages/ecosystem/tools/typescript.mdx:
--------------------------------------------------------------------------------
1 | # TypeScript Libraries
2 |
3 | The Tact language has built-in support for the [@ton/ton](https://github.com/ton-org/ton) and [@ton/core](https://github.com/ton-org/ton-core) TypeScript libraries. The compiler automatically generates code for these libraries, so you can use [@tact-lang/emulator](https://github.com/tact-lang/tact-emulator) or [@ton/sandbox](https://github.com/ton-org/sandbox), that work on top of them.
4 |
5 | ## Tact contract in TypeScript
6 |
7 | The compiler generates files named `{project}_{contract}.ts` for each contract in your [project](/book/config#projects), which contain ready-to-use strongly typed wrappers for working with it in any TypeScript-powered environment: for [testing](/book/debug), [deployments](/book/deploy), etc.
8 |
--------------------------------------------------------------------------------
/pages/ecosystem/tools/vscode.mdx:
--------------------------------------------------------------------------------
1 | # VS Code Extension
2 |
3 | Provides extensive support for Tact language in the Visual Studio Code:
4 |
5 | * Syntax highlighting
6 | * Error highlighting
7 | * Snippets
8 | * Information on hover
9 | * Code completion for all variables, functions, global parameters and unique types of Tact
10 | * Code completion for all contracts / libraries in the current file and all referenced imports
11 | * Formatting
12 |
13 | Extension on the VS Code Marketplace: [Tact Language Support for TON blockchain](https://marketplace.visualstudio.com/items?itemName=KonVik.tact-lang-vscode)
14 |
15 | ## Installation manual
16 |
17 | 1. Open Visual Studio Code (shortly referred to as VS Code).
18 | 2. Navigate to the Extensions view by clicking on the Extensions icon in the Activity Bar on the side of the window. It looks like a square within a square.
19 | 3. In the Extensions view input box, type "Tact Language". You should see a dropdown with the extension "Tact Language" provided by KonVik. Probably, you would see the similar extension provided by TON Community, but that one is deprecated and **we should use KonVik's one instead**.
20 | 4. Click on the install button next to the extension name. Wait until the installation is complete.
21 | 5. Once the extension is installed, you might need to reload VS Code. If necessary, there will be a Reload button next to the extension. Click on this button if it appears.
22 | 6. The Tact Language extension should now be installed on your VS Code.
23 |
24 | ## Enabling `Format on Save` [#format-on-save]
25 |
26 | This guide will provide instructions on how to enable the Format on Save feature for the Tact Language extension in VS Code using the Command Palette and editing the JSON settings file.
27 |
28 | 1. Type `Preferences: Open Settings (JSON)` in the command palette. This will open your `settings.json` file.
29 | 2. Editing JSON Settings
30 |
31 | - You'll see a JSON object. We're going to add some properties to this object to enable format on save for the Tact Language extension.
32 | - Add the following lines inside the JSON object:
33 |
34 | ```json
35 | {
36 | "[tact]": {
37 | "editor.formatOnSave": true,
38 | "editor.defaultFormatter": "KonVik.tact-lang-vscode"
39 | }
40 | }
41 | ```
42 |
43 | - This will enable format on save (`"editor.formatOnSave": true`) and set the default formatter for Tact files (`"[tact]": {"editor.defaultFormatter": "KonVik.tact-lang-vscode"}`) to the Tact Language extension.
44 |
45 | 3. Saving and Closing Settings
46 | - Save your `settings.json` file after adding these lines (You can press `Ctrl+S` to save).
47 | - Close the `settings.json` tab or press `Ctrl+W`.
48 |
49 | Your Tact Language VS Code extension should now automatically format your files when you save them. If you don't see these changes take effect immediately, you might need to reload VS Code.
50 |
51 | ## References and Resources
52 |
53 | - [Extension on GitHub](https://github.com/tact-lang/tact-vscode)
54 | - [Extension on the VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=KonVik.tact-lang-vscode)
--------------------------------------------------------------------------------
/pages/index.mdx:
--------------------------------------------------------------------------------
1 | # Learn all about programming in ⚡ Tact
2 |
3 | import { Cards, Steps, Tabs } from 'nextra/components'
4 |
5 | 
6 |
7 | Tact is a new programming language for TON Blockchain that is focused on efficiency and simplicity. It is designed to be easy to learn and use, and to be a good fit for smart contracts. Tact is a statically typed language with a simple syntax and a powerful type system.
8 |
9 | ## Let's start! [#start]
10 |
11 |
12 |
13 | ### Ensure that the supported version of Node.js is installed and available [#start-1]
14 |
15 | To check it, run `node --version{:shell}` — it should show you the version 22.0.0 or later.
16 |
17 | ### Run the following command [#start-2]
18 |
19 | It will create a new project with the simple counter contract:
20 |
21 |
22 |
23 | ```shell
24 | npm create ton@latest -- simple-counter --type tact-counter --contractName SimpleCounter
25 | ```
26 |
27 |
28 | ```shell
29 | # recommended
30 | yarn create ton simple-counter --type tact-counter --contractName SimpleCounter
31 | ```
32 |
33 |
34 | ```shell
35 | pnpm create ton@latest simple-counter --type tact-counter --contractName SimpleCounter
36 | ```
37 |
38 |
39 | ```shell
40 | bun create ton@latest simple-counter --type tact-counter --contractName SimpleCounter
41 | ```
42 |
43 |
44 |
45 | ### That's it! [#start-3]
46 |
47 | Your first contract project is written and compiled already! Go check it out by moving into the relevant directory — `cd simple-counter/contracts{:shell}`.
48 |
49 | Here's how it would look like:
50 |
51 | ```tact
52 | import "@stdlib/deploy";
53 |
54 | message Add {
55 | queryId: Int as uint64;
56 | amount: Int as uint32;
57 | }
58 |
59 | contract SimpleCounter with Deployable {
60 | id: Int as uint32;
61 | counter: Int as uint32;
62 |
63 | init(id: Int) {
64 | self.id = id;
65 | self.counter = 0;
66 | }
67 |
68 | receive(msg: Add) {
69 | self.counter += msg.amount;
70 |
71 | // Notify the caller that the receiver was executed and forward remaining value back
72 | self.notify("Cashback".asComment());
73 | }
74 |
75 | get fun counter(): Int {
76 | return self.counter;
77 | }
78 |
79 | get fun id(): Int {
80 | return self.id;
81 | }
82 | }
83 | ```
84 |
85 | To re-compile or deploy, refer to the commands in the scripts section of `package.json` in the root of this newly created project and to the documentation of [Blueprint](https://github.com/ton-org/blueprint) — this is the tool we've used to create and compile your first simple counter contract in Tact. In fact, Blueprint can do much more than that: including tests, customizations and more.
86 |
87 |
88 |
89 | ## Where to go next? [#next]
90 |
91 |
92 |
93 | ### Have some blockchain knowledge already? [#next-1]
94 |
95 | See the [Tact Cookbook](/cookbook), which is a handy collection of everyday tasks (and solutions) every Tact developer faces during smart contract development. Use it to avoid re-inventing the wheel.
96 |
97 | Alternatively, check the following cheatsheets to quickly get started:
98 |
99 |
100 |
105 |
110 |
111 |
112 | ### Want to know more? [#next-2]
113 |
114 | For further guidance on compilation, testing and deployment see the respective pages:
115 |
116 | * [Testing and debugging](/book/debug) page tells you everything about debugging Tact contracts
117 | * [Deployment](/book/deploy) page shows what deployment looks like and helps you harness the powers of [Blueprint](https://github.com/ton-org/blueprint) for it.
118 |
119 | For custom plugins for your favorite editor and other tooling see the [Tools](/ecosystem/tools/overview) page.
120 |
121 | Alternatively, take a look at the following broader sections:
122 | * [Book](/book) helps you learn the language step-by-step
123 | * [Cookbook](/cookbook) gives you ready-made recipes of Tact code
124 | * [Reference](/ref) provides a complete glossary of the standard library, grammar and evolution process
125 | * Finally, [Ecosystem](/ecosystem) describes "what's out there" in the Tacts' and TONs' ecosystems
126 |
127 |
128 |
133 |
138 |
143 |
148 |
149 |
150 | ### Feeling a bit uncomfortable? [#next-3]
151 |
152 | If you ever get stuck, try searching — the search box is right at the top of the documentation. There is also a handy Ctrl + K shortcut to quickly focus and start the search as you type.
153 |
154 | If you can't find the answer in the docs, or you've tried to do some local testing and it still didn't help — don't hesitate to reach out to Tact's flourishing community:
155 |
156 |
157 |
163 |
169 |
170 |
171 | Good luck on your coding adventure with ⚡ Tact!
172 |
173 |
174 |
--------------------------------------------------------------------------------
/pages/ref/_meta.js:
--------------------------------------------------------------------------------
1 | export default {
2 | index: 'Overview',
3 | spec: 'Specification',
4 | evolution: 'Evolution',
5 | '-- Core library': {
6 | type: 'separator',
7 | title: 'Core library',
8 | },
9 | 'core-base': 'Base trait',
10 | 'core-common': 'Common',
11 | 'core-comptime': 'Compile-time',
12 | 'core-debug': 'Debug',
13 | 'core-random': 'Random',
14 | 'core-math': 'Math',
15 | 'core-strings': 'Strings and StringBuilders',
16 | 'core-cells': 'Cells, Builders and Slices',
17 | 'core-advanced': 'Advanced',
18 | '-- Stdlib': {
19 | type: 'separator',
20 | title: 'Standard libraries',
21 | },
22 | 'standard-libraries': 'Overview',
23 | 'stdlib-config': '@stdlib/config',
24 | 'stdlib-content': '@stdlib/content',
25 | 'stdlib-deploy': '@stdlib/deploy',
26 | 'stdlib-dns': '@stdlib/dns',
27 | 'stdlib-ownable': '@stdlib/ownable',
28 | 'stdlib-stoppable': '@stdlib/stoppable',
29 | '-- Community': {
30 | type: 'separator',
31 | },
32 | 'telegram-link': {
33 | title: '✈️ Telegram',
34 | href: 'https://t.me/tactlang',
35 | newWindow: true
36 | },
37 | 'xtwitter-link': {
38 | title: '🐦 X/Twitter',
39 | href: 'https://twitter.com/tact_language',
40 | newWindow: true
41 | },
42 | }
43 |
--------------------------------------------------------------------------------
/pages/ref/core-base.mdx:
--------------------------------------------------------------------------------
1 | # Base trait
2 |
3 | import { Callout } from 'nextra-theme-docs'
4 |
5 | Every [contract](/book/contracts) and [trait](/book/types#traits) in Tact implicitly [inherits](/book/contracts#traits) the `BaseTrait{:tact}` trait, which contains a number of the most useful [internal functions](/book/contracts#internal-functions) for any kind of contract, and a constant `self.storageReserve{:tact}` aimed at advanced users of Tact.
6 |
7 | ## Constants
8 |
9 | ### self.storageReserve [#self-storagereserve]
10 |
11 | ```tact
12 | virtual const storageReserve: Int = 0;
13 | ```
14 |
15 | Usage example:
16 |
17 | ```tact
18 | contract AllYourStorageBelongsToUs {
19 | // This would change the behavior of self.forward() function,
20 | // causing it to try reserving this amount of nanoToncoins before
21 | // forwarding a message with SendRemainingBalance mode
22 | override const storageReserve: Int = ton("0.1");
23 | }
24 | ```
25 |
26 | ## Functions
27 |
28 | ### self.reply [#self-reply]
29 |
30 | ```tact
31 | virtual fun reply(body: Cell?);
32 | ```
33 |
34 | An alias to calling the [`self.forward(){:tact}`](#self-forward) function with the following arguments:
35 |
36 | ```tact
37 | self.forward(sender(), body, true, null);
38 | // ↑ ↑ ↑ ↑
39 | // | | | init: StateInit?
40 | // | | bounce: Bool
41 | // | body: Cell?
42 | // to: Address
43 | ```
44 |
45 | Usage example:
46 |
47 | ```tact
48 | // This message can bounce back to us!
49 | self.reply("Beware, this is my reply to you!".asComment());
50 | ```
51 |
52 | ### self.notify [#self-notify]
53 |
54 | ```tact
55 | virtual fun notify(body: Cell?);
56 | ```
57 |
58 | An alias to calling the [`self.forward(){:tact}`](#self-forward) function with the following arguments:
59 |
60 | ```tact
61 | self.forward(sender(), body, false, null);
62 | // ↑ ↑ ↑ ↑
63 | // | | | init: StateInit?
64 | // | | bounce: Bool
65 | // | body: Cell?
66 | // to: Address
67 | ```
68 |
69 | Usage example:
70 |
71 | ```tact
72 | // This message won't bounce!
73 | self.notify("Beware, this is my reply to you!".asComment());
74 | ```
75 |
76 | ### self.forward [#self-forward]
77 |
78 | ```tact
79 | virtual fun forward(to: Address, body: Cell?, bounce: Bool, init: StateInit?);
80 | ```
81 |
82 | [Queues the message](/book/send#outbound-message-processing) (bounceable or non-bounceable) to be sent to the specified address `to`. Optionally, you may provide a `body` of the message and the [`init` package](/book/expressions#initof).
83 |
84 | When [`self.storageReserve{:tact}`](#self-storagereserve) constant is overwritten to be $> 0$, before sending a message it also tries to reserve the `self.storageReserve{:tact}` amount of [nanoToncoins][nano] from the remaining balance before making the send in the [`SendRemainingBalance{:tact}`](https://docs.tact-lang.org/book/message-mode#base-modes) ($128$) mode.
85 |
86 | In case reservation attempt fails and in the default case without the attempt, the message is sent with the [`SendRemainingValue{:tact}`](https://docs.tact-lang.org/book/message-mode#base-modes) ($64$) mode instead.
87 |
88 |
89 |
90 | Note, that `self.forward(){:tact}` never sends additional [nanoToncoins][nano] on top of what's available on the balance.\
91 | To be able to send more [nanoToncoins][nano] with a single message, use the the [`send(){:tact}`](/ref/core-common#send) function.
92 |
93 |
94 |
95 | Usage example:
96 |
97 | ```tact
98 | import "@stdlib/ownable";
99 |
100 | message PayoutOk {
101 | address: Address;
102 | value: Int as coins;
103 | }
104 |
105 | contract Payout with Ownable {
106 | completed: Bool;
107 | owner: Address;
108 |
109 | init(owner: Address) {
110 | self.owner = owner;
111 | self.completed = false;
112 | }
113 |
114 | // ... some actions there ...
115 |
116 | // Bounced receiver function, which is called when the specified outgoing message bounces back
117 | bounced(msg: bounced) {
118 | // Reset completed flag if our message bounced
119 | self.completed = false;
120 |
121 | // Send a notification that the payout failed using the remaining funds for processing this send
122 | self.forward(self.owner, "Payout failed".asComment(), false, null);
123 | }
124 | }
125 | ```
126 |
127 | [nano]: /book/integers#nanotoncoin
128 |
--------------------------------------------------------------------------------
/pages/ref/core-comptime.mdx:
--------------------------------------------------------------------------------
1 | # Compile-time
2 |
3 | import { Callout } from 'nextra-theme-docs'
4 |
5 | This page lists all the built-in [global static functions](/book/functions#global-static-functions), which are evaluated at the time of building the Tact project and cannot work with non-constant, run-time data. These functions are commonly referred to as "compile-time functions".
6 |
7 | ## address
8 |
9 | ```tact
10 | fun address(s: String): Address;
11 | ```
12 |
13 | A compile-time function that converts a [`String{:tact}`][p] with an address into the [`Address{:tact}`][p] type.
14 |
15 | Usage example:
16 |
17 | ```tact
18 | contract Example {
19 | // Persistent state variables
20 | addr: Address =
21 | address("EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N"); // works at compile-time!
22 | }
23 | ```
24 |
25 | ## cell
26 |
27 | ```tact
28 | fun cell(bocBase64: String): Cell;
29 | ```
30 |
31 | 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.
32 |
33 | Usage example:
34 |
35 | ```tact
36 | contract Example {
37 | // Persistent state variables
38 | storedCell: Cell =
39 | // Init package for Wallet V3R1 as a base64-encoded BoC
40 | cell("te6cckEBAQEAYgAAwP8AIN0gggFMl7qXMO1E0NcLH+Ck8mCDCNcYINMf0x/TH/gjE7vyY+1E0NMf0x/T/9FRMrryoVFEuvKiBPkBVBBV+RDyo/gAkyDXSpbTB9QC+wDo0QGkyMsfyx/L/8ntVD++buA="); // works at compile-time!
41 | }
42 | ```
43 |
44 |
45 |
46 | **Useful links:**\
47 | [Bag of Cells in TON Docs](https://docs.ton.org/develop/data-formats/cell-boc#bag-of-cells)
48 |
49 |
50 |
51 | ## ton
52 |
53 | ```tact
54 | fun ton(value: String): Int;
55 | ```
56 |
57 | A compile-time function that converts the given Toncoins `value` from a human-readable format [`String{:tact}`][p] to the [nanoToncoin](/book/integers#nanotoncoin) [`Int{:tact}`][int] format.
58 |
59 | Usage example:
60 |
61 | ```tact
62 | contract Example {
63 | // Persistent state variables
64 | one: Int = ton("1"); // 10^9 nanoToncoins, which is equal to one Toncoin
65 | pointOne: Int = ton("0.1"); // 10^8 nanoToncoins, which is equal to 0.1 Toncoin
66 | nano: Int = ton("0.000000001"); // 1 nanoToncoin, which is equal to 10^-9 Toncoins
67 | // works at compile-time!
68 | }
69 | ```
70 |
71 | [p]: /book/types#primitive-types
72 | [bool]: /book/types#booleans
73 | [int]: /book/integers
74 | [cell]: /book/cells#cells
75 |
--------------------------------------------------------------------------------
/pages/ref/core-debug.mdx:
--------------------------------------------------------------------------------
1 | # Debug
2 |
3 | import { Callout } from 'nextra-theme-docs'
4 |
5 | List of functions commonly used for debugging smart contracts in Tact.
6 |
7 |
8 |
9 | Read more about debugging on the dedicated page: [Debugging](/book/debug).
10 |
11 |
12 |
13 | ## require
14 |
15 | ```tact
16 | fun require(condition: Bool, error: String);
17 | ```
18 |
19 | Checks the `condition` and throws an error with an [exit code](/book/exit-codes) generated from the `error` message if the `condition` is `false{:tact}`. Does nothing otherwise.
20 |
21 | The algorithm for generating the exit code works as follows:
22 |
23 | * First, the [SHA-256](https://en.wikipedia.org/wiki/SHA-2#Hash_standard) hash of `error` message [`String{:tact}`][p] is obtained.
24 | * Then, its value is read as a 32-bit [big-endian](https://en.wikipedia.org/wiki/Endianness) number modulo $63000$ plus $1000$, in that order.
25 | * Finally, it's put into the `.md` compilation report file, which resides with the other compilation artifacts in your project's `outputs/` or `build/` directories.
26 |
27 | The generated exit code is guaranteed to be outside the common $0 - 255$ range reserved for TVM and Tact contract errors, which makes it possible to distinguish exit codes from `require(){:tact}` and any other [standard exit codes](/book/exit-codes).
28 |
29 | Usage examples:
30 |
31 | ```tact
32 | // now() has to return a value greater than 1000, otherwise an error message will be thrown
33 | require(now() > 1000, "We're in the first 1000 seconds of 1 January 1970!");
34 |
35 | try {
36 | // The following will never be true, so this require would always throw
37 | require(now() < -1, "Time is an illusion. Lunchtime doubly so.");
38 | } catch (e) {
39 | // e will be outside of range 0-255
40 | dump(e);
41 | }
42 | ```
43 |
44 | ## dump
45 |
46 | ```tact
47 | fun dump(arg);
48 | ```
49 |
50 | Prints the argument `arg` to the contract's debug console. Evaluated only if the `debug` option in the [configuration file](/book/config) is set to `true{:json}`, otherwise does nothing.
51 |
52 | Can be applied to the following list of types and values:
53 |
54 | * [`Int{:tact}`][int]
55 | * [`Bool{:tact}`][bool]
56 | * [`Address{:tact}`][p]
57 | * [`Cell{:tact}`][cell], [`Builder{:tact}`][builder] or [`Slice{:tact}`][slice]
58 | * [`String{:tact}`][p] or [`StringBuilder{:tact}`][p]
59 | * [`map{:tact}`](/book/maps)
60 | * [Optionals and `null{:tact}` value](/book/optionals)
61 | * `void`, which is implicitly returned when a function doesn't have return value defined
62 |
63 | Usage examples:
64 |
65 | ```tact
66 | // Int
67 | dump(42);
68 |
69 | // Bool
70 | dump(true);
71 | dump(false);
72 |
73 | // Address
74 | dump(myAddress());
75 |
76 | // Cell, Builder or Slice
77 | dump(emptyCell()); // Cell
78 | dump(beginCell()); // Builder
79 | dump(emptySlice()); // Slice
80 |
81 | // String or StringBuilder
82 | dump("Hello, my name is..."); // String
83 | dump(beginTailString()); // StringBuilder
84 |
85 | // Maps
86 | let m: map = emptyMap();
87 | m.set(2 + 2, 4);
88 | dump(m);
89 |
90 | // Special values
91 | dump(null);
92 | dump(emit("msg".asComment())); // As emit() function doesn't return a value, dump() would print #DEBUG#: void.
93 | ```
94 |
95 | ## dumpStack
96 |
97 | ```tact
98 | fun dumpStack();
99 | ```
100 |
101 | Prints all the values of [persistent state variables](/book/contracts#variables) to the contract's debug console. Evaluated only if `debug` option is set in the [configuration file](/book/config), otherwise does nothing.
102 |
103 | Usage example:
104 |
105 | ```tact {6}
106 | contract DumpsterFire {
107 | var1: Int = 0;
108 | var2: Int = 5;
109 |
110 | receive() {
111 | dumpStack(); // would print 0 5
112 | }
113 | }
114 | ```
115 |
116 | ## throw
117 |
118 | ```tact
119 | fun throw(code: Int);
120 | ```
121 |
122 | An alias to [`nativeThrow(){:tact}`](#nativethrow).
123 |
124 | ## nativeThrow
125 |
126 | ```tact
127 | fun nativeThrow(code: Int);
128 | ````
129 |
130 | Throws an exception with an error code equal to `code`. Execution of the current context stops (the statements after `nativeThrow` won't be executed) and control will be passed to the first [`try...catch{:tact}` block](/book/statements#try-catch) in the call stack. If no `try{:tact}` or `try...catch{:tact}` block exists among caller functions, [TVM](https://docs.ton.org/learn/tvm-instructions/tvm-overview) will terminate the transaction.
131 |
132 | Usage examples:
133 |
134 | ```tact {2,7}
135 | fun thisWillTerminate() {
136 | nativeThrow(42); // throwing with exit code 42
137 | }
138 |
139 | fun butThisDoesNot() {
140 | try {
141 | nativeThrow(42); // throwing with exit code 42
142 | }
143 |
144 | // ... follow-up logic ...
145 | }
146 | ```
147 |
148 | ## nativeThrowIf
149 |
150 | ```tact
151 | fun nativeThrowIf(code: Int, condition: Bool);
152 | ```
153 |
154 | Similar to [`nativeThrow(){:tact}`](#nativethrow), but throws an exception conditionally, when `condition` is equal to `true{:tact}`. Doesn't throw otherwise.
155 |
156 | Usage examples:
157 |
158 | ```tact {2,7}
159 | fun thisWillTerminate() {
160 | nativeThrowIf(42, true); // throwing with exit code 42
161 | }
162 |
163 | fun butThisDoesNot() {
164 | try {
165 | nativeThrowIf(42, true); // throwing with exit code 42
166 | }
167 | // ... follow-up logic ...
168 | }
169 | ```
170 |
171 | ## nativeThrowUnless
172 |
173 | ```tact
174 | fun nativeThrowUnless(code: Int, condition: Bool);
175 | ```
176 |
177 | Similar to [`nativeThrow(){:tact}`](#nativethrow), but throws an exception conditionally, when `condition` is equal to `false{:tact}`. Doesn't throw otherwise.
178 |
179 | Usage examples:
180 |
181 | ```tact {2,7}
182 | fun thisWillTerminate() {
183 | nativeThrowUnless(42, false); // throwing with exit code 42
184 | }
185 |
186 | fun butThisDoesNot() {
187 | try {
188 | nativeThrowUnless(42, false); // throwing with exit code 42
189 | }
190 | // ... follow-up logic ...
191 | }
192 | ```
193 |
194 | [p]: /book/types#primitive-types
195 | [bool]: /book/types#booleans
196 | [int]: /book/integers
197 | [cell]: /book/cells#cells
198 | [builder]: /book/cells#builders
199 | [slice]: /book/cells#slices
200 |
--------------------------------------------------------------------------------
/pages/ref/core-random.mdx:
--------------------------------------------------------------------------------
1 | # Random number generation
2 |
3 | import { Callout } from 'nextra-theme-docs'
4 |
5 | Random number generation for Tact smart contracts.
6 |
7 | ## random
8 |
9 | ```tact
10 | fun random(min: Int, max: Int): Int;
11 | ```
12 |
13 | Generates and returns a new pseudo-random unsigned [`Int{:tact}`][int] value `x` in the provided semi-closed interval: `min` $≤$ `x` $<$ `max` or `min` $≥$ `x` $>$ `max`, if both `min` and `max` are negative. Note, that `max` value is never included in the interval.
14 |
15 | Usage examples:
16 |
17 | ```tact
18 | random(42, 43); // 42, always
19 | random(0, 42); // 0-41, but never a 42
20 | ```
21 |
22 | ## randomInt
23 |
24 | ```tact
25 | fun randomInt(): Int;
26 | ```
27 |
28 | Generates and returns a new pseudo-random unsigned $256$-bit [`Int{:tact}`][int] value `x`.
29 |
30 | The algorithm works as follows: if `r` is the old value of the random seed considered a $32$-byte array (by constructing the big-endian representation of an unsigned $256$-bit [`Int{:tact}`][int]), then its `sha512(r){:tact}` is computed. The first $32$ bytes of this hash are stored as the new value `r'` of the random seed, and the remaining $32$ bytes are returned as the next random value `x`.
31 |
32 | Usage example:
33 |
34 | ```tact
35 | let allYourRandomBelongsToUs: Int = randomInt(); // ???, it's random :)
36 | ```
37 |
38 |
39 |
40 | Advanced functions for working with random numbers are listed on a specialized page: [Advanced APIs](/ref/core-advanced).
41 |
42 |
43 |
44 | [int]: /book/integers
45 |
--------------------------------------------------------------------------------
/pages/ref/evolution/OTP-001.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "OTP-001: Supported Interfaces"
3 | ---
4 |
5 | # OTP-001: Supported Interfaces
6 |
7 | This proposal recommends a way to introspect smart contracts and find out what interfaces they support.
8 |
9 | ## Motivation
10 |
11 | Right now it is impossible to guess what a user wants to do with a contract or can't figure out what the transaction is about because there is no clear way to find what a contract is about. Humans need to remember or guess what this was about in most ways.
12 |
13 | ## Guide
14 |
15 | When human tries to sign a transaction, they need to understand clearly what they are doing: minting, token transfer, staking, DAO voting. While Ethereum wallets support signing arbitrary structures it is still not clear what are you signing and what's the implications of doing so. In the same way, explorers can't show what's going on in a nice form.
16 |
17 | The start of a working with specific contract is a performing introspection - figuring out what the contract declares about itself. When the app knows what this contract is about it could build a good UI, show transaction history, and verify what a human tries to sign.
18 |
19 | This proposal describes a way to report what interfaces the contract supports.
20 |
21 | Interfaces are defined in a free-form specification. Unlike most of the other approaches, this proposal defines interface as not only the technical interface of a contract (get methods, internal messages, etc) but also a description of its behavior. Attaching a hash of the representation of a technical interface of a contract could cause conflicts between different standards and because of this proposal defines interfaces loosely. Also, it allows an interface to be more fluid, for example token that couldn't be transferred could be just a contract that will have to get the method `can_transfer` that returns `false` and this would mean that this token doesn't support transfers at all without the need to implement this method.
22 |
23 | Interface IDs are hashes of reverse domain names (like packages in Java), this avoids clashes of names between different teams if they want to build something just for themselves.
24 |
25 | ## Specification
26 |
27 | In order to support the introspection contract MUST implement the supports_interface GET method:
28 |
29 | ```(int...) supported_interfaces()```
30 | Which returns a list of supported interface codes. The first value MUST be `hash("org.ton.introspection.v0")` = `123515602279859691144772641439386770278`.
31 | If the first value is incorrect app MUST stop attempting to introspect the contract.
32 | Example
33 | ```func
34 | _ supported_interfaces() method_id {
35 | return (123515602279859691144772641439386770278);
36 | }
37 | ```
38 |
39 | The hash of an interface is defined as truncated to 128 bits SHA256.
40 |
41 | ## Drawbacks
42 |
43 | This proposal doesn't guarantee that the contract would behave correctly to an interface, also it doesn't provide a guaranteed way to avoid name clashes between different interfaces. This is a non-goal for this proposal.
44 |
45 | This proposal isn't tied to a specific technical interface. This could lead to multiple interfaces that do the same thing but with different IDs. This is a non-goal for this proposal since a centralized registry would be very useful for existing interfaces and a custom one would be used mostly in-house.
46 |
47 | ## Rationale and alternatives
48 |
49 | - Why 128 bit? We are looking at a global namespace that we need to keep without conflicts, we can't use anything much smaller since the probability of conflicts would be much higher. We are looking at UUID-like entropy that is exactly 128-bit and is time-proven. More than 128 is too wasteful.
50 | - Why freeform? As mentioned before, it is easier just to define some ID to start work early and then eventually build a standard. Also interfaces (like ERC20) usually not just a technical interface, but also a number of rules on how to work with it.
51 | - Why not find out what contract supports by decompiling? Explicit is always better than implicit in open-world scenarios. We can't rely on our "disassembling" capabilities to perform introspections, even small errors could be fatal.
52 | - Why not hash of representation? Right now there are no compilers that support that, also this proposal is future-proof. If anyone would want to build something more automated they could easily build their own hashes by their own rules keeping everything the same for external observers.
53 |
54 | ## Prior art
55 |
56 | [Ethereum Interface Detection](https://eips.ethereum.org/EIPS/eip-165)
57 |
--------------------------------------------------------------------------------
/pages/ref/evolution/OTP-002.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "OTP-002: Contract ABI"
3 | ---
4 |
5 | # OTP-002: Contract ABI
6 |
7 | ABI defines how to communicate with smart contracts. It contains information about the contract's receivers, data structures, etc.
8 |
9 | ## Motivation
10 |
11 | ABI is an essential tool that allows developers to generate handy bindings, UIs, etc. One of the best consumer usages would be using a DAO and being able to confirm what exactly it is trying to do before signing a transaction.
12 |
13 | ## Guide
14 |
15 | This OTP is based on types that are defined in TLB+ and it is advised to know them before reading this OTP.
16 |
17 | ## Specification
18 |
19 | ABI is a JSON file:
20 |
21 | ```json
22 | {
23 | "name": "MyContract",
24 | "types": [
25 | {
26 | "name": "MyRequest",
27 | "header": 12315123,
28 | "fields": [
29 | {
30 | "name": "queryId",
31 | "type": {
32 | "kind": "simple",
33 | "type": "int",
34 | "optional": false,
35 | "format": "uint256"
36 | }
37 | }
38 | ]
39 | }
40 | ],
41 | "receivers": [
42 | { "type": "binary", "kind": "internal", "name": "MyRequest" },
43 | { "type": "binary", "kind": "internal" },
44 | { "type": "comment", "kind": "internal", "comment": "Vote!" },
45 | { "type": "comment", "kind": "internal" },
46 | { "type": "empty", "kind": "internal" }
47 | ],
48 | "getters": [
49 | { "name": "getOwner", "type": "address", "args": [] },
50 | {
51 | "name": "getBalance",
52 | "type": "coins",
53 | "args": [
54 | {
55 | "name": "invested",
56 | "type": {
57 | "kind": "simple",
58 | "type": "uint",
59 | "format": "coins"
60 | }
61 | }
62 | ]
63 | }
64 | ],
65 | "errors": {
66 | "123": "Error description",
67 | "124": "Division by zero"
68 | }
69 | }
70 | ```
71 |
72 | ## Drawbacks
73 |
74 | - Binary and compact representation of ABI could be better, but it is not critical for now.
75 |
76 | ## Prior art
77 |
78 | - OTP-001, that is complimentary to this OTP.
79 |
--------------------------------------------------------------------------------
/pages/ref/evolution/OTP-003.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "OTP-003: Self-ABI reporting"
3 | ---
4 |
5 | # OTP-003: Self-ABI reporting
6 |
7 | This proposal defines how to report the contract's ABI using the IPFS link.
8 |
9 | ## Motivation
10 |
11 | Usually, ABI is supplied separately using a third-party service or via some repository on GitHub. This proposal suggests adding a new self-reporting of the contract's ABI using a link to an IPFS. This would allow us to avoid any third-party dependency and allow anyone to build tools that rely on ABI such as explorers, wallets, etc.
12 |
13 | ## Specification
14 |
15 | To support this proposal, the contract should implement OTP-001 and report an interface `org.ton.abi.ipfs.v0`. Then implement a get method `get_abi_ipfs` that returns a string with an IPFS link to the ABI file. The link should be in the format `ipfs://`.
16 |
17 | ## Drawbacks
18 |
19 | - No way to upgrade ABI without updating a contract. This is a drawback exists only for hardcoded links.
20 |
--------------------------------------------------------------------------------
/pages/ref/evolution/OTP-004.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "OTP-004: Auto Encoder"
3 | ---
4 |
5 | # OTP-004: Auto Encoder
6 |
7 | This proposal defines a way to automatically build a serialization layout for a given structure.
8 |
9 | ## Motivation
10 |
11 | Designing a serialization layout in TLB is a very risky task. Developers have to take care of the size limitations of cells and remember how many bits are used by each field. This is a very error-prone task and it is very easy to make a mistake. This proposal aims to solve this problem by providing a way to automatically build a serialization layout for a given structure.
12 |
13 | ## Specification
14 |
15 | We define auto-encoder as an eager algorithm that builds a serialization layout for a given structure. The algorithm is defined as follows:
16 |
17 | ```text
18 | Define available references and bits in a current cell
19 | as `available_references` and `available_bits` respectively.
20 | NOTE: there must be at least one reference reserved for the serialization tail and one
21 | bit for an optional flag. Depending on context more references or bits may be reserved.
22 |
23 | For each field in A:
24 | (size_bits, size_ref) = get_field_max_size(field);
25 | if (available_bits >= size_bits && available_references >= size_ref) {
26 | Push field to a current cell
27 | } else {
28 | available_references = (1023 - 1);
29 | available_bits = (4 - 1);
30 | Allocate a new tail and continue from the current field
31 | }
32 | ```
33 |
34 | ## Drawbacks
35 |
36 | - This is an implicit algorithm. It is not clear results of this allocator have to be checked to make compatible serialization.
--------------------------------------------------------------------------------
/pages/ref/evolution/OTP-005.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "OTP-005: Argument-addressable contracts"
3 | ---
4 |
5 | # OTP-005: Argument-addressable contracts
6 |
7 | This proposal defines a way to address contracts by their arguments instead of their initial data.
8 |
9 | ## Motivation
10 |
11 | Init data could be very different from the arguments. This allows us to avoid executing untrusted code from another contract in the context of a current one or executing TVM code off-chain for deployment that could be risky in some cases.
12 |
13 | ## Specification
14 |
15 | This specification defines a way to write arguments to an init data cell to be read by the contract code during deployment.
16 |
17 | ### Prefix
18 |
19 | The prefix is defined by a smart contract itself, but by default, it is assumed as a `single zero bit`. Prefix is used by the contract code to distinguish between deployed and not-deployed state.
20 |
21 | ### Arguments encoding
22 |
23 | Arguments are encoded using [Auto Encoder](/ref/evolution/OTP-004).
24 |
25 | ### Contract Requirements
26 |
27 | - Contract MUST expose `lazy_deployment_completed` get method that returns `true` if the contract is deployed and `false` otherwise.
28 | - Contract MUST expose `org.ton.deploy.lazy.v0` interface.
29 |
30 | ## Drawbacks
31 |
32 | - Contracts could be in a semi-deployed state
33 | - There are multiple ways to write arguments that would end up in a different init data and a different address
34 | - You can deploy a pre-initialized contract and it would have a different address while being fully functional
35 | - Unpredictable gas usage on deployment. Deployments are usually expensive, but this proposal makes it even more expensive.
36 |
--------------------------------------------------------------------------------
/pages/ref/evolution/OTP-006.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: "OTP-006: Contract Package"
3 | ---
4 |
5 | # OTP-006: Contract Package
6 |
7 | This proposal defines a way to package compile contracts, their dependencies, and all related metadata into a single file.
8 |
9 | ## Motivation
10 |
11 | A unified package format is needed to simplify the process of deploying and upgrading contracts using various tools without the need to configure them.
12 |
13 | ## Specification
14 |
15 | The package file has an extension `.pkg` and is a JSON file:
16 |
17 | ```json
18 | {
19 | "name": "My Contract",
20 | "code": "... boc of code ...",
21 | "abi": "ABI string to be uploaded as is to IPFS or Ton Storage",
22 | "init": {
23 | "kind": "direct", // Means that this contract can be deployed as is
24 | "args": {
25 | // ... Arguments in ABI format
26 | },
27 | "prefix": {
28 | // Optional prefix for contract init state
29 | "bits": 0, // Number of bits in prefix
30 | "value": 0 // Value of prefix
31 | },
32 | "deployment": {
33 | "kind": "system-cell", // Means that this contract can be deployed as is
34 | "system": "... boc of system cell ..."
35 | }
36 | },
37 | "sources": {
38 | "file.ton": "... base64 encoded source file ..."
39 | },
40 | "compiler": {
41 | "name": "func",
42 | "version": "0.4.1",
43 | "parameters": "..." // Optional string parameters
44 | }
45 | }
46 | ```
47 |
48 | ## Drawbacks
49 |
50 | None
51 |
52 |
53 | ## Reference
54 | - Bags of Cells(BOC): https://docs.ton.org/develop/data-formats/cell-boc#packing-a-bag-of-cells
55 |
--------------------------------------------------------------------------------
/pages/ref/evolution/_meta.js:
--------------------------------------------------------------------------------
1 | export default {
2 | overview: 'Overview',
3 | 'OTP-001': 'OTP-001: Supported Interfaces',
4 | 'OTP-002': 'OTP-002: Contract ABI',
5 | 'OTP-003': 'OTP-003: Self-ABI reporting',
6 | 'OTP-004': 'OTP-004: Auto Encoder',
7 | 'OTP-005': 'OTP-005: Argument-addressable contracts',
8 | 'OTP-006': 'OTP-006: Contract Package'
9 | }
10 |
--------------------------------------------------------------------------------
/pages/ref/evolution/overview.mdx:
--------------------------------------------------------------------------------
1 | # Evolution overview
2 |
3 | import { Cards } from 'nextra/components'
4 |
5 | This sub-section contains all standards that are defined by the Tact Foundation and are used in the evolution process of the Tact and TON ecosystem.
6 | Additionally, it features TEPs (TON Enhancement Proposals) and the up-to-date changelog of Tact updates.
7 |
8 | ## Open Tact Proposals (OTPs)
9 |
10 |
11 |
16 |
21 |
26 |
31 |
36 |
41 |
42 |
43 | ## TON Enhancement Protocols (TEPs)
44 |
45 | The main goal of TON Enhancement Proposals is to provide a convenient and formal way to propose changes to TON Blockchain and standardize ways of interaction between different parts of ecosystem. Proposal management is done using GitHub pull requests, the process is described formally in [TEP-1](https://github.com/ton-blockchain/TEPs/blob/master/text/0001-tep-lifecycle.md).
46 |
47 | List of [merged TEPs](https://github.com/ton-blockchain/TEPs#merged-teps).
48 |
49 | ## Changelog
50 |
51 | All notable changes to the main Tact repository are documented in the [CHANGELOG.md](https://github.com/tact-lang/tact/blob/main/CHANGELOG.md).
52 |
--------------------------------------------------------------------------------
/pages/ref/index.mdx:
--------------------------------------------------------------------------------
1 | # Reference overview
2 |
3 | import { Cards, Steps } from 'nextra/components'
4 |
5 | Welcome to the **Reference** section of Tact documentation — a place for discovering the Tact's standard library, grammar specification and evolution process.
6 |
7 | Here are its main contents:
8 |
9 |
10 |
11 | ### Core library
12 |
13 | [Core library](/ref/core-base) gives a comprehensive list of auto-included functions, traits and other constructs with examples of their usage.
14 |
15 |
16 |
21 |
22 |
23 | ### Standard libraries
24 |
25 | [Standard libraries](/ref/standard-libraries) sub-section explains how to use the bundled libraries, lists all their contents with examples of their usage.
26 |
27 |
28 |
33 |
34 |
35 | ### Specification
36 |
37 | [Specification](/ref/spec) page provides full Tact grammar written in Ohm language, which is used in the Tact's compiler. Aimed at more experienced programmers, but generally can still be very handy to quickly grasp all of the possible syntax in the language.
38 |
39 |
40 |
45 |
46 |
47 | ### Evolution
48 |
49 | Finally, [Evolution](/ref/evolution/overview) sub-section gives insight on important decisions about language semantics, Tact's future and links to the up-to-date changelog of Tact updates.
50 |
51 |
52 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/pages/ref/standard-libraries.mdx:
--------------------------------------------------------------------------------
1 | # Standard libraries overview
2 |
3 | import { Callout } from 'nextra-theme-docs'
4 |
5 | Some libraries (also referred to as standard libraries or stdlibs) come bundled with Tact compiler, but aren't automatically included to your project until explicitly made to.
6 |
7 | To import any standard library, use the [`import{:tact}` keyword](/book/import) followed by the name of that library in a [string][p], like so:
8 |
9 | ```tact
10 | // This would include everything from @stdlib/deploy into your codebase:
11 | import "@stdlib/deploy";
12 | ```
13 |
14 | ## List of standard libraries: [#list]
15 |
16 | Library | Description | Commonly used APIs
17 | :----------------------- | :--------------------------------------------------------------- | :-----------------
18 | [`@stdlib/config`][1] | Config and elector address retrieval. | [`getConfigAddress(){:tact}`][gca], [`getElectorAddress(){:tact}`][gea]
19 | [`@stdlib/content`][2] | Encoding off-chain link [strings][p] to a [`Cell{:tact}`][cell]. | [`createOffchainContent(){:tact}`][coff]
20 | [`@stdlib/deploy`][3] | Unified mechanism for deployments. | [`Deployable{:tact}`][dep], [`FactoryDeployable{:tact}`][fcd]
21 | [`@stdlib/dns`][4] | Resolution of [DNS][dns] names. | [`DNSResolver{:tact}`][dnsr], [`dnsInternalVerify(){:tact}`][dnsi]
22 | [`@stdlib/ownable`][5] | Traits for ownership management. | [`Ownable{:tact}`][own], [`OwnableTransferable{:tact}`][ownt]
23 | [`@stdlib/stoppable`][6] | Traits that allow contract stops. Requires [@stdlib/ownable][5]. | [`Stoppable{:tact}`][stp], [`Resumable{:tact}`][res]
24 |
25 | [1]: /ref/stdlib-config
26 | [gca]: /ref/stdlib-config#getconfigaddress
27 | [gea]: /ref/stdlib-config#getelectoraddress
28 |
29 | [2]: /ref/stdlib-content
30 | [coff]: /ref/stdlib-content#createoffchaincontent
31 |
32 | [3]: /ref/stdlib-deploy
33 | [dep]: /ref/stdlib-deploy#deployable
34 | [fcd]: /ref/stdlib-deploy#factorydeployable
35 |
36 | [4]: /ref/stdlib-dns
37 | [dnsr]: /ref/stdlib-dns#dnsresolver
38 | [dnsi]: /ref/stdlib-dns#dnsinternalverify
39 |
40 | [5]: /ref/stdlib-ownable
41 | [own]: /ref/stdlib-ownable#ownable
42 | [ownt]: /ref/stdlib-ownable#ownabletransferable
43 |
44 | [6]: /ref/stdlib-stoppable
45 | [stp]: /ref/stdlib-stoppable#stoppable
46 | [res]: /ref/stdlib-stoppable#resumable
47 |
48 | [p]: /book/types#primitive-types
49 | [cell]: /book/cells#cells
50 | [dns]: https://docs.ton.org/participate/web3/dns
51 |
--------------------------------------------------------------------------------
/pages/ref/stdlib-config.mdx:
--------------------------------------------------------------------------------
1 | # @stdlib/config
2 |
3 | Provides functions for config and elector Address retrieval.
4 |
5 | To use this library, import `@stdlib/config`:
6 |
7 | ```tact
8 | import "@stdlib/config";
9 | ```
10 |
11 | ## Functions
12 |
13 | ### getConfigAddress
14 |
15 | ```tact
16 | fun getConfigAddress(): Address;
17 | ```
18 |
19 | Retrieves config parameter $0$ as an [`Address{:tact}`][p].
20 |
21 | Source code:
22 |
23 | ```tact
24 | fun getConfigAddress(): Address {
25 | let cell: Cell = getConfigParam(0)!!;
26 | let sc: Slice = cell.beginParse();
27 | return newAddress(-1, sc.loadUint(256));
28 | }
29 | ```
30 |
31 | ### getElectorAddress
32 |
33 | ```tact
34 | fun getElectorAddress(): Address;
35 | ```
36 |
37 | Retrieves config parameter $1$ as an [`Address{:tact}`][p].
38 |
39 | Source code:
40 |
41 | ```tact
42 | fun getElectorAddress(): Address {
43 | let cell: Cell = getConfigParam(1)!!;
44 | let sc: Slice = cell.beginParse();
45 | return newAddress(-1, sc.loadUint(256));
46 | }
47 | ```
48 |
49 | ## Sources
50 |
51 | * [config.tact](https://github.com/tact-lang/tact/blob/61541b7783098e1af669faccd7d2334c10981c72/stdlib/libs/config.tact)
52 |
53 | [p]: /book/types#primitive-types
54 |
--------------------------------------------------------------------------------
/pages/ref/stdlib-content.mdx:
--------------------------------------------------------------------------------
1 | # @stdlib/content
2 |
3 | Provides a function for encoding an off-chain link from a [`String{:tact}`][p] to a [`Cell{:tact}`][cell].
4 |
5 | To use this library, import `@stdlib/content`:
6 |
7 | ```tact
8 | import "@stdlib/content";
9 | ```
10 |
11 | ## Functions
12 |
13 | ### createOffchainContent
14 |
15 | ```tact
16 | fun createOffchainContent(link: String): Cell;
17 | ```
18 |
19 | Encodes an off-chain `link` from a [`String{:tact}`][p] to a [`Cell{:tact}`][cell].
20 |
21 | Source code:
22 |
23 | ```tact
24 | fun createOffchainContent(link: String): Cell {
25 | let builder: StringBuilder = beginStringFromBuilder(beginCell().storeUint(0x01, 8));
26 | builder.append(link);
27 | return builder.toCell();
28 | }
29 | ```
30 |
31 | ## Sources
32 |
33 | * [content.tact](https://github.com/tact-lang/tact/blob/61541b7783098e1af669faccd7d2334c10981c72/stdlib/libs/content.tact)
34 |
35 | [p]: /book/types#primitive-types
36 | [cell]: /book/cells#cells
37 |
--------------------------------------------------------------------------------
/pages/ref/stdlib-deploy.mdx:
--------------------------------------------------------------------------------
1 | # @stdlib/deploy
2 |
3 | Provides unified mechanisms for deployments.
4 |
5 | To use this library, import `@stdlib/deploy`:
6 |
7 | ```tact
8 | import "@stdlib/deploy";
9 | ```
10 |
11 | ## Messages
12 |
13 | ### Deploy
14 |
15 | ```tact
16 | message Deploy {
17 | queryId: Int as uint64;
18 | }
19 | ```
20 |
21 | ### DeployOk
22 |
23 | ```tact
24 | message DeployOk {
25 | queryId: Int as uint64;
26 | }
27 | ```
28 |
29 | ### FactoryDeploy
30 |
31 | ```tact
32 | message FactoryDeploy {
33 | queryId: Int as uint64;
34 | cashback: Address;
35 | }
36 | ```
37 |
38 | ## Traits
39 |
40 | ### Deployable
41 |
42 | Simplest trait `Deployable{:tact}` that provides a handy unified mechanism for deployments by implementing a simple receiver for the [Deploy](#deploy) message.
43 |
44 | 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](#deploy) message.
45 |
46 | 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](#deployok) message and echo the same `queryId` in the response.
47 |
48 | Source code:
49 |
50 | ```tact
51 | trait Deployable {
52 | receive(deploy: Deploy) {
53 | self.notify(DeployOk{queryId: deploy.queryId}.toCell());
54 | }
55 | }
56 | ```
57 |
58 | Usage example:
59 |
60 | ```tact /Deployable/
61 | import "@stdlib/deploy";
62 |
63 | contract ExampleContract with Deployable {
64 | // Now, this contract has a receiver for Deploy message
65 | }
66 | ```
67 |
68 | ### FactoryDeployable
69 |
70 | Trait `FactoryDeployable{:tact}` provides a handy unified mechanism for chained deployments.
71 |
72 | Source code:
73 |
74 | ```tact
75 | trait FactoryDeployable {
76 | receive(deploy: FactoryDeploy) {
77 | self.forward(deploy.cashback, DeployOk{queryId: deploy.queryId}.toCell(), false, null);
78 | }
79 | }
80 | ```
81 |
82 | Usage example:
83 |
84 | ```tact /FactoryDeployable/
85 | import "@stdlib/deploy";
86 |
87 | contract ExampleContract with FactoryDeployable {
88 | // Now, this contract has a receiver for FactoryDeploy message
89 | }
90 | ```
91 |
92 | ## Sources
93 |
94 | * [deploy.tact](https://github.com/tact-lang/tact/blob/61541b7783098e1af669faccd7d2334c10981c72/stdlib/libs/deploy.tact)
95 |
--------------------------------------------------------------------------------
/pages/ref/stdlib-dns.mdx:
--------------------------------------------------------------------------------
1 | # @stdlib/dns
2 |
3 | Provides means for resolution of [DNS](https://docs.ton.org/participate/web3/dns) names.
4 |
5 | To use this library, import `@stdlib/dns`:
6 |
7 | ```tact
8 | import "@stdlib/dns";
9 | ```
10 |
11 | ## Structs
12 |
13 | ### DNSResolveResult
14 |
15 | ```tact
16 | struct DNSResolveResult {
17 | prefix: Int;
18 | record: Cell?;
19 | }
20 | ```
21 |
22 | ## Functions
23 |
24 | ### dnsStringToInternal
25 |
26 | ```tact
27 | @name(dns_string_to_internal)
28 | native dnsStringToInternal(str: String): Slice?;
29 | ```
30 |
31 | Converts a DNS string to a [`Slice{:tact}`][slice] or [`null{:tact}`](/book/optionals), if it's impossible.
32 |
33 | Source code (FunC): [dns.fc#L1](https://github.com/tact-lang/tact/blob/61541b7783098e1af669faccd7d2334c10981c72/stdlib/libs/dns.fc#L1)
34 |
35 | ### dnsInternalNormalize
36 |
37 | ```tact
38 | @name(dns_internal_normalize)
39 | native dnsInternalNormalize(src: Slice): Slice;
40 | ```
41 |
42 | Normalizes the internal DNS representation of the [`Slice{:tact}`][slice].
43 |
44 | Source code (FunC): [dns.fc#L125](https://github.com/tact-lang/tact/blob/61541b7783098e1af669faccd7d2334c10981c72/stdlib/libs/dns.fc#L125)
45 |
46 | ### dnsInternalVerify
47 |
48 | ```tact
49 | @name(dns_internal_verify)
50 | native dnsInternalVerify(subdomain: Slice): Bool;
51 | ```
52 |
53 | Verifies the internal DNS representation of the subdomain [`Slice{:tact}`][slice].
54 |
55 | Source code (FunC): [dns.fc#L81](https://github.com/tact-lang/tact/blob/61541b7783098e1af669faccd7d2334c10981c72/stdlib/libs/dns.fc#L81)
56 |
57 | ### dnsExtractTopDomainLength
58 |
59 | ```tact
60 | fun dnsExtractTopDomainLength(subdomain: Slice): Int;
61 | ```
62 |
63 | Calculates length of a top domain in the `subdomain` [`Slice{:tact}`][slice].
64 |
65 | Source code:
66 |
67 | ```tact
68 | fun dnsExtractTopDomainLength(subdomain: Slice): Int {
69 | let i: Int = 0;
70 | let needBreak: Bool = false;
71 | do {
72 | let char: Int = subdomain.loadUint(8); // we do not check domain.length because it MUST contain \0 character
73 | needBreak = char == 0;
74 | if (!needBreak) {
75 | i += 8;
76 | }
77 | } until (needBreak);
78 | require(i != 0, "Invalid DNS name");
79 | return i;
80 | }
81 | ```
82 |
83 | ### dnsExtractTopDomain
84 |
85 | ```tact
86 | fun dnsExtractTopDomain(subdomain: Slice): Slice;
87 | ```
88 |
89 | Extracts top domain from a `subdomain` [`Slice{:tact}`][slice].
90 |
91 | Source code:
92 |
93 | ```tact
94 | fun dnsExtractTopDomain(subdomain: Slice): Slice {
95 | let len: Int = dnsExtractTopDomainLength(subdomain);
96 | return subdomain.loadBits(len);
97 | }
98 | ```
99 |
100 | ### dnsResolveNext
101 |
102 | ```tact
103 | fun dnsResolveNext(address: Address): Cell;
104 | ```
105 |
106 | Resolves an `address` [`Address{:tact}`][p] into a [`Cell{:tact}`][cell].
107 |
108 | Source code:
109 |
110 | ```tact
111 | fun dnsResolveNext(address: Address): Cell {
112 | return beginCell()
113 | .storeUint(0xba93, 16)
114 | .storeAddress(address)
115 | .endCell();
116 | }
117 | ```
118 |
119 | ### dnsResolveWallet
120 |
121 | ```tact
122 | fun dnsResolveWallet(address: Address): Cell;
123 | ```
124 |
125 | Resolves a wallet `address` [`Address{:tact}`][p] into a [`Cell{:tact}`][cell].
126 |
127 | Source code:
128 |
129 | ```tact
130 | fun dnsResolveWallet(address: Address): Cell {
131 | return beginCell()
132 | .storeUint(0x9fd3, 16)
133 | .storeAddress(address)
134 | .storeUint(0, 8)
135 | .endCell();
136 | }
137 | ```
138 |
139 | ## Traits
140 |
141 | ### DNSResolver
142 |
143 | Trait `DNSResolver` provides two helper functions for DNS resolution:
144 |
145 | 1. [getter function](/book/functions#getter-functions) `dnsresolve(){:tact}`, which corresponds to its [FunC variant](https://docs.ton.org/develop/howto/subresolvers#dnsresolve-code).
146 | 2. virtual function `doResolveDNS(){:tact}`, which creates a struct [DNSResolveResult](#dnsresolveresult) out of subdomain [`Slice{:tact}`][slice] bits.
147 |
148 | Source code:
149 |
150 | ```tact
151 | trait DNSResolver {
152 | get fun dnsresolve(subdomain: Slice, category: Int): DNSResolveResult {
153 | // Normalize
154 | let delta: Int = 0;
155 | if (subdomain.preloadUint(8) == 0) {
156 | subdomain.loadUint(8); // Skip first byte
157 | delta += 8;
158 | }
159 |
160 | // Checks correctness
161 | require(dnsInternalVerify(subdomain), "Invalid DNS name");
162 |
163 | // Resolve
164 | let res: DNSResolveResult = self.doResolveDNS(subdomain, category);
165 | return DNSResolveResult{prefix: res.prefix + delta, record: res.record};
166 | }
167 | virtual fun doResolveDNS(subdomain: Slice, category: Int): DNSResolveResult {
168 | return DNSResolveResult{prefix: subdomain.bits(), record: null};
169 | }
170 | }
171 | ```
172 |
173 | Usage example:
174 |
175 | ```tact
176 | import "@stdlib/dns";
177 |
178 | contract ExampleContract with DNSResolver {
179 | // Now, this contract has a:
180 | // 1. dnsresolve getter function
181 | // 2. doResolveDNS virtual function
182 | }
183 | ```
184 |
185 | ## Sources
186 |
187 | * [dns.tact](https://github.com/tact-lang/tact/blob/61541b7783098e1af669faccd7d2334c10981c72/stdlib/libs/dns.tact)
188 | * [dns.fc](https://github.com/tact-lang/tact/blob/61541b7783098e1af669faccd7d2334c10981c72/stdlib/libs/dns.fc)
189 |
190 | [p]: /book/types#primitive-types
191 | [cell]: /book/cells#cells
192 | [slice]: /book/cells#slices
193 |
--------------------------------------------------------------------------------
/pages/ref/stdlib-ownable.mdx:
--------------------------------------------------------------------------------
1 | # @stdlib/ownable
2 |
3 | Provides [traits](/book/types#composite-types) for ownable contracts. This is most commonly used trait that is required by most other traits.
4 |
5 | To use this library, import `@stdlib/ownable`:
6 |
7 | ```tact
8 | import "@stdlib/ownable";
9 | ```
10 |
11 | ## Messages
12 |
13 | ### ChangeOwner
14 |
15 | ```tact
16 | message ChangeOwner {
17 | queryId: Int as uint64;
18 | newOwner: Address;
19 | }
20 | ```
21 |
22 | ### ChangeOwnerOk
23 |
24 | ```tact
25 | message ChangeOwnerOk {
26 | queryId: Int as uint64;
27 | newOwner: Address;
28 | }
29 | ```
30 |
31 | ## Traits
32 |
33 | ### Ownable
34 |
35 | [Trait](/book/types#composite-types) `Ownable{:tact}` declares an owner (non-editable) of a [contract](/book/contracts) and provides a helper function `requireOwner(){:tact}` that checks that a message was sent by an owner.
36 |
37 | This [trait](/book/types#composite-types) requires a field `owner: Address{:tact}` to be declared and exposes a [getter function](/book/functions#getter-functions) `owner(){:tact}`, which reads it from the [contract](/book/contracts).
38 |
39 | Source code:
40 |
41 | ```tact
42 | @interface("org.ton.ownable")
43 | trait Ownable {
44 | owner: Address;
45 |
46 | fun requireOwner() {
47 | nativeThrowUnless(132, sender() == self.owner);
48 | }
49 |
50 | get fun owner(): Address {
51 | return self.owner;
52 | }
53 | }
54 | ```
55 |
56 | Usage example:
57 |
58 | ```tact /Ownable/
59 | import "@stdlib/ownable";
60 |
61 | contract ExampleContract with Ownable {
62 | owner: Address;
63 |
64 | init(owner: Address) {
65 | self.owner = owner;
66 | }
67 | }
68 | ```
69 |
70 | ### OwnableTransferable
71 |
72 | `OwnableTransferable{:tact}` is an extension of an [`Ownable{:tact}`](#ownable) that allows to transfer ownership of a contract to another address. It provides a secure handle [Message](/book/structs-and-messages#messages) [`ChangeOwner{:tact}`](#changeowner) that could be called by an owner to transfer ownership.
73 |
74 | If the owner transfer request succeeds, the contract will reply with a [`ChangeOwnerOk{:tact}`](#changeownerok) [Message](/book/structs-and-messages#messages).
75 |
76 | Source code:
77 |
78 | ```tact
79 | @interface("org.ton.ownable.transferable.v2")
80 | trait OwnableTransferable with Ownable {
81 | owner: Address;
82 |
83 | receive(msg: ChangeOwner) {
84 | // Check if the sender is the owner
85 | self.requireOwner();
86 |
87 | // Update owner
88 | self.owner = msg.newOwner;
89 |
90 | // Reply result
91 | self.reply(ChangeOwnerOk{ queryId: msg.queryId, newOwner: msg.newOwner }.toCell());
92 | }
93 | }
94 | ```
95 |
96 | Usage example:
97 |
98 | ```tact /OwnableTransferable/
99 | import "@stdlib/ownable";
100 |
101 | contract ExampleContract with OwnableTransferable {
102 | owner: Address;
103 |
104 | init(owner: Address) {
105 | self.owner = owner;
106 | }
107 | }
108 | ```
109 |
110 | ## Sources
111 |
112 | * [ownable.tact](https://github.com/tact-lang/tact/blob/61541b7783098e1af669faccd7d2334c10981c72/stdlib/libs/ownable.tact)
113 |
--------------------------------------------------------------------------------
/pages/ref/stdlib-stoppable.mdx:
--------------------------------------------------------------------------------
1 | # @stdlib/stoppable
2 |
3 | Provides [traits](/book/types#composite-types) that allow to stop a [contract](/book/contracts). Useful for emergency or maintenance modes. Requires an [`Ownable{:tact}`](/ref/stdlib-ownable#ownable) trait from [`@stdlib/ownable`](/ref/stdlib-ownable). This trait just manages a single flag `stopped` in the contract and handling stopped state have to be done in the contract itself.
4 |
5 | To use this library, import `@stdlib/stoppable`:
6 |
7 | ```tact
8 | import "@stdlib/stoppable"; // this would automatically import @stdlib/ownable too!
9 | ```
10 |
11 | ## Traits
12 |
13 | ### Stoppable
14 |
15 | [Trait](/book/types#composite-types) `Stoppable{:tact}` implements receiver for the [Message](/book/structs-and-messages#messages) [string](/book/types#primitive-types) "Stop" that can be sent by owner, implements `stopped(){:tact}` [getter function](/book/functions#getter-functions) that returns `true{:tact}` if contract is stopped (or `false{:tact}` otherwise) and provides private (non-getter) functions `requireNotStopped(){:tact}` and `requireStopped(){:tact}`.
16 |
17 | Source code:
18 |
19 | ```tact
20 | @interface("org.ton.stoppable")
21 | trait Stoppable with Ownable {
22 | stopped: Bool;
23 | owner: Address;
24 |
25 | fun requireNotStopped() {
26 | require(!self.stopped, "Contract stopped");
27 | }
28 |
29 | fun requireStopped() {
30 | require(self.stopped, "Contract not stopped");
31 | }
32 |
33 | receive("Stop") {
34 | self.requireOwner();
35 | self.requireNotStopped();
36 | self.stopped = true;
37 | self.reply("Stopped".asComment());
38 | }
39 |
40 | get fun stopped(): Bool {
41 | return self.stopped;
42 | }
43 | }
44 | ```
45 |
46 | Usage example:
47 |
48 | ```tact /Stoppable/
49 | import "@stdlib/ownable";
50 | import "@stdlib/stoppable";
51 |
52 | contract MyContract with Stoppable {
53 | owner: Address;
54 | stopped: Bool;
55 |
56 | init(owner: Address) {
57 | self.owner = owner;
58 | self.stopped = false;
59 | }
60 | }
61 | ```
62 |
63 | ### Resumable
64 |
65 | `Resumable{:tact}` [trait](/book/types#composite-types) extends [`Stoppable{:tact}`](#stoppable) trait and allows to resume [contract](/book/contracts) execution.
66 |
67 | Source code:
68 |
69 | ```tact
70 | @interface("org.ton.resumable")
71 | trait Resumable with Stoppable {
72 | stopped: Bool;
73 | owner: Address;
74 |
75 | receive("Resume") {
76 | self.requireOwner();
77 | self.requireStopped();
78 | self.stopped = false;
79 | self.reply("Resumed".asComment());
80 | }
81 | }
82 | ```
83 |
84 | Usage example:
85 |
86 | ```tact /Resumable/
87 | import "@stdlib/ownable";
88 | import "@stdlib/stoppable";
89 |
90 | contract MyContract with Resumable {
91 | owner: Address;
92 | stopped: Bool;
93 |
94 | init(owner: Address) {
95 | self.owner = owner;
96 | self.stopped = false;
97 | }
98 | }
99 | ```
100 |
101 | ## Sources
102 |
103 | * [stoppable.tact](https://github.com/tact-lang/tact/blob/61541b7783098e1af669faccd7d2334c10981c72/stdlib/libs/stoppable.tact)
104 |
--------------------------------------------------------------------------------
/public/abi-and-tlb/tact-abi-tlb-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/abi-and-tlb/tact-abi-tlb-1.png
--------------------------------------------------------------------------------
/public/banner.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/banner.jpeg
--------------------------------------------------------------------------------
/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/favicon.png
--------------------------------------------------------------------------------
/public/tact-hello-world/tact-compile-success.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-hello-world/tact-compile-success.jpg
--------------------------------------------------------------------------------
/public/tact-hello-world/tact-compiler-scheme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-hello-world/tact-compiler-scheme.png
--------------------------------------------------------------------------------
/public/tact-hello-world/tact-deployment-process-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-hello-world/tact-deployment-process-1.png
--------------------------------------------------------------------------------
/public/tact-hello-world/tact-deployment-process-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-hello-world/tact-deployment-process-2.png
--------------------------------------------------------------------------------
/public/tact-hello-world/tact-deployment-process-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-hello-world/tact-deployment-process-3.png
--------------------------------------------------------------------------------
/public/tact-hello-world/tact-deployment-process-4-b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-hello-world/tact-deployment-process-4-b.png
--------------------------------------------------------------------------------
/public/tact-hello-world/tact-hello-world-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-hello-world/tact-hello-world-1.png
--------------------------------------------------------------------------------
/public/tact-hello-world/tact-hello-world-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-hello-world/tact-hello-world-3.png
--------------------------------------------------------------------------------
/public/tact-hello-world/tact-hello-world-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-hello-world/tact-hello-world-4.png
--------------------------------------------------------------------------------
/public/tact-hello-world/tact-hello-world-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-hello-world/tact-hello-world-5.png
--------------------------------------------------------------------------------
/public/tact-hello-world/tact-hello-world-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-hello-world/tact-hello-world-6.png
--------------------------------------------------------------------------------
/public/tact-hello-world/tact-hello-world-7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-hello-world/tact-hello-world-7.png
--------------------------------------------------------------------------------
/public/tact-jetton/tact-jetton-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-jetton/tact-jetton-1.png
--------------------------------------------------------------------------------
/public/tact-jetton/tact-jetton-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-jetton/tact-jetton-10.png
--------------------------------------------------------------------------------
/public/tact-jetton/tact-jetton-11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-jetton/tact-jetton-11.png
--------------------------------------------------------------------------------
/public/tact-jetton/tact-jetton-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-jetton/tact-jetton-2.png
--------------------------------------------------------------------------------
/public/tact-jetton/tact-jetton-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-jetton/tact-jetton-5.png
--------------------------------------------------------------------------------
/public/tact-jetton/tact-jetton-6-b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-jetton/tact-jetton-6-b.png
--------------------------------------------------------------------------------
/public/tact-jetton/tact-jetton-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-jetton/tact-jetton-6.png
--------------------------------------------------------------------------------
/public/tact-jetton/tact-jetton-7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-jetton/tact-jetton-7.png
--------------------------------------------------------------------------------
/public/tact-jetton/tact-jetton-8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-jetton/tact-jetton-8.png
--------------------------------------------------------------------------------
/public/tact-jetton/tact-jetton-9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-jetton/tact-jetton-9.png
--------------------------------------------------------------------------------
/public/tact-wallet/tact-deployment-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-wallet/tact-deployment-1.png
--------------------------------------------------------------------------------
/public/tact-wallet/tact-deployment-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tact-lang/tact-docs/00be0e1e106d8f7a6cb714ce01989a974c3ccbc2/public/tact-wallet/tact-deployment-2.png
--------------------------------------------------------------------------------
/scripts/proposals-generate.js:
--------------------------------------------------------------------------------
1 | const matter = require('gray-matter');
2 | const fs = require('fs');
3 | const path = require('path');
4 | const process = require('process');
5 |
6 | // Update metadata
7 | let meta = {
8 | "index": "Evolution Process"
9 | };
10 | const prefix = '/pages/language/evolution';
11 | const cwd = process.cwd(); // current working directory of the process
12 | const files = fs.readdirSync(cwd + prefix);
13 | for (let f of files) {
14 | if (f.endsWith('.mdx') && f.startsWith("OTP-")) {
15 | const name = f.substring(0, f.length - 4);
16 | const title = matter(fs.readFileSync(path.join(cwd, prefix, f), 'utf8')).data.title;
17 | meta[name] = title;
18 | }
19 | }
20 |
21 | // Write metadata
22 | fs.writeFileSync(path.join(cwd, `${prefix}/_meta.json`), JSON.stringify(meta, null, 4));
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "strict": false,
12 | "forceConsistentCasingInFileNames": true,
13 | "noEmit": true,
14 | "incremental": true,
15 | "esModuleInterop": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "isolatedModules": true,
20 | "jsx": "preserve",
21 | "paths": {
22 | "@components/*": ["components/*"]
23 | }
24 | },
25 | "include": [
26 | "next-env.d.ts",
27 | "**/*.ts",
28 | "**/*.tsx"
29 | ],
30 | "exclude": [
31 | "node_modules"
32 | ]
33 | }
34 |
--------------------------------------------------------------------------------