📚Lecture Notes
На этом уроке мы рассмотрим код элемента NFT, классического. Кроме того, мы узнаем о предмете SoulBound (SBT).
Договор о товаре NFT
Давайте откроем и рассмотрим contract.
int min_tons_for_storage() asm "50000000 PUSHINT"; ;; 0.05 TON
Как и в предыдущих уроках, мы видим, что есть определенные константы, которые показывают, какой минимум монет мы должны на самом деле хранить в контракте, чтобы иметь возможность платить за аренду.
(int, int, slice, slice, cell) load_data() {
slice ds = get_data().begin_parse();
var (index, collection_address) = (ds~load_uint(64), ds~load_msg_addr());
if (ds.slice_bits() > 0) {
return (-1, index, collection_address, ds~load_msg_addr(), ds~load_ref());
} else {
return (0, index, collection_address, null(), null()); ;; nft not initialized yet
}
}
Затем мы видим load_data. И эта load_data немного отличается от того, что мы видели раньше. Обычно мы просто читали данные из локального хранилища, но здесь у нас есть более сложная логика. Поэтому мы открываем ячейку локального хранилища для чтения, а затем читаем индекс и collection_address. Мы знаем, что такое индекс и адрес коллекции.
Затем мы пытаемся прочитать метаданные элемента NFT. Во-первых, мы проверяем, присутствует ли он там. Если да, мы возвращаем -1 вместе с адресом коллекции, адресом владельца и метаданными. Или мы просто возвращаем 0, индекс и адрес коллекции, когда нет ни владельца, ни метаданных.
Это означает, что NFT еще не инициализирован. Исходя из этого, мы примем некоторые решения позже в коде.
И здесь мы инкапсулируем логику отправки сообщения, чтобы мы могли использовать эту функцию в остальной части логики нашего контракта. Поэтому всякий раз, когда мы хотим отправить сообщение, мы можем просто использовать эту функцию. Он принимает адрес назначения, сумму, которую мы должны прикрепить, код операции, идентификатор запроса, возможную полезную нагрузку (на этот раз в формате конструктора) и режим отправки сообщения. Вот как мы формируем логику отправки сообщений.
Еще одна функция, которая у нас есть, - это transfer_ownership. Давайте посмотрим на это позже, как только перейдем к этому в логике recv_internal, потому что это самая важная функция здесь.
Посмотрим, что он делает. Опять же, мы игнорируем пустые сообщения in_msg_body, читаем флаги, игнорируем отбрасываемые сообщения и проверяем, кто является отправителем. Теперь мы пропускаем некоторые вещи, такие как адрес назначения сообщения и прочее, потому что вы уже знаете, каково содержимое этой ячейки. Затем у нас снова есть fwd_fee, чтобы оценить, сколько будет стоить отправка следующей транзакции на основе предыдущей транзакции.
Затем мы загружаем данные. Как вы помните, мы на самом деле загружаем данные так же, как и здесь. Поэтому мы проверяем, что он не инициализирован, затем мы ожидаем фактически получить эти данные, ожидаем, что in_msg_body будет иметь адрес владельца и ячейку с метаданными. Но это можно сделать только с помощью collection_address, поэтому мы проверяем, что он равен адресу отправителя. Затем мы можем инициализировать элемент NFT.
int op = in_msg_body~load_uint(32);
int query_id = in_msg_body~load_uint(64);
if (op == op::transfer()) {
transfer_ownership(my_balance, index, collection_address, owner_address, content, sender_address, query_id, in_msg_body, fwd_fee);
return ();
}
if (op == op::get_static_data()) {
send_msg(sender_address, 0, op::report_static_data(), query_id, begin_cell().store_uint(index, 256).store_slice(collection_address), 64); ;; carry all the remaining value of the inbound message
return ();
}
Далее у нас есть код операции, который может быть op::transfer или op::get_static_data. Это две возможные ценности, с которыми мы будем обращаться. Когда мы говорим get_static_data, мы немедленно отправляем сообщение тому, кто отправил запрос на статические данные. Мы просто сообщаем данные, поэтому отправляем ему индекс и collection_address. Это функция get_static_data. И, как вы видите, это наш первый пример использования send_ msg.
Для передачи права собственности у нас есть функция здесь. Во-первых, мы проверяем, что адрес владельца товара в настоящее время является тем, кто отправляет сообщение, потому что только он может передать право собственности. Затем мы зачитываем адрес нового владельца. Мы принуждаем_chain, чтобы убедиться, что он находится в той же цепочке. Затем мы проверяем, есть ли response_destination, так что если мы должны сказать кому-то отправить сообщение кому-то другому, как только мы передадим это право собственности. Мы проверяем, что такое forward_amount, если она запрошена. Затем мы выясняем, что у нас будет достаточно денег после того, как мы отправим эту сумму в пункт назначения. Затем мы выясняем, нужен ли вообще ответ, если присутствует response_destination. Если он присутствует, остальная сумма должна быть больше 0.
Я кратко покажу вам, как это работает. Если forward_amount присутствует там, мы отправим сообщение с уведомлением о том, что право собственности назначено этому forward_amount. Если нам нужен ответ, мы снова force_chain, чтобы убедиться, что место назначения ответа находится в той же цепочке. И мы отправляем ответ, который обычно включает в себя эксцессы и все дополнительные средства; они просто перенаправляются в response_destination. Затем мы просто сохраняем данные с помощью new_owner_address. По сути, это единственное, что изменится, transfer_ownership является одной из основных функций здесь. У вас есть предмет, и иногда вы передаете право собственности другим людям или продаете его, в зависимости от типа этой сделки.
Контракт на товар SBT
NFT могут работать на другом уровне. Проверьте Getgems marketplace. У них есть свои собственные контракты, которые позволяют продавать такого рода активы. Сейчас мы не будем исследовать эти рыночные контракты. Тем не менее, я покажу вам место, где вы можете много узнать о NFT — GetGems github —Там мы найдем еще один тип NFT, который я хочу рассмотреть для вас.
GetGems repository Проводит ряд различных контрактов NFT, коллекций, продажи и рынка, а также некоторые аукционы. Это хорошее место, чтобы узнать больше о контрактах, связанных с коллекциями NFT, предметами и тем, что их окружает. Но я хотел показать вам один точный контракт, в котором мы можем немного покопаться.
The sbt-item Является токеном SoulBound (SBT). Soulbound очень похож на NFT, но разница в том, что душевные токены не могут быть переданы другим людям без полномочий. Давайте подробнее посмотрим на его код.
Здесь у нас есть некоторые переменные: storage::index, storage::collection_address. Мы также определяем другие глобальные переменные, и это всего лишь пример реализации GetGems. Вы не должны делать это так же. Я хотел сосредоточиться на некоторых других частях здесь:
Как видите, здесь у нас есть несколько комментариев, но мы не собираемся копаться в каждой строке. Вы видите, что этот токен будет использоваться по-разному, но не так, как обычные NFT.
Вот контракт, и вы можете запросить владельца этого контракта. Некоторые коды операции могут запросить подтверждение права собственности. Вы можете получить статические данные. Вы также можете уничтожить или отозвать этот токен. Вы можете взять лишние, например, некоторые деньги, которые там хранились. И вы можете запросить это, если вы являетесь владельцем этого контракта. Но вы не можете передать это, очевидно, так же, как вы видите это здесь. Это совершенно другой тип токенов, и вы должны провести больше времени в этом репозитории GetGems, если вам нравятся NFT.
Я хочу показать вам, что коллекция NFT может оставаться прежней со всем своим кодом, но элементы, которые развертывается в контракте на сбор, могут отличаться. Например, вы можете заменить элемент NFT на элемент SBT. Таким образом, у вас будет коллекция команд SBT, а затем вы просто измените code Который инициализирует вашу коллекцию:
(slice, int, cell, cell, cell) load_data() inline {
var ds = get_data().begin_parse();
return
(ds~load_msg_addr(), ;; owner_address
ds~load_uint(64), ;; next_item_index
ds~load_ref(), ;; content
ds~load_ref(), ;; nft_item_code
ds~load_ref() ;; royalty_params
);
}
Таким образом, вы фактически развернете коллекцию предметов SBT. Также вы можете создать один, независимый SBT item Без коллекции. Мы не будем осваивать программирование этих элементов; я просто хотел показать вам, как это работает в большем масштабе.
Conclusion
Из очень простой логики главы 3 мы дошли до понимания многих вещей в сложных контрактах, таких как NFT или Jettons. Это хороший пример того, что шаг за шагом вы можете изучить определенный синтаксис и концепции, а затем для вас открыта более сложная логика. Надеюсь, эти несколько уроков помогли вам понять, что такое Jettons и NFT на самом деле и как подойти к их кодовым базам - чтобы понять, как они работают, и узнать больше с точки зрения синтаксиса и архитектуры, доступных для вас, когда вы строите в TON.
Я очень ценю ваше внимание. Это может быть самая сложная глава для вас, хотя мы ничего не кодировали; мы просто читали кое-что, чего вы никогда раньше не видели, и это очень сложно. Так что я очень горжусь тем, что вы добрались до этого последнего урока, и я с нетерпением жду встречи с вами в следующих главах. Надеюсь, вам пока понравится курс.