In FunC you can use string literals with a
tag. For example: "Ef8zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM0vF"a
More info: https://ton.org/docs/develop/func/literals_identifiers#string-literals
With a minor change, you can. In the while
loop, assign qRefs.store_ref
to qRefs
. In fact you don't need to keep references to the old builder. I would write it like this:
() save_data_on_update(slice destination_address) impure inline {
builder b = begin_cell();
b = b.store_slice(destination_address);
repeat (4) {
b = b.store_ref(begin_cell().store_uint(0, 1).end_cell());
}
cell c = b.end_cell();
set_data(c);
}
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.
You can use Sandbox to deploy multiple smart contracts and do the integration test.
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...
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...
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.
Consider using another solution like PaymentChannels:
https://github.com/ton-blockchain/payment-channels
This way you can move the costly operation off-chain, and you can open the channel once for each user.
It will log to standard output of TVM. The way you execute TVM, determines the way output is generated or logged. So you have to run TVM with your smart contract and the input message, and then check the debug log. For example, if you use ton-contract-executor
, it will be available in debugLogs
field of the result.
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...
Seqno is one way to prevent Replay Attacks. When a transaction is sent to a wallet smart contract, it compares the seqno field of the transaction with the one inside its storage. If they match, it's accepted and the stored seqno is incremented by one. If they don't match, the transaction is discarded.
Without seqno (or another mechanism to prevent Replay Attacks), anyone (usually the receiver of funds) can read the transaction data (for example from blockchain explorers) and create another...
Consider using TON Payments to minimize fees for lots of transactions:
You can use the ICO version of Jetton smart contract which is available here:
https://github.com/ton-blockchain/token-contract/blob/main/ft/jetton-minter-ICO.fc
You have to change the multiplier for your jetton. For example, multiplying to 1000, means that 1 TON equals 1000 of your jettons.
Then you can deploy it and anyone sending Toncoin to it, will receive your jettons.
Note that this is a template and you have to add additional functionality on top of it, like stopping it when i...
It depends on many factors.
-
You have included the
initState
(that is the code and data of the wallet or smart contract) alongside your transaction. In this case the smart contract is deployed first, and then it handles the incoming message. This is similar to sending the transaction to an initialized account. -
No
initState
, andbounce
flag is set. In this case, the message cannot be delivered to a smart contract and the message will be bounced back to the sender. After subtra...
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 ...
Inactive means the wallet is not initialized yet, meaning that the code for the smart contract of your wallet is not yet deployed on the network.
This is not problematic, and you can use your wallet to receive funds on the network without initializing it first. Multiple deposits can be sent to your wallet. However, to withdraw, you need to first deploy it, and wallet softwares do this automatically on first withdrawal.
In fact, many wallets are initialized after their first deposit!
...
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 ...
Start with reading and understanding wallet v3 code here:
https://github.com/ton-blockchain/ton/blob/master/crypto/smartcont/wallet3-code.fc
Then maybe check wallet v4:
https://github.com/ton-blockchain/wallet-contract/blob/main/func/wallet-v4-code.fc
Then you may read NFT Collection and Item implementation:
https://github.com/ton-blockchain/token-contract/blob/main/nft/nft-collection.fc
https://github.com/ton-blockchain/token-contract/blob/main/nft/nft-collection.fc
Finally, J...
There is no float
in FunC, and TVM in general. Floating point numbers are useful in scientific calculations. Because they don't have exact precision, they are usually not that useful in applications working with money.
TON amounts like 1.234567890 are stored as a big integer of nano tons like 1234567890 and when displayed to user, they are divided by 1 billion in client side applications, so the user can view a more friendly and understandable amount. Other monetary values like jettons u...
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.
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...
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...
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.
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
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...
There is a page on ton.org that presents some best practices for optimizing gas:
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
.
false
is zero. true
is -1
. All other non-zero integers are also like a boolean true
.