Skip to content

Commit 65d7c0f

Browse files
committed
func-tolk flow
1 parent 9342cd0 commit 65d7c0f

File tree

9 files changed

+340
-83
lines changed

9 files changed

+340
-83
lines changed

docs/v3/guidelines/quick-start/developing-smart-contracts/deploying-to-network.mdx renamed to docs/v3/guidelines/quick-start/developing-smart-contracts/func-tolk-folder/deploying-to-network.mdx

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ This makes it possible to calculate the future wallet smart contract address.
2626

2727
### Magic storage member
2828

29-
In previous steps, we deliberately didn't explain the purpose of `ctxID` and `ID` stored in our smart contract's state and why they remained untouched in all the smart contract functionality. Now, their purpose should start to become clearer.
29+
In previous steps, we deliberately didn't explain the purpose of `ctx_id` and `ID` stored in our smart contract's state and why they remained untouched in all the smart contract functionality. Now, their purpose should start to become clearer.
3030

3131
Since we can't deploy a smart contract with the same `state_init`, the only way to provide the same initial code and **"same"** initial data is to create a separate field in it, ensuring additional uniqueness. This, in the case of a wallet, gives you the opportunity to have the same key pair for several wallet smart contracts.
3232

33-
### One to rule them all
33+
{/*### One to rule them all
3434
3535
If you've already considered that the `ID` field is a must-have for any smart contract, there is another opportunity that could change your mind. Let's examine the previously developed `CounterInternal` smart contract's init section:
3636
@@ -47,10 +47,10 @@ If we remove the `id` field from its initial storage, we can ensure that **only
4747
:::info Tokens
4848
This mechanism plays a crucial role in [Jetton Processing](/v3/guidelines/dapps/asset-processing/jettons/). Each non-native (jetton) token requires its own `Jetton Wallet` for a particular owner and, therefore, provides a calculable address for it, creating a **star scheme** with the basic wallet in the center.
4949
:::
50-
50+
*/}
5151
## Implementation
5252

53-
Now that our smart contracts are fully tested, we are ready to deploy them to TON. In `Blueprint SDK`, this process is the same for both `Mainnet` and `Testnet` and for any of the presented languages in the guide: `FunC`, `Tact`, or `Tolk`.
53+
Now that our smart contracts are fully tested, we are ready to deploy them to TON. In `Blueprint SDK`, this process is the same for both `Mainnet` and `Testnet` and for any of the presented languages in the guide: `FunC` or `Tolk`.
5454

5555
### Step 1: update the deployment script
5656

@@ -59,7 +59,6 @@ Deployment scripts rely on the same wrappers that you have used in testing scrip
5959
```typescript title="/scripts/deployHelloWorld.ts"
6060
import { toNano } from '@ton/core';
6161
import { HelloWorld } from '../wrappers/HelloWorld';
62-
import { CounterInternal } from '../wrappers/CounterInternal';
6362
import { compile, NetworkProvider } from '@ton/blueprint';
6463

6564
export async function run(provider: NetworkProvider) {
@@ -78,23 +77,7 @@ export async function run(provider: NetworkProvider) {
7877

7978
await provider.waitForDeploy(helloWorld.address);
8079

81-
const counterInternal = provider.open(
82-
await CounterInternal.fromInit(
83-
BigInt(Math.floor(Math.random() * 10000)),
84-
helloWorld.address
85-
)
86-
);
87-
88-
await counterInternal.send(
89-
provider.sender(),
90-
{ value: toNano('0.05') },
91-
null
92-
);
93-
94-
await provider.waitForDeploy(counterInternal.address);
95-
9680
console.log('ID', await helloWorld.getID());
97-
console.log('ID', (await counterInternal.getId()).toString());
9881
}
9982
```
10083

docs/v3/guidelines/quick-start/developing-smart-contracts/processing-messages.mdx renamed to docs/v3/guidelines/quick-start/developing-smart-contracts/func-tolk-folder/processing-messages.mdx

