📚Lecture Notes
На этом уроке мы рассмотрим смарт-контракт кошелька. Как вы помните, смарт-контракт кошелька развертывается смарт-контрактом minter, как только мы чеканим Jettons. Или смарт-контракт кошелька развертывается другим смарт-контрактом кошелька при переводе. Итак, опять же, у нас есть определенные приготовления:
Таким образом, код хранится в виде ячейки, и мы просто помещаем его сюда. По сути, это хороший пример первоначальных данных контракта после того, как этот контракт кошелька будет выполнен в первый раз. Какая у нас здесь функциональность? У нас есть функция send_tokens, функция receive_tokens, функция burn_tokens, on_bounce, и все это определено нами. Это не стандарт. recv_internal является основным, и здесь мы видим стандартную вещь.
Итак, как только код операции, который приходит с сообщением, соответствует коду операции передачи, или внутренней передаче, или записи, мы запускаем те функции, которые мы только что обсудили:
Здесь у нас есть пять основных вещей, которые мы должны рассмотреть. Одна из них - подготовка здесь: что происходит, когда мы впервые видим in_msg_full и начинаем читать в нем? Поэтому мы выясняем, что с этим делать. Затем, основываясь на коде операции, мы рассматриваем передачу, а именно функцию send_tokens, которую мы обсуждали здесь. Затем мы рассмотрим функцию receive_tokens, также доступную здесь, и burn_tokens. Последнее, что нам нужно сделать, это метод получения, но он здесь самый простой. Итак, давайте начнем с логики here:
Опять же, мы не хотим работать с сообщениями, которые имеют пустое тело. Итак, мы начинаем читать in_msg_full, чтобы увидеть флаги. И опять же, мы обнаруживаем, говорит ли флаг, что это отскаканное сообщение. Теперь мы хотим справиться с этим, и мы собираемся рассмотреть это через минуту. Затем мы выясняем, что такое sender_address. Затем мы пропускаем некоторую информацию, потому что собираемся передать in_msg_body в соответствующие функции. Так что здесь нас это на самом деле не волнует.
Но дальше мы заботимся о fwd_fee. Здесь мы оцениваем, сколько было выплачено за предыдущую транзакцию, и теперь мы хотим знать эту сумму, чтобы фактически сохранить определенную сумму по контракту. Поэтому мы оцениваем, сколько это будет стоить для следующей транзакции. Это интересная логика, которую вы на самом деле должны изучить.
Вы уже знаете, как составить сообщение, как мы делали это в предыдущих главах с помощью send_draw_message. Вы уже знаете, что send_draw_message принимает ячейку со всеми этими параметрами. И именно поэтому мы можем прочитать это здесь, потому что эти параметры присутствуют в виде битов внутри этой ячейки сообщения.
Хорошо, так что дальше мы идем с кодами операций. К этому моменту мы уже выяснили границы, мы выяснили, сколько мы должны на самом деле сохранить для следующей транзакционной стоимости. А теперь мы перейдем к кодам операций. Итак, мы видим эти send_tokens и передаем in_msg_body. Мы передаем все, что приходит с телом - адрес отправителя, значение сообщения. Как вы помните, msg_value - это то, сколько денег пришло с этим сообщением. И fwd_fee - это оценка, это в основном точная сумма, которая была потрачена на пересылку до этого сообщения, и мы передаем ее в send_tokens.
Передача токенов
Давайте посмотрим:
Поэтому мы хотим убедиться, что sender_address является владельцем. Владелец - это какой-то контракт с реальным кошельком, контракт с реальным кошельком, который владеет этим контрактом на кошелек Jetton. Он сохраняется здесь, в хранилище. Мы хотим убедиться, что отправитель, который на самом деле отправляет нам это сообщение, имеет тот же адрес, что и тот, кто владеет этим кошельком.
Мы выбросим ошибку, если это не так. Затем мы проверяем, что баланс все еще больше или равен 0 после того, как мы уменьшили сумму Jetton.
Теперь мы начинаем готовить сообщение для отправки для развертывания этого контракта кошелька. Мы используем те же самые функции, что и Jetton utils Папка. Мы не углубляемся здесь, потому что вы уже понимаете, как это работает. Итак, мы рассчитываем state_init, выясняем адрес кошелька, куда мы собираемся отправить это сообщение. А затем мы читаем ответный_адрес. Таким образом, in_msg_body будет содержать, кто получает доступ, и уведомление о том, кто должен получить остальные данные после завершения этой последовательности транзакций. Затем мы можем поставить custom_payload, и мы выставим forward_ton_amount, чтобы мы знали, сколько TON мы должны поместить внутри этой транзакции.
Итак, мы начинаем составлять сообщение, чтобы отправить Jettons. У того, кому мы хотим отправить Jettons, может не быть контракта с кошельком Jetton. Вот почему нам нужно прикрепить state_init к этому сообщению: мы собираемся развернуть контракт, если у него его нет.
Таким образом, у нас есть те же ярлыки на флагах в начале. Пункт назначения идет дальше. Мы не ставим никаких монет только сейчас, потому что мы сделаем это, когда собираемся отправить их. А затем мы сочиняем все эти функции - что-то еще не работает, что-то будет переписано валидаторами. А затем, после ядра сообщения вы составляете тело сообщения.
Вот кое-что интересное, с чем вы раньше не встречались. На самом деле мы можем продолжить этот код, потому что мы не закончили ячейку в var msg. Мы можем продолжать вкладывать определенные вещи в эту ячейку.
Теперь мы начинаем готовить сообщение для отправки для развертывания этого контракта кошелька. Мы используем те же самые функции, что и у сферы. Мы помещаем query_id, jetton_amount, owner_address, response_address, сколько TON нужно переслать и возможную полезную нагрузку, которая останется в in_msg_body, возможно.
Хорошо, так что давайте перейдем к fwd_count. Здесь мы проверяем, что после того, как мы выполним эту транзакцию, в нашем контракте все еще достаточно денег, чтобы выжить. И только в этот момент мы заканчиваем ячейку сообщения и отправляем это сообщение. Снова с 64, мы передаем средства, которые пришли с этим сообщением. Вы должны узнать больше об этом режиме и флагах в документации, мы уже говорили об этом. И, конечно, вы сохраняете новые данные, новый баланс после того, как мы сделали все эти манипуляции.
Отлично, это функция передачи. Эта функция будет вызываться основным кошельком. Например, у вас есть обычный кошелек, например, на Tonhub или Tonkeeper. И этот контракт кошелька запустит send_tokens. Или может быть какая-то другая логика. Но вы должны быть владельцем этого контракта кошелька Jetton, чтобы иметь возможность запустить операцию send_tokens.
Получение токенов
Следующий получает токены:
Вот как вы получаете токены. Опять же, вы читаете все данные из хранилища. Мы увеливаем баланс. Мы проверяем, что тот, кто прислал нам Jettons, отправил эту информацию об увеличении баланса, является либо генеральным контрактом, либо каким-то другим контрактом кошелька Jetton. А затем мы читаем forward_ton_amount, чтобы убедиться, что у нас достаточно денег, чтобы остаться по контракту. В случае, если есть forward_ton_amount, мы составим это новое сообщение с forward_ton_amount и forward_payload, если оно действительно доступно там. Конечно, нам нужно отправить доступы на случай, если они там присутствуют. Вот почему мы составляем сообщение об отправке всех доступов, оставшихся в этой цепочке транзакций, на адрес ответа, если он указан. Затем мы сохраняем новые данные здесь. Что бы ни изменилось, это изменит только баланс. Отлично. Так вот как мы обрабатываем получение токенов.
Сжигание токенов
Осталось еще два: как мы на самом деле их сжигаем и как это сделать on_bouce. Видите ли, мы не углубляемся в каждую строку и логическую ячейку, которую мы сочиняем, потому что нам потребуется несколько часов, чтобы обзорить это. Я хочу, чтобы вы поняли логику на более высоком уровне. Мы могли бы сделать главу для каждого из этих контрактов, чтобы выяснить каждый логический случай, который может быть обработан здесь. Но я хочу, чтобы вы понимали логику высокого уровня, потому что вы не собираетесь создавать эти контракты самостоятельно.
Вам просто нужно понять, как они работают, чтобы на самом деле использовать эти функции, потому что большинство контрактов Jetton используют их. И вы будете знать, как использовать их в своих случаях.
В основном, burn_tokens для уменьшения. Мы читаем данные, получаем query_id, количество монет для сжигания, кому отправить ответ, а затем уменьшаем баланс. Итак, мы проверяем, является ли отправитель владельцем, если баланс все еще больше 0. Мы следим за тем, чтобы суммы денег, которая поставляется с ним, достаточно, сам контракт сохранится после того, как мы отправим эту транзакцию и сможем оплатить аренду. Затем мы составляем уведомление о сжигании, точно так же, как мы его просмотрели.
Итак, здесь у нас есть burn_notification. Мы отправляем burn_notification в качестве тела сообщения генеральному контракту. Мы ставим сумму, владельца, ответ. Вы помните, что в качестве ответа мы также внедрили, кому отправить ответ, верно? На самом деле мы составили ячейку сообщения. Здесь мы помещаем тело сообщения и отправляем необработанное сообщение с этой информацией и телом сообщения. А потом мы просто отправляем save_data, потому что баланс изменился.
Отскок
Последнее, что мы собираемся рассмотреть в этом уроке, это on_bounce:
Что мы делаем, когда сообщение на самом деле отбрасывается? Он будет отскакивать с определенной ошибкой, поэтому мы прочитаем наш баланс и проверим, что код операции является либо сообщениями bounce internal_transfer, либо burn_notification. Если это один из них, нам придется вернуть количество Jettons, которые не были приняты другим контрактом, в наш контракт.
Заключение
Так что это основная логика контракта на кошелек Jetton. Надеюсь, это тебя не смущает. Это отличный пример для вас, чтобы на самом деле прочитать код и увидеть, насколько он может быть сложным. Это очень поможет вам, если вы потратите некоторое время на чтение этих контрактов. Если вы не понимаете определенные вещи, такие как строки или биты в ячейках, вы можете легко писать текст в группах или читать документацию. Цель этого урока заключалась в том, чтобы дать вам более высокий обзор того, как он работает с Jettons, чтобы вы могли понять эту логику с различными контрактами, взаимодействующими друг с другом вместе со стандартом.
В следующем уроке мы более подробно изучим другой тип токена, который называется невзаимозаменяемым токеном (NFT). Это будет интересно для вас, потому что у нас там есть контракты на взыскание, контракты на товары. Вы уже прошли эту очень сложную часть, и теперь вы понимаете, что может быть несколько контрактов. Jetton - это не один контракт, это система контрактов.
А с NFT вам также будет очень интересно посмотреть, как они работают под капотом в соответствии со стандартом. Так что увидимся очень скоро!