Как отправить транзакцию с возможностью возврата? ИЛИ транзакция израсходовала весь баланс отправителя!
-
Как отправить ** возвратный** перевод native TON?
Согласно документации:
- https://docs.ton.org/develop/smart-contracts/tutorials/wallet * https://docs.ton.org/develop/smart-contracts/messages * https://docs.ton.org/develop/smart-contracts/guidelines/non-bouncable-messages
Для отправки отскакивающего перевода необходимо установить флаг
отскок
во внутреннем сообщении и использовать режим отправки+16
.+16 | В случае сбоя действия - транзакция с отказом
It is uninitialized wallet: https://testnet.tonviewer.com/EQAfs3mJctSyXlJpR89j6h1T7fYJ_nBt8hGbfkDUaET7x9p8
Пример кода:
import { WalletContractV4, TonClient, internal } from '@ton/ton'; const client = new TonClient({ endpoint: 'https://testnet.toncenter.com/api/v2/jsonRPC', }); const walletContract = client.open(wallet); const seqno = await walletContract.getSeqno(); const transfer = await walletContract.createTransfer({ secretKey: key.secretKey, seqno: seqno, sendMode: 16, messages: [ internal({ to: 'EQAfs3mJctSyXlJpR89j6h1T7fYJ_nBt8hGbfkDUaET7x9p8', value: 12345, bounce: true, // sender is fresh wallet so init it init: wallet.init, }) ], }); await walletContract.send(transfer);
Ожидаемое поведение
Сумма транзакции возвращается отправителю за вычетом комиссии
Настоящий бахавиур
Бесконечное количество попыток израсходовало весь баланс отправителя https://testnet.tonviewer.com/0QA3tr_6AZK9qMQy46a7ULtriizI7iXeiPufNxib4a7b6eU8
-
TLDR: Для внешних сообщений на кошельки не устанавливайте флаг +16, вместо этого установите флаг +2.
Значение флага +16: Если при обработке действия произошла ошибка, отсканируйте сообщение в дополнение к откату транзакции. Это бесполезно для внешних сообщений, поскольку нет отправителя, который мог бы получить отсканированное сообщение.
Значение флага +2: Если при обработке действия произошла ошибка, не откатывайте транзакцию и игнорируйте ее. Это очень важно во внешних сообщениях для кошельков.
Кошельки сначала проверяют подпись, и когда параметры верны, они ПРИНИМАЮТ сообщение, а затем пытаются обработать вводимые действия. Если какое-либо действие завершается неудачей и оно не игнорируется, транзакция будет отменена, но кошелек оплатит газ, поскольку он уже принял сообщение.
Поэтому очень важно не допустить сбоя после того, как сообщение будет ПРИНЯТО. Вот почему вы должны установить флаг +2 во внешних сообщениях для кошельков.