Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update documentation according to FunC v0.5.0 #631

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
4 changes: 2 additions & 2 deletions docs/contribute/tutorials/sample-tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Any technology that needs to be installed **prior** to starting the tutorial and
- \```javascript *or* ```js can be used for any JavaScript code.
- \```typescript or ```ts can be used for any TypeScript code.
- \```jsx is for ReactJS code.
- \```cpp is for Func code.
- \```func is for FunC code.
- Use \```graphql when highlighting GraphQL syntax.
- Use \```json when highlighting valid JSON. (For invalid JSON examples use \```text instead.)
- \```bash should *only* be used in code blocks where you need to have # style comments. This must be done carefully because in many situations the # character will render as a markdown heading. Typically, the Table of Contents will be affected if this occurs.
Expand Down Expand Up @@ -117,4 +117,4 @@ This section ***must*** be present if you have taken any help in writing this tu

Credit sources by adding their name and a link to the document when possible.

If it is not a digital document, include an ISBN or other form of reference.
If it is not a digital document, include an ISBN or other form of reference.
34 changes: 17 additions & 17 deletions docs/develop/dapps/asset-processing/nfts.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Because each NFT makes use of its own smart contract, it is not possible to obta
### NFT Collections
NFT Collection is a contract that serves to index and store NFT content and should contain the following interfaces:
#### Get method `get_collection_data`
```
```func
(int next_item_index, cell collection_content, slice owner_address) get_collection_data()
```
Retrieves general information about collection, which represented with the following:
Expand All @@ -28,13 +28,13 @@ Retrieves general information about collection, which represented with the follo
3. `owner_address` - a slice that contains the collection owner's address (this value can also be empty).

#### Get method `get_nft_address_by_index`
```
```func
(slice nft_address) get_nft_address_by_index(int index)
```
This method can be used to verify the authenticity of an NFT and confirm whether it truly belongs to a specific collection. It also enables users to retrieve the address of an NFT by providing its index in the collection. The method should return a slice containing the address of the NFT that corresponds to the provided index.

#### Get method `get_nft_content`
```
```func
(cell full_content) get_nft_content(int index, cell individual_content)
```
Since the collection serves as a common data storage for NFTs, this method is necessary to complete the NFT content. To use this method, first, it’s necessary to obtain the NFT’s `individual_content` by calling the corresponding `get_nft_data()` method. After obtaining the `individual_content`, it’s possible to call the `get_nft_content()` method with the NFT index and the `individual_content` cell. The method should return a TEP-64 cell containing the full content of the NFT.
Expand All @@ -43,12 +43,12 @@ Since the collection serves as a common data storage for NFTs, this method is ne
Basic NFTs should implement:

#### Get method `get_nft_data()`
```
```func
(int init?, int index, slice collection_address, slice owner_address, cell individual_content) get_nft_data()
```

#### Inline message handler for `transfer`
```
```tlb
transfer#5fcc3d14 query_id:uint64 new_owner:MsgAddress response_destination:MsgAddress custom_payload:(Maybe ^Cell) forward_amount:(VarUInteger 16) forward_payload:(Either Cell ^Cell) = InternalMsgBody
```
Let's look at each parameter you need to fill in your message:
Expand Down Expand Up @@ -182,19 +182,19 @@ Now that we’ve covered the basics of sending and receiving NFTs, let’s explo

In this example, the NFT transfer message is found on [line 67](https://www.google.com/url?q=https://github.com/ton-blockchain/token-contract/blob/1ad314a98d20b41241d5329e1786fc894ad811de/nft/nft-sale.fc%23L67&sa=D&source=docs&ust=1685436161341866&usg=AOvVaw1yuoIzcbEuvqMS4xQMqfXE):

```
```func
var nft_msg = begin_cell()
.store_uint(0x18, 6)
.store_slice(nft_address)
.store_coins(0)
.store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) ;; default message headers (see sending messages page)
.store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) // default message headers (see sending messages page)
.store_uint(op::transfer(), 32)
.store_uint(query_id, 64)
.store_slice(sender_address) ;; new_owner_address
.store_slice(sender_address) ;; response_address
.store_int(0, 1) ;; empty custom_payload
.store_coins(0) ;; forward amount to new_owner_address
.store_int(0, 1); ;; empty forward_payload
.store_slice(sender_address) // new_owner_address
.store_slice(sender_address) // response_address
.store_int(0, 1) // empty custom_payload
.store_coins(0) // forward amount to new_owner_address
.store_int(0, 1); // empty forward_payload


