TLDR: For external messages to wallets, don't set the +16 flag, instead set the +2 flag.
The meaning of +16 flag: If there was an error in processing the action, bounce the message in addition to rolling back the transaction. This has no use in external messages, because there is no sender to receive the bounced message.
The meaning of +2 flag: If there was an error in processing the action, don't rollback the transaction and ignore it. This is very important in external messages to wal...
Hex digit 0xF
has the binary representation 1111
. Anything that is &
with it will remain the same.
Hex digit 0x7
has this binary representation: 0111
. Anything that is &
with it will lost the first bit, or the first bit becomes zero.
In your first example, 0x5... & 0x7...
remains 0x5...
because 5
has binary represenation 0101
and the first bit is already 0
.
In your second example, 0x8... & 0x7...
changed to 0x0...
because 8
has binary representation 1000
...
Newer versions of FunC compiler added support for const
, so in newly written code, you may use this feature, or use the old approach. Both are supported.
The const
way of defining a constant is similar to other programming languages, so it can make your code easier to understand for readers.
Send any amount from your wallet.
You don't need to worry about it bein inactive. The first time that you send an outgoing transaction, your wallet software will deploy your wallet on chain and then sends the specified amount from it.
The CS{Cell{...} bits: 0..267; refs: 0..0}
is the string representation of a slice. A slice is a structure for reading a cell.
In your example, depending on the context, 2 different cells where returned and converted to slices. The first one has 267 bits, and the second has 268 bits, but also starts from bit 1.
That is, even though these cells are different, because slices are starting at different indexes, they represent the same thing at the end, and as you said, after parsing them ...
Your transfer happens on mainnet, and will be sent to the address you specified. What happens will depend on a few factors:
-
If you (or your wallet) disable
bounce
flag, the TON amount will be sent and will remain at the recipient's account. -
If you (or your wallet) keep the
bounce
flag, then it depends on the recipient account:A. If there is no smart contract at the destination, it will bounce back.
B. If there is a smart contract, it will depend on its behavior, and ...
Yes, it's supported, and your code is valid. enough?
will be an integer, with value -1
.
There is a page on ton.org that presents some best practices for optimizing gas:
Finding the length of a lisp-style list is a manual process. You have to traverse the list. As such, it most likely doesn't worth it in a smart contract context, so it's better to keep a separate counter variable, whenever you're going to need to use length.
false
is zero. true
is -1
. All other non-zero integers are also like a boolean true
.
Validators create a new keypair for each round of validation, and use that to participate in elections and create blocks. They may also change their ADNL address on each round, but that's not what they usually do.
If you want to look at their wallets on TON blockchain explorers, you have to first find the controlling wallet, that is the wallet that sends TON to participate in elections.
This information can be looked up by running the get method participant_list_extended
and it only r...
The Elector smart contract:
https://github.com/ton-blockchain/ton/blob/040df63c9864f2f37ebe50c4cafcc01f2d5d2d5c/crypto/smartcont/elector-code.fc#L431-L457
hTON liquid staking protocol (disclosure: I'm the author):
https://github.com/HipoFinance/contract/blob/612e27fef6b641edfcc562ac9561c565ada8603d/contracts/treasury.fc#L1799-L1842
Looks like it is removed to force developers to use equal_slice_bits
function. This function name is better in that it highlights the fact that only bits are compared and not references.
This is the old definition of both:
;;; Checks whether the data parts of two slices coinside
int equal_slice_bits(slice a, slice b) asm "SDEQ";
int equal_slices(slice a, slice b) asm "SDEQ";
So these were both equal functions.
Gas prices are calculated by looking at config params 20 (for masterchain) and 21 (for basechain). As long as they are the same, the calculated gas fees will be the same.
I checked it and currently on the basechain they're equal, but on the masterchain, they're not.
Also storage fees are dependent on the runtime state of each account, so they'll surely be different, although usually it's a very small fee.
There is also a forward fee which might differ depending on the blockchain conf...
When you create a smart contract on TON (such as a wallet), its address is pre-calculated, even before being deployed. You can start sending it money and messages, and if the sent messages are non-bounceable, the balance of the account on-chain will be increased. In this case, you will see the account is still uninitialized and not activated, but it has a positive TON balance.
To activate it, you have to deploy the smart contract. If this is a wallet smart contract, it will automatically g...
You can do it, and it probably helps your smart contract to consume less gas, however, it makes it more difficult to read it and check it for security reasons, and also makes maintenance of it harder.
I guess it doesn't worth it to save some gas in the TON ecosystem, because gas prices are fixed, and they're very cheap.
Use at
, a built-int function:
Address that start with EQ are bounceable addresses, and those that start with UQ are non-bounceable addresses. These are only a hint to the wallet software that you want the sent message to be able to bounce or not.
When an error occurs in the target smart contract, usually a bounced message will return to the sender. In some cases you don't want the error message to be generated and also you don't want the transferred TON to be returned.
One such case is when you want to deploy a smar...
TON configuration is the data for the Configuration smart contract. When an election is held and the vote to change a configuration is in support of the change, the config smart contract automatically changes the configuration data.
There is no need for any action from node owners. However, they might need to update their software from time to time, before an election is held which relies on the updates software.
Consider using TON Payments to minimize fees for lots of transactions:
You can use Sandbox to deploy multiple smart contracts and do the integration test.
Dicts
Dicts can be used to store a map of keys to values. However, in TON, it's recommended to avoid storing unbounded dicts. That is dicts that grow dynamically as time passes. The use case that you described is a dynamic one. The reason to avoid it is that your storage grows, and as it grows you have to pay more and more to keep it on the blockchain.
To store a dynamic list, you have to break it into smaller parts. This is called sharding, and you can find more info about how to d...
In TON, smart contracts are executed inside TVM (TON Virtual Machine). TVM expects instructions in a specific binary format, available here:
https://ton.org/docs/learn/tvm-instructions/instructions
These binary instructions are like assembly code, and writing them by hand is very hard. At the beginning Fift was created as a scripting language to make it easier to write smart contract codes. It has a special syntax and working with it is easier than TVM instructions, but it's still very ...
If you mean the current transaction time when transaction is being processed and accepted in a block, then you can use now()
in FunC.
I guess that's because of the way special characters like ?!:/
are accepted in variable and function names. If //
was used for single line comments then at the end of lines without a semicolon, you had to put a space before them, or else they'd be treated as part of an identifier's name.
Semicolon is not allowed in identifier names and so it can be used without a problem as single line comments.
dton.io shows some stats on its homepage, including transactions per second.
Yes, the data should fit in the c4
register. c4
is limited to a depth of <= 512
. Read more here:
https://ton.org/docs/learn/tvm-instructions/tvm-overview
If you use cells in a linear single ref tree, you are limited to 512 * 1023 = 523776
bits or near 64 KB. But if you use all cells to store data, it's a very huge tree with a lot of space. Only at the bottom layer it has 4 ** 511
cells.
Sometimes, exchanges create a single wallet account, and use it to receive transfers of all their users. They need a way to distinguish between different users, and know who sent what fund to credit the correct account on their database. Memo is used here, and they assign a separate number to each user and ask them to use it when they transfer funds. Then they use this number to find the owner.
The other approach is to create a separate wallet for each user. This way, there is no need for ...
Regular wallets can send up to 4 transactions in each request. Since they need to sign seq_no
, this limits them to 4 transactions every 5 seconds or so. If you need more bandwidth, for example a thousand transaction or more, you may use a highload wallet.
Regular wallets can send at most 4 transactions at once, and they need to sign the current seq_no
. This in effect limits them to 4 transactions every 5 second, and this operation need to be serialized, meaning that there needs to be a single service sending these 4 transactions.
Highload wallets can send up to 254 transactions in a single request, and they don't need a seq_no
. This way, they can send many transactions, multiple times without needing to wait between each batch, and ther...