Контракты кошельков
Возможно, вы слышали о разных версиях кошельков на блокчейне 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:
Стандартные кошельки
Хеши контрактов кошельков
Здесь вы можете найти текущие хеши различных версий кода контрактов кошельков. Подробные спецификации каждого контракта кошелька приведены ниже в тексте, а также на странице ContractSources.md.
Показать таблицу хешей контрактов кошельков
| Версия контракта | Хеш |
|---|---|
| walletv1r1 | oM/CxIruFqJx8s/AtzgtgXVs7LEBfQd/qqs7tgL2how= |
| walletv1r2 | 1JAvzJ+tdGmPqONTIgpo2g3PcuMryy657gQhfBfTBiw= |
| walletv1r3 | WHzHie/xyE9G7DeX5F/ICaFP9a4k8eDHpqmcydyQYf8= |
| walletv2r1 | XJpeaMEI4YchoHxC+ZVr+zmtd+xtYktgxXbsiO7mUyk= |
| walletv2r2 | /pUw0yQ4Uwg+8u8LTCkIwKv2+hwx6iQ6rKpb+MfXU/E= |
| walletv3r1 | thBBpYp5gLlG6PueGY48kE0keZ/6NldOpCUcQaVm9YE= |
| walletv3r2 | hNr6RJ+Ypph3ibojI1gHK8D3bcRSQAKl0JGLmnXS1Zk= |
| walletv4r1 | ZN1UgFUixb6KnbWc6gEFzPDQh4bKeb64y3nogKjXMi0= |
| walletv4r2 | /rX/aCDi/w2Ug+fg1iyBfYRniftK5YDIeIZtlZ2r1cA= |
| walletv5r1 | IINLe3KxEhR+Gy+0V7hOdNGjDwT3N9T2KmaOlVLSty8= |
Примечание: Эти хеши также можно найти в эксплорерах.
Кошелёк V1
Это самый простой вариант. Он позволяет только отправлять до четырёх транзакций за раз и не проверяет ничего, кроме вашей подписи и seqno.
Исходный код кошелька:
Эта версия даже не используется в стандартных приложениях, потому что у неё есть несколько серьёзных недостатков:
- Нет простого способа запросить у контракта seqno и публичный ключ.
- Нет проверки
valid_until, позволяющей быть уверенными, что транзакция не окажется подтверждена слишком поздно.
Первая проблема была исправлена в версиях V1R2 и V1R3. Буква R означает ревизию. Обычно ревизии — это небольшие обновления, которые добавляют только get-методы; вы можете найти их в истории изменений new-wallet.fif. Здесь и далее мы будем рассматривать только последние ревизии.
Тем не менее, поскольку каждая последующая версия наследует функциональность предыдущей, мы все равно рассмотрим первую, так как это поможет нам с более поздними.
Официальные хеши кода
| Версия контракта | Хеш |
|---|---|
| walletv1r1 | oM/CxIruFqJx8s/AtzgtgXVs7LEBfQd/qqs7tgL2how= |
| walletv1r2 | 1JAvzJ+tdGmPqONTIgpo2g3PcuMryy657gQhfBfTBiw= |
| walletv1r3 | WHzHie/xyE9G7DeX5F/ICaFP9a4k8eDHpqmcydyQYf8= |
Структура постоянной памяти
- seqno: 32-бит ный порядковый номер.
- public-key: 256-битный публичный ключ.
Структура тела внешнего сообщения
- Данные:
- signature: 512-битная подпись в формате Ed25519.
- msg-seqno: 32-битный порядковый номер.
- (0-4) mode: до четырёх 8-битных целых чисел, определяющих режим отправки для каждого из сообщений на отправку.
- До 4 ссылок на ячейки, содержащие сообщения:
Как вы можете видеть, основная функциональность кошелька — это обеспечение безопасного способа связи с блокчейном TON из внешнего мира. Механизм seqno защищает от атак повторного воспроизведения, а подпись Ed25519 обеспечивает авторизованный доступ к функциональности кошелька. Мы не будем подробно останавливаться на каждом из этих механизмов, так как они подробно описаны на странице документации внешнего сообщения и довольно распрос транены среди смарт-контрактов, получающих внешние сообщения. Полезная нагрузка сообщения состоит из ссылок на ячейки (не более 4) и соответствующего количества режимов, которые будут напрямую переданы методу send_raw_message(cell msg, int mode).
Обратите внимание, что кошелёк никак не проверяет внутренние сообщения, которые вы отправляете через него. Ответственность за сериализацию данных в соответствии со структурой внутреннего сообщения лежит на программисте (т. е. на внешнем клиенте).
Коды возврата
| Код возврата | Описание |
|---|---|
| 0x21 |