send_raw_message(nft_msg.end_cell(), 128 + 32);
Expand All @@ -206,20 +206,20 @@ Let's examine each line of code:
- `store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1)` - the remaining components that make up the message header are left empty.
- `store_uint(op::transfer(), 32)` - this is the start of the msg_body. Here we start by using the transfer OP code so the receiver understands its transfer ownership message.
- `store_uint(query_id, 64)` - store query_id
- `store_slice(sender_address) ;; new_owner_address` - the first stored address is the address used for transferring NFTs and sending notifications.
- `store_slice(sender_address) ;; response_address` - the second stored address is a response address.
- `store_slice(sender_address) // new_owner_address` - the first stored address is the address used for transferring NFTs and sending notifications.
- `store_slice(sender_address) // response_address` - the second stored address is a response address.
- `store_int(0, 1)` - the custom payload flag is set to 0, indicating there is no custom payload required.
- `store_coins(0)` - amount of TON to be forwarded with the message. In this example it’s set to 0, however, it is recommended to set this value to a higher amount (such as at least 0.01 TON) in order to create a forward message and notify the new owner that they have received the NFT. The amount should be sufficient to cover any associated fees and costs.
- `.store_int(0, 1)` - custom payload flag. It's necessary to set up to `1` if your service should pass payload as a ref.

### Receiving NFTs
Once we've sent the NFT, it is critical to determine when it has been received by the new owner. A good example of how to do this can be found in the same NFT sale smart contract:

```
```func
slice cs = in_msg_full.begin_parse();
int flags = cs~load_uint(4);

