Типы контрактов кошелька
Эта страница переведена сообществом на русский язык, но нуждается в улучшениях. Если вы хотите принять участие в переводе свяжитесь с @alexgton.
Возможно, вы слышали о различных версиях кошельков на блокчейне TON. Но что на самом деле означают эти версии и чем отличаются?
В этой статье мы рассмотрим различные версии и модификации кошельков TON.
Before we start, there are some terms and concepts that you should be familiar with to fully understand the article:
- Управление сообщениями – поскольку это основная функциональность кошельков.
- Язык FunC – потому что мы будем в значительной степени полагаться на реализации, сделанные с его помощью.
Общая концепция
Чтобы разрушить напряжение, для начала мы должны понять, что кошельки не являются особой сущностью в экосистеме TON. Они по-прежнему являются всего лишь смарт-контрактами, состоящими из кода и данных, и в этом смысле равны любому другому субъекту (т.е. смарт-контракту) в TON.
Как и ваш собственный или любой другой смарт-контракт, кошельки могут принимать внешние и внутренние сообщения, отправлять внутренние сообщения и логи, а также использовать GET-методы. Поэтому возникает вопрос: какую функциональность предоставляют кошельки и чем она отличается в разных версиях?
Вы можете рассматривать каждую версию кошелька как реализацию смарт-контракта, предоставляющую стандартный внешний интерфейс, позволяющий различным внешним клиентам взаимодействовать с кошельками одинаковым образом. Вы можете найти эти реализации на языках FunC и Fift в основном репозитарии TON:
Базовые кошельки
Кошелек V1
Это самый простой вариант кошелька. Он позволяет вам отправлять только четыре транзакции одновременно и не проверяет ничего, кроме вашей подписи и seqno.
Исходный код кошелька:
Эта версия кошелька даже не используется в обычных приложениях, потому что у нее есть серьезные проблемы:
- Нет простого способа получить seqno и публичный ключ из контракта.
- Нет проверки
valid_until
, поэтому вы не можете быть уверен ы, что транзакция не будет подтверждена слишком поздно.
Первая проблема была исправлена в V1R2
и V1R3
. Символ R
означает "ревизия". Обычно ревизии – это небольшие обновления, которые добавляют только GET-методы (вы можете найти историю изменений в файле new-wallet.fif
). Здесь и далее мы будем рассматривать только последние ревизии.
Тем не менее, поскольку каждая последующая версия наследует функциональность предыдущей, нам все равно следует придерживаться ее, поскольку это поможет нам в последующих версиях.
Расположение постоянной памяти
- seqno: 32-битный порядковый номер.
- public-key: 256-битный публичный ключ.
Оформление тела внешнего сообщения
- Данные:
- подпись: 512-битная подпись ed25519.
- msg-seqno: 32-битный порядковый номер.
- (0-4)mode: до четырех 8-битных целых чисел, определяющих режим отправки для каждого сообщения.
- До 4 ссылок на ячейки, содержащие сообщения.
Как вы можете видеть, основная функциональность кошелька заключается в обеспечении безопасного способа связи с блокчейном TON из внешнего мира. Механизм seqno
защищает от атак повторного воспроизведения, а подпись Ed25519
обеспечивает авторизованный доступ к функционалу кошелька. Мы не будем подробно останавливаться на каждом из этих механизмов, поскольку они подробно описаны на странице документации external message и довольно часто встречаются среди смарт-контрактов, получающих внешние сообщения. Данные полезной нагрузки состоят из до 4 ссылок на ячейки и соответствующего количества режимов, которые будут непосредственно переданы в метод send_raw_message(cell msg, int mode).
Обратите внимание, что кошелек не обеспечивает никакой проверки внутренних сообщений, которые вы отправляете через него. Ответственность за сериализацию данных в соответствии с макетом внутреннего сообщения лежит на программисте (т.е. внешнем клиенте).
Коды завершения
Код завершения | Описание |
---|---|
0x21 | Проверка seqno не выполнена, сработала защита ответа |
0x22 | Проверка Ed25519 signature не выполнена |
0x0 | Стандартный код завершения при успешном выполнении |
Обратите внимание, что у TVM есть стандартные коды завершения (0x0
– один из них), поэтому вы также можете получить один из них, например, если у вас закончился газ, то вы получите код 0xD
.
GET-методы
- int
seqno()
– возвращает текущий сохраненный seqno. - int
get_public_key
– возвращает текущий сохраненный публичный ключ.
Кошелек V2
Исходный код кошелька:
В данной версии появился параметр valid_until
, который используется для установки временного ограничения для транзакции, если вы не хотите, чтобы она была подтверждена слишком поздно. В этой версии также отсутствует get-метод для публичного ключа, который был добавлен в V2R2
.
Все отличия по сравнению с предыдущей версией являются следствием добавления функциональности valid_until
. Был добавлен новый код завершения: 0x23
, отмечающий неудачу при проверке valid_until
. Кроме того, в макет тела внешнего сообщения было добавлено новое поле Unix-time
, задающее временной лимит транзакции. Все GET-методы остаются прежними.
Содержимое тела внешнего сообщения
- Данные:
- signature: 512-битная подпись ed25519.
- msg-seqno: 32-битный порядковый номер.
- valid-until: 32-битное целое число Unix-time.
- (0-4)mode: до четырех 8-битных целых чисел, определяющих режим отправки для каждого сообщен ия.
- До 4 ссылок на ячейки, содержащие сообщения.
Кошелек V3
В этой версии появился параметр subwallet_id
, который позволяет вам создавать несколько кошельков, используя один и тот же публичный ключ (таким образом, у вас может быть только одна seed-фраза и несколько кошельков). Как и раньше, V3R2
добавляет только метод get-метод для публичного ключа.
Исходный код кошелька:
По сути, subwallet_id
– это просто число, добавляемое к состоянию контракта при его развертывании. Поскольку адрес контракта в TON представляет собой хэш его состояния и код, адрес кошелька изменится на другой subwallet_id
. Эта версия наиболее широко используется в настоящее время. Она охватывает большинство случаев использования и остается универсальной, простой и в основном такой же, как и предыдущие версии. Все GET-методы остаются прежними.
Содержимое постоянной памяти
- seqno: 32-битный порядковый номер.
- subwallet: 32-битный идентификатор subwallet.
- public-key: 256-битный публичный ключ.
Содержимое внешнего сообщения
- Данные:
- подпись: 512-битная подпись ed25519.
- subwallet-id: 32-битный идентификатор subwallet.
- msg-seqno: 32-битный порядковый номер.
- valid-until: 32-битное целое число Unix-time.
- (0-4)mode: до четырех 8-битных целых чисел, определяющих режим отправки для каждого сообщения.
- До 4 ссылок на ячейки, содержащие сообщения.