Работа со смарт-контрактами кошелька
👋 Введение
Прежде чем приступать к разработке смарт-контрактов, важно изучить как работают кошельки и транзакции на TON. Это поможет разработчикам понять принцип взаимодействия между кошельками, сообщениями и смарт-контрактами для выполнения конкретных задач разработки.
Перед чтением руководства рекомендуется ознакомиться со статьей Типы контрактов кошелька.
Мы научимся создавать операции без использования предварительно настроенных функций, это полезно для лучшего понимания процесса разработки. Дополнительные ссылки на материалы для изучения находятся в конце каждого раздела.
💡 Перед началом работы
Изучение данного руководства потребует базовых знаний JavaScript и TypeScript или Golang. На балансе кошелька должно быть как минимум 3 TON (это может быть биржевой счет, некастодиальный кошелек или бот Кошелек от Telegram). Также необходимо иметь представление об адресах в TON, ячейке, блокчейне блокчейнов.
Работа с TON Testnet часто приводит к ошибкам при развертывании, сложностям с отслеживанием транзакций и нестабильной работе сети. Большую часть разработки лучше реализовать в TON Mainnet, чтобы избежать проблем, которые могут возникнуть при попытках уменьшить количество транзакций, и понизить сборы, соответственно.
💿 Исходный код
Все примеры кода, используемые в руководстве, можно найти в репозитории GitHub.
✍️ Что нужно для начала работы
- Установленный NodeJS
- Специальные библиотеки TON: @ton/ton 13.5.1+, @ton/core 0.49.2+ и @ton/crypto 3.2.0+
ОПЦИОНАЛЬНО: Если вы предпочитаете использовать Go, а не JS, то для разработки на TON необходимо установить GoLand IDE и библиотеку tonutils-go. Эта библиотека будет использоваться в данном руководстве для версии Go.
- JavaScript
- Golang
npm i --save @ton/ton @ton/core @ton/crypto
go get github.com/xssnick/tonutils-go
go get github.com/xssnick/tonutils-go/adnl
go get github.com/xssnick/tonutils-go/address
⚙ Настройте свое окружение
Для создания проекта TypeScript выполните следующие шаги:
- Создайте пустую папку (мы назовем ее WalletsTutorial).
- Откройте папку проекта с помощью CLI.
- Используйте следующие команды для настройки проекта:
npm init -y
npm install typescript @types/node ts-node nodemon --save-dev
npx tsc --init --rootDir src --outDir build \ --esModuleInterop --target es2020 --resolveJsonModule --lib es6 \ --module commonjs --allowJs true --noImplicitAny false --allowSyntheticDefaultImports true --strict false
Процесс ts-node
запускает выполнение кода TypeScript без предварительной компиляции, а nodemon
используется для автоматического перезапуска приложения node при обнаружении изменений файлов в директории.
"files": [
"\\",
"\\"
]
- Затем создайте конфигурацию
nodemon.json
в корне проекта со следующим содержанием:
{
"watch": ["src"],
"ext": ".ts,.js",
"ignore": [],
"exec": "npx ts-node ./src/index.ts"
}
- Добавьте этот скрипт в
package.json
вместо "test", который добавляется при создании проекта:
"start:dev": "npx nodemon"
- Создайте папку
src
в корне проекта и файлindex.ts
в этой папке. - Далее добавьте следующий код:
async function main() {
console.log("Hello, TON!");
}
main().finally(() => console.log("Exiting..."));
- Запустите код в терминале:
npm run start:dev
- В итоге в консоли появится следующий вывод:
TON Community создали отличный инструмент для автоматизации всех процессов разработки (развертывание, написание контрактов, тестирование) под названием Blueprint. Однако нам не понадобится такой мощный инструмент, поэтому следует держаться приведенных выше инструкций.
ОПЦИОНАЛЬНО: При использовании Golang выполните следующие шаги:
- Установите GoLand IDE.
- Создайте папку проекта и файл
go.mod
со следующим содержанием (для выполнения этого процесса может потребоваться изменить версию Go, если текущая используемая версия устарела):
module main
go 1.20
- Введите следующую команду в терминал:
go get github.com/xssnick/tonutils-go
- Создайте файл
main.go
в корне проекта со следующим содержанием:
package main
import (
"log"
)
func main() {
log.Println("Hello, TON!")
}
- Измените наименование модуля в файле
go.mod
наmain
. - Запустите код выше до появления вывода в терминале.
Т акже можно использовать другую IDE, поскольку GoLand не бесплатна, но она предпочтительнее.
В каждом последующем разделе руководства будут указаны только те импорты, которые необходимы для конкретного раздела кода, новые импорты нужно будет добавлять и объединять со старыми.
🚀 Давайте начнем!
В этом разделе мы узнаем, какие кошельки (V3 и V4) чаще всего используются на блокчейне TON, и как работают их смарт-контракты. Это позволит разработчикам лучше понять различные типы сообщений на платформе TON, упростить их создание и отправку в блокчейн, научиться разворачивать кошельки и, в конечном итоге, работать с highload-кошельками.
Наша основная задача – научиться создавать сообщения, используя различные объекты и функции: @ton/ton, @ton/core, @ton/crypto (ExternalMessage, InternalMessage, Signing и т.д.), чтобы понять, как выглядят сообщения в более широких масштабах. Для этого мы будем использовать две основные версии кошелька (V3 и V4), поскольку биржи, некастодиальные кошельки и большинство пользователей используют именно эти версии.
There may be occasions in this tutorial when there is no explanation for particular details. In these cases, more details will be provided in later stages of this tutorial.
ВАЖНО: В данном руководстве используется код кошелька V3. Следует отметить, что версия 3 имеет две ревизии: R1 и R2. В настоящее вре мя используется только вторая ревизия, поэтому, когда мы по тексту ссылаемся на V3, это означает V3R2.
💎 Кошельки TON Blockchain
Все кошельки, работающие на блокчейне TON, являются смарт-контрактами, и все, что работает на TON функционирует как смарт-контракт. Как и в большинстве блокчейнов TON позволяет разворачивать смарт-контракты и модифицировать их для различных целей, предоставляя возможность полной кастомизация кошелька. В TON смарт-контракты кошелька облегчают взаимодействие между платформой и другими типами смарт-контрактов. Однако важно понимать, как происходит данное взаимодействие.
Взаимодействие с кошельком
В блокчейне TON существует два типа сообщений: internal
(внутренние) и external
(внешние). Внеш ние сообщения позволяют отправлять сообщения в блокчейн из внешнего мира, тем самым обеспечивая связь со смарт-контрактами, которые принимают такие сообщения. Функция, отвечающая за выполнение этого процесса, выглядит следующим образом:
() recv_external(slice in_msg) impure {
;; some code
}
Перед более подробным изучением кошельков давайте рассмотрим, как они принимают внешние сообщения. На TON каждый кошелек хранит public key
, seqno
и subwallet_id
владельца. При получении внешнего сообщения кошелек использует метод get_data()
для извлечения данных из хранилища. Затем проводится несколько процедур верификации и определяется, принимать сообщение или нет. Это происходит следующим образом:
() recv_external(slice in_msg) impure {
var signature = in_msg~load_bits(512); ;; get signature from the message body
var cs = in_msg;
var (subwallet_id, valid_until, msg_seqno) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32)); ;; get rest values from the message body
throw_if(35, valid_until <= now()); ;; check the relevance of the message
var ds = get_data().begin_parse(); ;; get data from storage and convert it into a slice to be able to read values
var (stored_seqno, stored_subwallet, public_key) = (ds~load_uint(32), ds~load_uint(32), ds~load_uint(256)); ;; read values from storage
ds.end_parse(); ;; make sure we do not have anything in ds variable
throw_unless(33, msg_seqno == stored_seqno);
throw_unless(34, subwallet_id == stored_subwallet);
throw_unless(35, check_signature(slice_hash(in_msg), signature, public_key));
accept_message();
💡 Полезные ссылки:
Теперь давайте рассмотрим подробнее.