Перейти к основному содержимому

Развёртывание в сеть

Резюме: В предыдущих частях мы разработали и протестировали наши смарт-контракты, убедившись в их корректности.

В этой части руководства мы приступим к развёртыванию ранее разработанных смарт-контрактов и рассмотрим взаимодействие с ними в блокчейне.

Адрес и начальное состояние

Мы уже знаем, что адрес — это уникальный идентификатор смарт-контракта в сети, используемый для отправки транзакций и верификации отправителя при получении. Однако мы пока что не обсуждали его создание. Стандартная формула для вычисления адреса смарт-контракта выглядит так:

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 этим кодом:

/scripts/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 радо помочь!

Was this article useful?