Обновление кода Move
Tags: aptos, blockchain, tutorial, developer
Published: 2022-09-01 14:42:12

Сеть Aptos поддерживает обновление кода, что означает, что уже развернутый код Move может быть заменен на более новый. Если происходит обновление кода, все потребители обновленного кода автоматически получат новый код при следующем выполнении их кода.

Обновление кода позволяет владельцам кода развивать свои контракты или фреймворки под стабильным, хорошо известным адресом учетной записи, на который могут ссылаться другие приложения внутри или вне сети.

Обновление кода основано на политике обновления, которую определяет владелец пакета. По умолчанию используется политика (обратной) совместимости. Это означает, что принимаются только те обновления, которые гарантируют, что ни один из существующих публичных API (включая транзакции и публичные функции) и/или существующее хранилище ресурсов не будет нарушено обновлением. Такая проверка совместимости является технически полной и возможной благодаря сильно типизированной семантике байт-кода Move. Однако, даже совместимое обновление может иметь опасные последствия для приложений, поэтому зависимость от обновляемого кода в сети должна быть тщательно рассмотрена в каждом конкретном случае (см. также ниже обсуждение аспектов безопасности).

## Как это работает

Обновление кода в сети Aptos происходит на уровне [пакета Move](https://move-language.github.io/move/packages.html). Пакет определяет политику обновления в манифесте `Move.toml`:

```
[package]
name = "MyApp"
version = "0.0.1"
upgrade_policy = "compatible"
...
```

> **ПРОВЕРКА СОВМЕСТИМОСТИ
**> Aptos проверяет совместимость во время публикации пакета Move с помощью специальной транзакции фреймворка Aptos. Эта транзакция прерывается, если совместимость не удовлетворяет заданным требованиям.

## Политика обновления

В настоящее время поддерживаются три различные политики обновления:

- `compatible`: обновления должны быть обратно совместимы, в частности:
  - Для хранилища все старые объявления struct должны быть такими же в новом коде. Это гарантирует, что существующее состояние хранилища будет правильно интерпретировано новым кодом. Однако можно добавлять новые определения структур.
  - Для API все публичные функции должны иметь ту же подпись, что и раньше. Новые функции могут быть добавлены.

- `immutable`: код не подлежит обновлению и гарантированно остается неизменным всегда.
- `arbitrary`: код может быть произвольно обновлен без каких-либо проверок на совместимость.


Эти политики упорядочены по силе так: `arbitrary < compatible < immutable`. Политика пакета по сети может становиться только сильнее, но не слабее. Более того, политика всех зависимостей пакета должна быть сильнее или равна политике данного пакета. Например, `immutable` пакет не может прямо или косвенно ссылаться на `compatible` пакет. Это дает пользователям гарантию того, что под капотом не произойдет никаких неожиданных обновлений. Существует одно исключение из этого правила: пакеты фреймворка, установленные по адресам с `0x1` по `0xa`, освобождаются от проверки зависимостей. Это необходимо для того, чтобы можно было определить `immutable` пакет, основанный на стандартных библиотеках, которые имеют `compatible` политику.

В дополнение к вышеперечисленным правилам, существует еще одно правило для `arbitrary` пакетов: зависимость от пакета с `arbitrary` политикой обновления должна находиться в пределах одной учетной записи (два пакета должны находиться по одному адресу). Это ограничение призвано защитить пользователей от злоупотреблений при совместном использовании таких пакетов. Одна учетная запись может работать с `arbitrary` без ограничений, но совместное использование такого кода не допускается.

## Соображения безопасности для зависимостей

Как уже говорилось, даже совместимые обновления могут привести к опасным последствиям для контрактов, зависящих от обновленного кода. Эти эффекты могут возникнуть просто из-за ошибок, но могут быть и результатом злонамеренных обновлений. Например, обновленная зависимость может внезапно заставить все функции прерваться, нарушив работу вашего контракта, или внезапно потребовать гораздо больше газа для выполнения, чем до обновления. Поскольку вы не можете контролировать обновление, с зависимостями от обновляемых пакетов нужно обращаться осторожно.

- Самая безопасная зависимость - это, конечно, `immutable` пакет. Он гарантированно никогда не изменится, включая его переходные зависимости (по модулю фреймворка Aptos). Для того чтобы развить `immutable` пакет, его владелец должен представить новую основную версию, которая практически является независимым новым пакетом. В настоящее время основные версии должны быть выражены именованием (например, `module feature_v1` и `module feature_v2`). Однако не всем владельцам пакетов нравится публиковать свой код как `immutable`, поскольку это лишает их возможности исправлять ошибки и развивать код на месте.
- Если у вас есть зависимость от `compatible` пакета, настоятельно рекомендуется знать и понимать организацию, публикующую пакет. Наивысшим уровнем гарантии является то, что пакет управляется DAO, где ни один пользователь не может инициировать обновление, но должно быть проведено голосование или что-то подобное. Так, например, обстоит дело с фреймворком Aptos.
- Зависимости от `arbitrary` пакетов технически разрешены только в одной учетной записи, поэтому решение об обновлении и ответственность за обеспечение совместимости лежит на владельце учетной записи.

## Программное обновление

В целом, Aptos предлагает, через модуль Move `aptos_framework::code`, способы публикации кода из любого места в ваших смарт-контрактах. Однако обратите внимание, что код, опубликованный в текущей транзакции, не может быть выполнен до завершения этой транзакции.

Сам Aptos Framework, включая всю логику администрирования сетей, является примером для программного обновления. Фреймворк помечен как `compatible`. Обновление происходит с помощью специальных генерируемых скриптов управления. Для получения более подробной информации см. раздел [Управление Aptos](https://dev.to/egormajj/kontsieptsii-aptos-upravlieniie-28ak).