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

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

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

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

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

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

address = hash(state_init(code, data))

Адрес смарт-контракта — это хэш, вычисленный из первоначальных кода и данных смарт-контракта. Из этого простого механизма есть несколько важных следствий:

Вы уже знаете адрес

В TON любой адрес, не имеющий данных, рассматривается в состоянии несуществующий (nonexistent). Тем не менее, когда мы создавали новый кошелёк с помощью приложения в разделе Начало работы, мы могли получить адрес будущего смарт-контракта нашего кошелька в приложении ещё до его развёртывания и изучить его в эксплорере.

Причина в том, что создание вашей пары ключей (приватного и публичного) с помощью мнемонической фразы, где второй ключ является частью первоначальных данных смарт-контракта, делает state_init этого контракта полностью детерминированным:

  • code будет одной из стандартных реализаций кошелька, таких как v5r1.
  • data — это public_key вместе с другими полями, инициализированными по умолчанию.

Это позволяет рассчитать адрес смарт-контракта будущего кошелька.

Магический элемент хранилища

В предыдущих шагах, мы сознательно не объясняли назначение ctxID и 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 этот процесс выглядит одинаково для мейннета и тестнета, а также для любого из языков в этом гайде: Tact, FunC и Tolk.

Шаг 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 самостоятельно. Более того, вы даже можете сделать это с помощью внутреннего сообщения от смарт-контракта.

Was this article useful?