if (flags & 1) { ;; ignore all bounced messages
if (flags & 1) { // ignore all bounced messages
return ();
}
slice sender_address = cs~load_msg_addr();
Expand All @@ -233,7 +233,7 @@ Let's again examine each line of code:

- `slice cs = in_msg_full.begin_parse();` - used to parse the incoming message.
- `int flags = cs~load_uint(4);` - used to load flags from the first 4 bits of the message.
- `if (flags & 1) { return (); } ;; ignore all bounced messages` - used to verify that the message has not bounced. It’s important to carry out this process for all your incoming messages if there is no reason to do otherwise. Bounced messages are messages that encountered errors while trying to receive a transaction and were returned to the sender.
- `if (flags & 1) { return (); } // ignore all bounced messages` - used to verify that the message has not bounced. It’s important to carry out this process for all your incoming messages if there is no reason to do otherwise. Bounced messages are messages that encountered errors while trying to receive a transaction and were returned to the sender.
- `slice sender_address = cs~load_msg_addr();` - next the message sender is loaded. In this case specifically by using an NFT address.
- `throw_unless(500, equal_slices(sender_address, nft_address));` - used to verify that the sender is indeed an NFT that should have been transferred via a contract. It's quite difficult to parse NFT data from smart contracts, so in most cases the NFT address is predefined at contract creation.
- `int op = in_msg_body~load_uint(32);` - loads message OP code.
Expand Down
14 changes: 7 additions & 7 deletions docs/develop/dapps/tutorials/simple-zk-on-ton.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ The above lines are the new [TVM opcodes](https://docs.ton.org/learn/tvm-instruc
The load_data and save_data functions are simply used to load and save the proof verification results (only for test purposes).

```func
() load_data() impure {
() load_data() {

var ds = get_data().begin_parse();

Expand All @@ -255,7 +255,7 @@ The load_data and save_data functions are simply used to load and save the proof
ds.end_parse();
}

() save_data() impure {
() save_data() {
set_data(
begin_cell()
.store_uint(ctx_res, 32)
Expand All @@ -266,15 +266,15 @@ The load_data and save_data functions are simply used to load and save the proof

Next there are several simple util functions that are used to load the proof data sent to the contract:
```func
(slice, slice) load_p1(slice body) impure {
(slice, slice) load_p1(slice body) {
...
}

(slice, slice) load_p2(slice body) impure {
(slice, slice) load_p2(slice body) {
...
}

(slice, int) load_newint(slice body) impure {
(slice, int) load_newint(slice body) {
...
}
```
Expand All @@ -288,7 +288,7 @@ And the last part is the groth16Verify function which is required to check the v

int pubInput0

) impure {
) {

slice cpub = bls_g1_multiexp(

Expand All @@ -306,7 +306,7 @@ And the last part is the groth16Verify function which is required to check the v
pi_c, vk_delta_2,
vk_alpha_1, vk_beta_2,
4);
;; ctx_res = a;
// ctx_res = a;
if (a == 0) {
ctx_res = 0;
} else {
Expand Down
12 changes: 6 additions & 6 deletions docs/develop/data-formats/library-cells.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ You can consider library cell as C++ pointer: one small cell that points to larg

Library cell is [exotic cell](/develop/data-formats/exotic-cells) that contains a reference to some other static cell. In particular it contains 256 bit of hash of referenced cell.

For TVM, library cells works as follows: whenever TVM receives a command to open a cell to a slice (TVM Instruction: `CTOS`, funC method: `.begin_parse()`), it searches cell with the corresponding hash from library cell in the Masterchain library context. If found it, it opens referenced cell and returns its slice.
For TVM, library cells works as follows: whenever TVM receives a command to open a cell to a slice (TVM Instruction: `CTOS`, FunC method: `.begin_parse()`), it searches cell with the corresponding hash from library cell in the Masterchain library context. If found it, it opens referenced cell and returns its slice.

Opening library cell costs the same as opening ordinar cell, so it can be used as transparent replacement for static cells that however occupy much less space (and thus costs less fees for storage and sending).

Expand All @@ -50,11 +50,11 @@ Basically you need to put tag and hash to the builder and then "close builder as

It can be done in Fift-asm construction like [this](https://github.com/ton-blockchain/multisig-contract-v2/blob/master/contracts/auto/order_code.func), example of compilation some contract directly to library cell [here](https://github.com/ton-blockchain/multisig-contract-v2/blob/master/wrappers/Order.compile.ts).

```fift
;; https://docs.ton.org/tvm.pdf, page 30
;; Library reference cell — Always has level 0, and contains 8+256 data bits, including its 8-bit type integer 2
;; and the representation hash Hash(c) of the library cell being referred to. When loaded, a library
;; reference cell may be transparently replaced by the cell it refers to, if found in the current library context.
```func
// https://docs.ton.org/tvm.pdf, page 30
// Library reference cell — Always has level 0, and contains 8+256 data bits, including its 8-bit type integer 2
// and the representation hash Hash(c) of the library cell being referred to. When loaded, a library
// reference cell may be transparently replaced by the cell it refers to, if found in the current library context.

cell order_code() asm "<b 2 8 u, 0x6305a8061c856c2ccf05dcb0df5815c71475870567cab5f049e340bcf59251f3 256 u, b>spec PUSHREF";
```
Expand Down
26 changes: 13 additions & 13 deletions docs/develop/data-formats/msg-tlb.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -340,29 +340,29 @@ var_int$_ {n:#} len:(#< n) value:(int (len * 8))

## Message example

### Regular func internal message
### Regular FunC internal message

```func
var msg = begin_cell()
.store_uint(0, 1) ;; tag
.store_uint(1, 1) ;; ihr_disabled
.store_uint(1, 1) ;; allow bounces
.store_uint(0, 1) ;; not bounced itself
.store_uint(0, 1) // tag
.store_uint(1, 1) // ihr_disabled
.store_uint(1, 1) // allow bounces
.store_uint(0, 1) // not bounced itself
.store_slice(source)
.store_slice(destination)
;; serialize CurrencyCollection (see below)
// serialize CurrencyCollection (see below)
.store_coins(amount)
.store_dict(extra_currencies)
.store_coins(0) ;; ihr_fee
.store_coins(fwd_value) ;; fwd_fee
.store_uint(cur_lt(), 64) ;; lt of transaction
.store_uint(now(), 32) ;; unixtime of transaction
.store_uint(0, 1) ;; no init-field flag (Maybe)
.store_uint(0, 1) ;; inplace message body flag (Either)
.store_coins(0) // ihr_fee
.store_coins(fwd_value) // fwd_fee
.store_uint(cur_lt(), 64) // lt of transaction
.store_uint(now(), 32) // unixtime of transaction
.store_uint(0, 1) // no init-field flag (Maybe)
.store_uint(0, 1) // inplace message body flag (Either)
.store_slice(msg_body)
.end_cell();
```
### Regular func message in short form
### Regular FunC message in short form

Message parts that are always overwritten by validators could be skipped(fill with zero bits). Message's sender here skipped too, serialized as `addr_none$00`.

Expand Down
20 changes: 10 additions & 10 deletions docs/develop/fift/fift-and-tvm-assembly.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Fift is stack-based programming language that has TON-specific features and ther

Fift is executed **at compile-time** - when your compiler builds smart-contract code BOC, after FunC code is processed. Fift can look differently:

```
```fift
// tuple primitives
x{6F0} @Defop(4u) TUPLE
x{6F00} @Defop NIL
Expand All @@ -15,7 +15,7 @@ x{6F02} dup @Defop PAIR @Defop CONS
```
> TVM opcode definitions in Asm.fif

```
```fift
"Asm.fif" include
<{ SETCP0 DUP IFNOTRET // return if recv_internal
DUP 85143 INT EQUAL OVER 78748 INT EQUAL OR IFJMP:<{ // "seqno" and "get_public_key" get-methods
Expand Down Expand Up @@ -66,12 +66,12 @@ contract:
```

Put the BOC in `fift/blob.boc`, then add the following code to `fift/blob.fif`:
```
```fift
<b 8 4 u, 8 4 u, "fift/blob.boc" file>B B>boc ref, b> <s @Defop LDBLOB
```

Now, you're able to extract this blob from smart contract:
```
```func
cell load_blob() asm "LDBLOB";

() recv_internal() {
Expand All @@ -82,11 +82,11 @@ cell load_blob() asm "LDBLOB";
### [TVM assembly] - Converting integer to string

"Sadly", int-to-string conversion attempt using Fift primitives fails.
```
```func
slice int_to_string(int x) asm "(.) $>s PUSHSLICE";
```
The reason is obvious: Fift is doing calculations in compile-time, where no `x` is yet available for conversion. To convert non-constant integer to string slice, you need TVM assembly. For example, this is code by one of TON Smart Challenge 3 participants':
```
```func
tuple digitize_number(int value)
asm "NIL WHILE:<{ OVER }>DO<{ SWAP TEN DIVMOD s1 s2 XCHG TPUSH }> NIP";

Expand All @@ -106,16 +106,16 @@ builder store_signed(builder msg, int v) inline_ref {

### [TVM assembly] - Cheap modulo multiplication

```
int mul_mod(int a, int b, int m) inline_ref { ;; 1232 gas units
```func
int mul_mod(int a, int b, int m) inline_ref { // 1232 gas units
(_, int r) = muldivmod(a % m, b % m, m);
return r;
}
int mul_mod_better(int a, int b, int m) inline_ref { ;; 1110 gas units
int mul_mod_better(int a, int b, int m) inline_ref { // 1110 gas units
(_, int r) = muldivmod(a, b, m);
return r;
}
int mul_mod_best(int a, int b, int m) asm "x{A988} s,"; ;; 65 gas units
int mul_mod_best(int a, int b, int m) asm "x{A988} s,"; // 65 gas units
```

`x{A988}` is opcode formatted according to [5.2 Division](/learn/tvm-instructions/instructions#52-division): division with pre-multiplication, where the only returned result is remainder modulo third argument. But opcode needs to get into smart-contract code - that's what `s,` does: it stores slice on top of stack into builder slightly below.
24 changes: 0 additions & 24 deletions docs/develop/func/builtins.md

This file was deleted.

Loading
Loading