Развёртывание в сеть
Резюме: В предыдущих частях мы разработали и протестировали наши смарт-контракты, убедившись в их корректности.
В этой части руководства мы приступим к развёртыванию ранее разработанных смарт-контрактов и рассмотрим взаимодействие с ними в блокчейне.
Адрес и начальное состояние
Мы уже знаем, что адрес — это уникальный идентификатор смарт-контракта
в сети, используемый для отправки транзакций и верификации отправителя при получении. Однако мы пока что не обсуждали его создание. Стандартная формула для вычисления адреса смарт-контракта выглядит так:
address = hash(state_init(code, data))
Адрес смарт-контракта — это хеш первоначального кода и первоначальных данных смарт-контракта, взятых вместе. Из этого простого механизма есть несколько важных следствий:
Вы уже знаете адрес
В TON любой адрес, не имеющий данных, считается находящимся в состоянии несуществующий
(nonexistent
). Однако, когда мы создавали новый кошелёк в разделе Начало работы, мы могли получить в приложении адрес будущего смарт-контракта нашего кошелька ещё до его развёртывания и изучить его в эксплорере.
Дело в том, что если ваши приватный и публичный ключи создаются с помощью мнемонической фразы, и второй ключ — часть первоначальных данных смарт-контракта, это делает state_init
контракта полностью детерминированным:
- code — одна из стандартных реализаций кошелька, вроде
v5r1
. - data — это
public_key
вместе с другими полями, инициализированными по умолчанию.
Это позволяет рассчитать адрес будущего смарт-контракта кошелька.
Магический элемент хранилища
В предыдущих шагах мы намеренно не объясняли назначение ctx_id
и ID
, хранимых в состоянии нашего смарт-контракта, и то, почему они оставались нетронутыми во всех его функциях. Теперь их предназначение должно стать яснее.
Поскольку нельзя развернуть много разных смарт-контрактов с одним и тем же state_init
(их адреса совпадут), единственный способ предоставить всем вам один и тот же исходный код и "одинаковые" исходные данные — добавить в state_init
отдельное поле, обеспечивающее дополнительную уникальность. В случае кошелька это даёт вам возможность использовать одну и ту же пару ключей для нескольких смарт-контрактов кошелька.
Одно, чтоб править ими всеми
Вы могли подумать, что поле ID
является обязательным для любого смарт-контракта, однако есть и другой вариант. Рассмотрим раздел инициализации ранее разработанного контракта HelloWorld
:
init(id: Int, owner: Address) {
self.id = id;
self.counter = 0;
self.owner = owner;
}
Если мы удалим поле id
из его первоначального состояния хранилища, то сможем быть уверенными, что для определённого владельца может существовать только один смарт-контракт HelloWorld
.
Этот механизм играет ключевую роль в обработке Jetton. Каждый токен, не являющийся нативным (Jetton), требует наличия собственного Jetton Wallet
для определённого владельца. И, следовательно, предоставляет для него вычислимый адрес, создавая схему звезды с базовым кошельком в центре.
Реализация
Теперь, когда наши контракты полностью протестированы, мы готовы развернуть их в TON. В Blueprint
этот процесс выглядит одинаково для мейннета
и тестнета
, а также для любого из языков в этом гайде: Tolk
, FunC
и Tact
.
Шаг 1: обновить скрипт развёртывания
Скрипты развёртывания опираются на те же обёртки, которые вы использовали в скриптах тестирования. Мы будем использовать один общий скрипт для развёртывания обоих ранее разработанных смарт-контрактов. Обновите deployHelloWorld.ts
этим кодом:
// @version TypeScript 5.8.3
import { toNano } from '@ton/core';
import { HelloWorld } from '../wrappers/HelloWorld';
import { compile, NetworkProvider } from '@ton/blueprint';
export async function run(provider: NetworkProvider) {
const sender = provider.sender();
if (!sender.address) {
throw new Error('Sender address is required');
}
const helloWorld = provider.open(
await HelloWorld.fromInit(0n, sender.address)
);
await helloWorld.send(
sender,
{ value: toNano('0.05') },
null
);
await provider.waitForDeploy(helloWorld.address);
console.log('ID', await helloWorld.getId());
}
Шаг 2: запустите скрипт развёртывания
Вы можете запустить скрипт, введя следующую команду:
npx blueprint run deployHelloWorld
Шаг 3: выберите сеть
После этого вы увидите интерактивное меню, позволяющее выбрать сеть:
? Which network do you want to use? (Use arrow keys)
mainnet
❯ testnet
custom
Перед развёртыванием в мейннете
убедитесь, что ваши смарт-контракты соответствуют мерам безопасности. Как мы уже говорили ранее, смарт-контракт HelloWorld
им не соответствует.
Шаг 4: выберите приложение кошелька
Далее выберите способ доступа к вашему кошельку. Самый простой способ сделать это — использовать TON Connect и одно из самых популярных приложений кошельков: TonKeeper
, MyTonWallet
, или Tonhub
.
? Which wallet are you using? (Use arrow keys)
❯ TON Connect compatible mobile wallet (example: Tonkeeper)
Create a ton:// deep link
Mnemonic
? Choose your wallet (Use arrow keys)
❯ Tonkeeper
MyTonWallet
Tonhub
Наконец, отсканируйте QR-код в терминале через приложение кошелька и подключите кошелёк. После того, как вы сделаете это в проекте впервые, этот шаг будет пропускаться.
Вы будете получать запрос на транзакцию в вашем приложении кошелька каждый раз, когда ваш код требует оплаты для транзакции.
Шаг 5: наблюдайте ваш смарт-контракт в сети
После того, как вы подтвердите запрос в вашем кошельке и дождётесь развёртывания, вы увидите сообщение со ссылкой на просмотр вашего недавно развёрнутого смарт-контракта в эксплорере:
Contract deployed at address EQBrFHgzSwxVYBXjIYAM6g2RHbeFebJA8QUDwg4IX8CPDPug
You can view it at https://testnet.tonscan.org/address/EQBrFHgzSwxVYBXjIYAM6g2RHbeFebJA8QUDwg4IX8CPDPug
Поздравляем! Ваш собственный смарт-контракт
готов исполнять get-методы
так же, как это делал ваш кошелёк в разделе Как начать. И он может исполнять транзакции
так же, как описано в разделе о взаимодействии с блокчейном — если вы ещё его не читали, это полезно сделать, чтобы понять, как взаимодействовать со смарт-контрактами
извне блокчейна.
Использование Blueprint
и приложений кошельков — не единственный вариант. Вы можете создать сообщение со state_init самостоятельно. Более того, вы даже можете сделать это с помощью внутреннего сообщения от смарт-контракта.
Что дальше?
Вы освоили всё руководство — отлично! Теперь пришло время погрузиться глубже и продолжить создавать. Here are some helpful resources to continue your Tact journey:
- Официальный сайт — обзор, новости, ссылки на ресурсы экосистемы
- Документация Tact — основной источник информации по возможностям языка
- Репозиторий Tact — исходный код и возможность поучаствовать в его развитии
- Tact by example — сайт с наглядными примерами смарт-контрактов
- Tact smart battle — задания, позволяющие отточить навыки разработки на Tact
- @tact_kitchen — канал с апдейтами Tact
- @tactlang — чат для обсуждения разработки на Tact и помощи
Оставайтесь любопытными и не бойтесь задавать вопросы — сообщество Tact радо помочь!