Wtf is sui
Я положил крышу, устал и решил, что писать статью по суи будет попроще, чем класть ещё и конёк.
Итак, я решил, что почему бы не попробовать написать что-то для суи, но тут меня ждало несколько разочарований.
Во-первых, я испугался этой надписи в описании библы на python
Во-вторых, вся дока на басурманском языке, который я хоть и знаю, но вдумчиво читать на нём реально влом.
В-третьих, когда я всё-таки поставил библу и начал более-менее разбираться я встречаю это
В общем моё мнение о суи еще с прошлого года не изменилось и я начал ковырять палочкой это чудо.
Спустя пару дней я понял несколько очень важных вещей. Дальше всё будет на примере конкретного класса, а так же не будет возможности копировать код. Почему? Потому что нужно набивать руку печатать всё самому, а то привыкли, видите ли, с чатов гпт всё копировать.
Итак. Обратимся к офф доке и узнаем, что нам вообще нужно, чтобы отправить транзакцию:
Мы тут сразу видим какой-то конфиг, какой-то клиент. Все они дефолтные, судя по коду. Но что же будет если я скопирую этот код и запущу?
И он не может найти какой-то файл конфигурации. Что это за файл? Догадаться нужно самому, потому что в доке я этого не нашел. Поэтому после пары часов поисков, лазанья по всей библиотеке, метода научного тыка я обнаружил, что нужно создать 2 файла. Первый — это уже известный нам client.yaml, а второй — с произвольным названием, где по задумке разработчиков должны храниться все ключи от текущего конфига. С именем я не заморачивался и просто назвал a.sui
Теперь по содержанию файлов и что означает каждое поле
client.yaml представляет собой файлик, в котором хранятся данные по разным конфигам. Потом можно будет выбрать любой, но я использую один и програмно его изменяю.
keystore — В этом поле указывается расположение файла со всеми(или не совсем) приватными ключами. Название произвольно.
active_address — Это активный адрес текущего окружения. Принцип работы такой же, как и в метамаске. Если выбрать адрес, то он и будет подписывать(ЗЫ иметь приватный ключ от этого адреса не обязательно, оно и так запустится)
active_env — Тут указывается название текущего окружения
envs — Тут списком перечисляются разные окружения, у каждого свои параметры, такие как: alias - имя, rpc - ссылка на ноду, есть ещё парочка, но они не обязательны
В файле a.sui, а именно так я назвал файл с ключами, обязан быть хотя бы один приватный ключ. Я выбрал первый, что подходит из интернета. В целом, если брать конкретно мой класс из примера, это ни на что не влияет.
Итак, когда мы создали все файлы конфигурации, можно и начинать писать код.
Для класса аккаунта я использовал эти библиотеки
Начнем с самого базового. Создадим класс и прикрутим функцию __init__
Я решил сразу всё делать с поддержкой проксей, потому что ноды любят иногда рейтлимитить.
Дальше нам нужно создать конфиг и записать в него наш приватный ключ
Тут первой строкой мы создаем конфиг и указываем ему путь до файла конфигурации, дальше добавляем приватный ключ в него и выбираем нужную кривую(а их тут 4 штуки: ED25519, SECP256K1, SECP256R1, BLS12381).
После этого мы указываем в конфиге, что текущий активный адрес — это тот, что получился из нашего ключа.
Дальше мы создаём клиент, в него пихаем конфиг, и перезаписываем httpx клиент, чтобы он мог поддерживать прокси.
Для удобства я прикрутил ещё функцию/свойство для получения адреса от аккаунта. Целиком это выглядит так:
А теперь самое интересное. Как же отправлять транзакции? Всё очень просто.
Тут всё практически так же, как и в ЕВМ. Делаем транзу руками, смотрим на типы аргументов и их значения, пишем это в коде и вуаля, транза отправляется. Ну почти.
Буду брать в качестве примера транзакцию с movepump'a. А именно эту транзакцию
Если зайти по ссылке, то мы увидем много всякого непонятного, но нам всё и не нужно. Нам нужны вот эти 2 вещи
Если нажать на них, то они откроются и всё станет опять непонятно.
Split coin делает так, чтобы из одного объекта монеты получилось два. Допустим у нас был 1 суи. Мы вызвали split coins, указали, что мы это делаем с суи и вписали число 100000000( Оно же 0.1 SUI). После этого у нас в сканере в портфолио видим картину, где у нас 2 разных баланса суи, в одном больше монет, в другом меньше. Если брать конкретно этот пример, то будет 0.9 и 0.1(если округлять и не учитывать газ).
Перед тем, как показывать код, покажу нужные библиотеки
В коде это реализуется очень просто. Сначала мы создаем экземпляр транзакции, потом в нее засовываем Split Coins
GasCoin тут значит, что мы используем сам токен SUI
Дальше создаём саму транзакцию, если работали с аптосом, то всё будет очень просто.
В target указываем адрес контракта, модуль и функцию
В arguments аргументы с нужными типами данных
В type_arguments указываем уже кастомные типы из Move, которые может потребовать функция
В данном конкретном случае используется Nestedresult. Оно возвращает конкретное значение из конкретного вызова по счёту. 0 0 значит, что вернёт первое значение первого вызова, а у нас это 100000000.
Все типы данных есть в табличке в документации тут
Осталось только отправить транзакцию. Делаем так и всё
В gas_budget указываем максимальный газ, который готовы заплатить за транзакцию.
И Всё в целом
Если найдёте косяк в этой статье, то это был не я, а злой гном-хуекрад, который зашел с моего пк. Просьба оповестить о таких вещах в лс