Lines changed: 13 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ By combining both of these patterns, you can achieve a comprehensive description
182182

183183
`External messages` are your only way of toggling smart contract logic from outside the blockchain. Usually, there is no need for implementation of them in smart contracts because, in most cases, you don't want external entry points to be accessible to anyone except you. If this is all the functionality that you want from the external section, the standard way is to delegate this responsibility to a separate actor - [wallet](v3/documentation/smart-contracts/contracts-specs/wallet-contracts#basic-wallets/), which is practically the main reason they were designed for.
184184

185-
Developing external endpoints includes several standard [approaches](/v3/documentation/smart-contracts/message-management/external-messages/) and [security measures](/v3/guidelines/smart-contracts/security/overview/) that might be overwhelming at this point. Therefore, in this guide, we will implement incrementing the previously added `ctxCounterExt` number and add a send message to our `Tact` contract.
185+
Developing external endpoints includes several standard [approaches](/v3/documentation/smart-contracts/message-management/external-messages/) and [security measures](/v3/guidelines/smart-contracts/security/overview/) that might be overwhelming at this point. Therefore, in this guide, we will implement incrementing the previously added `ctx_counter_ext` number.
186186

187187
:::danger
188188
This implementation is **unsafe** and may lead to losing your contract funds. Don't deploy it to `Mainnet`, especially with a high smart contract balance.
@@ -259,7 +259,7 @@ fun onExternalMessage(inMsg: slice) {
259259
</TabItem>
260260
</Tabs>
261261

262-
This function, upon receiving an external message, will increment our `ctxCounterExt` and also send an internal message to the specified address with the `increase` operation, which we will use to increment the counter on our `CounterInternal` smart contract.
262+
This function, upon receiving an external message, will increment our `ctx_counter_ext` and also send an internal message to the specified address with the `increase` operation.
263263

264264
Verify that the smart contract code is correct by running:
265265

@@ -308,13 +308,12 @@ async sendExternalIncrease(
308308

309309
### Step 3: update test
310310

311-
Update the test to ensure that the `HelloWorld` contract received the external message, sent an internal message to the `CounterInternal` contract, and both updated their counters:
311+
Update the test to ensure that the `HelloWorld` contract received the external message, and updated its counters:
312312

313313
```typescript title="/tests/HelloWorld.spec.ts"
314314
import { Blockchain, SandboxContract, TreasuryContract } from '@ton/sandbox';
315315
import { Cell, toNano} from '@ton/core';
316316
import { HelloWorld } from '../wrappers/HelloWorld';
317-
import { CounterInternal } from '../wrappers/CounterInternal';
318317
import '@ton/test-utils';
319318
import { compile } from '@ton/blueprint';
320319

@@ -328,7 +327,6 @@ describe('HelloWorld', () => {
328327
let blockchain: Blockchain;
329328
let deployer: SandboxContract<TreasuryContract>;
330329
let helloWorld: SandboxContract<HelloWorld>;
331-
let counterInternal: SandboxContract<CounterInternal>;
332330

333331
beforeEach(async () => {
334332
blockchain = await Blockchain.create();
@@ -354,34 +352,16 @@ describe('HelloWorld', () => {
354352
deploy: true,
355353
success: true,
356354
});
357-
358-
counterInternal = blockchain.openContract(
359-
await CounterInternal.fromInit(0n, helloWorld.address)
360-
);
361-
362-
const deployResultCounter = await counterInternal.send(
363-
deployer.getSender(),
364-
{ value: toNano('1.00') },
365-
null
366-
);
367-
368-
expect(deployResultCounter.transactions).toHaveTransaction({
369-
from: deployer.address,
370-
to: counterInternal.address,
371-
deploy: true,
372-
success: true
373-
});
374355
});
375356

376-
it('should send an external message and update counter', async () => {
377-
const counterInternalValueBefore = await counterInternal.getCounter();
357+
it('should receive external message and update counter', async () => {
378358
const [__, counterExtBefore] = await helloWorld.getCounters()
379359
const increase = 5;
380360

381361
const result = await helloWorld.sendExternalIncrease({
382362
increaseBy: increase,
383363
value: toNano(0.05),
384-
addr: counterInternal.address,
364+
addr: deployer.address, // Using deployer address
385365
queryID: 0
386366
});
387367

@@ -391,33 +371,22 @@ describe('HelloWorld', () => {
391371
success: true,
392372
});
393373

394-
expect(result.transactions).toHaveTransaction({
395-
from: helloWorld.address,
396-
to: counterInternal.address,
397-
success: true,
398-
});
399-
400-
const counterInternalValueAfter = await counterInternal.getCounter();
401-
402-
expect(counterInternalValueAfter).toBeGreaterThan(counterInternalValueBefore);
403374
const [_, counterExt] = await helloWorld.getCounters()
404375
expect(counterExtBefore + BigInt(increase)).toBe(counterExt);
405376
});
406-
407-
// ... previous tests
408377
});
409378
```
410379

411-
This test describes the common transaction flow of any `multi-contract` system:
412-
1. Send an external message to toggle the smart contract logic from outside the blockchain.
380+
{/*This test describes the common transaction flow of any `multi-contract` system:
381+
1. Send an external message to toggle the smart contract logic outside the blockchain.
413382
2. Trigger one or more internal messages to be sent to other contracts.
414383
3. Upon receiving an internal message, change the contract state and repeat **step 2** if required.
415384
416385
Since the resulting sequence of transactions might be overwhelming for understanding, it's a good practice to create a `sequence diagram` describing your system. Here is an example of our case:
417386
418387
<div style={{marginBottom: '30px'}} align="center">
419388
<img src="/img/tutorials/quick-start/multi-contract.png" alt="Multi-contract scheme"/>
420-
</div>
389+
</div> */}
421390

422391
Verify that all examples are correct by running the test script:
423392

@@ -430,15 +399,14 @@ Expected output should look like this:
430399
```bash
431400
PASS tests/HelloWorld.spec.ts
432401
HelloWorld
433-
✓ should correctly initialize and return the initial data (446 ms)
434-
✓ should send an external message and update counter (209 ms)
435-
✓ should increase counter (298 ms)
402+
✓ should receive external message and update counter (251 ms)
436403

437404
Test Suites: 1 passed, 1 total
438-
Tests: 3 passed, 3 total
405+
Tests: 1 passed, 1 total
439406
Snapshots: 0 total
440-
Time: 3.663 s, estimated 4 s
441-
Ran all test suites matching /HelloWorld/i.
407+
Time: 1.841 s, estimated 2 s
408+
Ran all test suites.
409+
442410
```
443411

444412
<Feedback />

docs/v3/guidelines/quick-start/developing-smart-contracts/storage-and-get-methods.mdx renamed to docs/v3/guidelines/quick-start/developing-smart-contracts/func-tolk-folder/storage-and-get-methods.mdx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ Let's examine the [Cell](/v3/concepts/dive-into-ton/ton-blockchain/cells-as-data
3737

3838
TON Blockchain uses a data structure called **Cell** as the fundamental unit for storing data. Cells are the building blocks of smart contract data and have the following characteristics:
3939

40-
- A Cell can store up to 1023 bits (approximately 128 bytes) of data
41-
- A Cell can reference up to 4 other Cells (children)
42-
- A Cell is immutable once created
40+
- A Cell can store up to 1023 bits (approximately 128 bytes) of data.
41+
- A Cell can reference up to 4 other Cells (children).
42+
- A Cell is immutable once created.
4343

4444
You can think of a Cell as the following structure:
4545

@@ -118,11 +118,11 @@ fun saveData() {
118118
Let's modify our example slightly by exploring another common storage management approach in smart contract development:
119119

120120
Rather than initializing global variables, we'll:
121-
1. Pass storage members as parameters via `save_data(members...)`
122-
2. Retrieve them using `(members...) = get_data()`
123-
3. Move the global variables `ctx_id` and `ctx_counter` into method bodies
121+
1. Pass storage members as parameters via `save_data(members...)`.
122+
2. Retrieve them using `(members...) = get_data()`.
123+
3. Move the global variables `ctx_id` and `ctx_counter` into the method bodies.
124124

125-
Also let's add an additional **256-bit integer** to our storage. The modified implementation should appear as follows:
125+
Also let's add an additional **256-bit integer** to our storage as `ctx_counter_ext` global variable. The modified implementation should appear as follows:
126126

127127
<Tabs groupId="language">
128128
<TabItem value="FunC" label="FunC">
@@ -184,7 +184,7 @@ fun saveData(ctxID: int, ctxCounter: int, ctxCounterExt: int) {
184184

185185
Remember to:
186186
1. Remove the global variables `ctx_id` and `ctx_counter`
187-
2. Update function usage by copying storage members locally as shown:
187+
2. Update the function usage by copying storage members locally as shown:
188188

189189
<Tabs groupId="language">
190190
<TabItem value="FunC" label="FunC">

docs/v3/guidelines/quick-start/developing-smart-contracts/setup-environment.mdx

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Feedback from "@site/src/components/Feedback";
2+
import Button from '@site/src/components/button'
23

34
# Setup development environment
45

@@ -52,7 +53,7 @@ This will run an interactive script to create the project template. You can ente
5253

5354
1. **Project name**: `Example`
5455
2. **First contract name**: `HelloWorld`
55-
3. **Project template**: A **simple counter contract** in `FunC` or `Tact`
56+
3. **Project template**: a **simple counter contract** in `FunC`, `Tolk` or `Tact`
5657

5758
Finally, change your current directory to the generated project template folder and install all required dependencies:
5859

@@ -61,10 +62,35 @@ cd ./Example
6162
npm install
6263
```
6364

64-
### Step 4 (Optional): IDE and editor support
65+
### Step 4 (optional): IDE and editor support
6566

6667
The TON community has developed plugins that provide syntax support for several IDEs and code editors. You can find them here: [Plugin List](https://docs.ton.org/v3/documentation/smart-contracts/getting-started/ide-plugins/).
6768

6869
Also, consider installing plugins that support **JavaScript/TypeScript** tools for your preferred IDE or code editor, specifically `Jest`, for debugging smart contract tests.
6970

71+
72+
73+
## Choose the programming language
74+
75+
Now that your environment is set up choose a programming language to get started:
76+
77+
- **FunC or Tolk**: estimated time to learn is 40 min for each.
78+
- **Tact**: estimated time to learn is XX min.
79+
80+
81+
<Button href="v3/guidelines/quick-start/developing-smart-contracts/func-tolk-folder/blueprint-sdk-overview" colorType="primary" sizeType={'sm'}>
82+
Start with FunC or Tolk
83+
84+
</Button>
85+
86+
87+
<Button href="v3/guidelines/quick-start/developing-smart-contracts/tact-folder/tact-blueprint-sdk-overview" colorType={'secondary'} sizeType={'sm'}>
88+
89+
Start with Tact
90+
91+
</Button>
92+
93+
94+
95+
7096
<Feedback />
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import Feedback from "@site/src/components/Feedback";
2+
import Tabs from '@theme/Tabs';
3+
import TabItem from '@theme/TabItem';
4+
5+
# Blueprint SDK overview
6+
7+
> **Summary:** In the previous steps, we installed and configured all the tools required for TON smart contract development and created our first project template.
8+
9+
Before we proceed to actual smart contract development, let's briefly describe the project structure and explain how to use the **`Blueprint SDK`**.
10+
11+
## Project structure
12+
13+
:::warning
14+
If you didn't choose the proposed names in the previous steps, source code file names and some of the in-code entities may differ.
15+
:::
16+
17+
<Tabs groupId="language">
18+
<TabItem value="FunC" label="FunC">
19+
```ls title="Project structure"
20+
Example/
21+
├── contracts/ # Folder containing smart contracts code
22+
│ ├── imports/ # Library imports for contracts
23+
│ │ └── stdlib.fc # Standard library for FunC
24+
│ └── hello_world.fc # Main contract file
25+
├── scripts/ # Deployment and on-chain interaction scripts
26+
│ ├── deployHelloWorld.ts # Script to deploy the contract
27+
│ └── incrementHelloWorld.ts # Script to interact with the contract
28+
├── tests/ # Test folder for local contract testing
29+
│ └── HelloWorld.spec.ts # Test specifications for the contract
30+
└── wrappers/ # TypeScript wrappers for contract interaction
31+
├── HelloWorld.ts # Wrapper class for smart contract
32+
└── HelloWorld.compile.ts # Script for contract compilation
33+
```
34+
</TabItem>
35+
<TabItem value="Tolk" label="Tolk">
36+
```ls title="Project structure"
37+
Example/
38+
├── contracts/ # Folder containing smart contracts code
39+
│ └── hello_world.tolk # Main contract file
40+
├── scripts/ # Deployment and on-chain interaction scripts
41+
│ ├── deployHelloWorld.ts # Script to deploy the contract
42+
│ └── incrementHelloWorld.ts # Script to interact with the contract
43+
├── tests/ # Test fo der for local contract testing
44+
│ └── HelloWorld.spec.ts # Test specifications for the contract
45+
└── wrappers/ # TypeScript wrappers for contract interaction
46+
├── HelloWorld.ts # Wrapper class for smart contract
47+
└── HelloWorld.compile.ts # Script for contract compilation
48+
```
49+
</TabItem>
50+
</Tabs>
51+
52+
### `/contracts`
53+
54+
This folder contains your smart contract source code written in one of the available programming languages used for TON Blockchain smart contract development.
55+
56+
### `/wrappers`
57+
58+
To interact with your smart contract off-chain, you need to serialize and deserialize messages sent to it. `Wrapper` classes are developed to mirror your smart contract implementation, making its functionality simple to use.
59+
60+
### `/tests`
61+
62+
This directory contains test files for your smart contracts. Testing contracts directly on the TON network is not the best option because deployment requires some amount of time and may lead to losing funds. This testing playground allows you to execute multiple smart contracts and even send messages between them in your **"local network"**. Tests are crucial for ensuring your smart contracts behave as expected before deployment to the network.
63+
64+
### `/scripts`
65+
66+
The `scripts` directory contains `TypeScript` files that help you deploy and interact with your smart contracts on-chain using previously implemented wrappers.
67+
68+
## Development flow
69+
70+
Almost any smart contract project development consists of five simple steps:
71+
72+
1. Edit the smart contract code in the `/contracts` folder and build it by running the build script:
73+
74+
```bash
75+
npx blueprint build
76+
```
77+
78+
2. Update the smart contract wrapper in the `/wrappers` folder to correspond to changes in the contract.
79+
80+
3. Update tests in the `/tests` folder to ensure the correctness of the new functionality and run the test script:
81+
82+
```bash
83+
npx blueprint test
84+
```
85+
86+
4. Repeat steps 1-3 until you achieve the desired result.
87+
88+
5. Update the deployment script in the `/scripts` folder and run it using this command:
89+
90+
```bash
91+
npx blueprint run
92+
```
93+
94+
:::tip
95+
All examples in this guide follow the sequence of these **1-3 steps** with corresponding code samples. **Step 5**, the deployment process, is covered in the last section of the guide: [Deploying to network](/v3/guidelines/quick-start/developing-smart-contracts/deploying-to-network/).
96+
:::
97+
98+
Also, you can always generate the same structure for another smart contract if, for example, you want to create multiple contracts interacting with each other by using the following command:
99+
100+
```bash
101+
npx blueprint create PascalCase # Don't forget to name the contract in PascalCase
102+
```
103+
104+
<Feedback />

0 commit comments

Comments
 (0)