На прошлой неделе участник Mars @larry0x провел интерактивный обзор кода предстоящего контракта на раздачу новых токенов $MARS; посмотрите запись здесь .
Эта статья будет служить продолжением общих тем, которые обсуждались.
Введение в контракт Airdrop
Пользователи взаимодействуют со смарт-контрактом CosmWasm через функции точки входа . Данные, которые принимают точки входа, известны как сообщения , обычно определяемые как перечисления Rust. Для взаимодействия с контрактом пользователь отправляет транзакцию (tx) с указанием адреса контракта, точки входа и данных сообщения (закодированных в формате JSON), которые должны быть переданы в точку входа. Существует пять основных типов сообщений:
- InstantiateMsg — создает экземпляр контракта
- ExecuteMsg — действия, изменяющие состояние контракта
- SudoMsg — аналогичен ExecuteMsg, но вызывается только модулем управления L1, а не пользователями или другими контрактами.
- QueryMsg — действия только для чтения, т.е. не изменяют состояние
- MigrateMsg — мигрирует и бинарный код контракта
Для контракта airdrop у нас есть только один вариант ExecuteMsg — «claim» и один вариант SudoMsg — «clawback». Логика контракта проста: если пользователь имеет право на аирдроп, он может получить свои вознаграждения. В любое время управление L1 может, после успешного предложения правительства, вызвать функцию «возврата», чтобы пожертвовать все невостребованные токены в пул сообщества.
Типы монет
Чтобы лучше понять некоторые дизайнерские решения, лежащие в основе функции «требования», давайте разберем основы типов монет. BIP-39 (Предложение по улучшению биткойнов — 39) определяет алгоритм преобразования мнемонических фраз в открытые/закрытые ключи. Это полезно для создания разных учетных записей из одного и того же мнемонического ключа. Этот алгоритм зависит от нескольких параметров , одним из которых является `coin_type`, определенный BIP-44. Биткойн, Эфириум, Космос и т. д. имеют свои собственные типы монет. Это означает, что с одним и тем же мнемоническим ключом и другим типом монеты пользователь может создавать отдельные учетные записи.
Почему это важно? Cosmos зарегистрирован как монета типа 118. Но, в отличие от других блокчейнов, Cosmos состоит из множества различных цепочек, каждая из которых имеет свой собственный набор валидаторов и сетей. Чтобы улучшить взаимодействие между цепочками, которое напоминает Cosmos, большинство сетей, использующих Cosmos SDK, в конечном итоге выбирают тип монеты 118 для своего собственного токена. Однако некоторые сети, такие как Terra, используют собственный тип монеты (330 для Terra). Выбор между типами монет 188 и 330 для новых токенов $MARS имеет важные последствия для контракта Airdrop.
Некоторые разработчики утверждают, что преимуществом каждой сети, выбирающей свой собственный тип монеты BIP-44, является конфиденциальность — так что знание адреса пользователя в одной цепочке не позволяет отслеживать действия пользователя в других цепях. Другие утверждают, что лучший способ добиться конфиденциальности — изменить «индекс», еще один параметр, используемый алгоритмом BIP-39, вместо изменения типов монет.
Использование монеты типа 330 для токенов $MARS может обеспечить более плавный аирдроп в краткосрочной перспективе, но есть долгосрочные проблемы UX, о которых следует больше беспокоиться. Поэтому токены $MARS будут использовать тип монеты 118.
Что это означает в краткосрочной перспективе? Поскольку Terra использует свой собственный тип монеты, когда вы импортируете ту же сид-фразу в свой кошелек Keplr, вы получаете адрес Mars, который совершенно не связан с адресом Terra, который вы получаете, вводя ту же сид-фразу в кошелек Terra Station. Происходит то, что Keplr создает кошелек на основе типа монеты 118, который создает отдельную учетную запись.
В результате, чтобы пользователь мог запросить аирдроп, ему необходимо предоставить две части данных: доказательство Меркла, подтверждающее, что адрес имеет право на вознаграждение за аирдроп, и подпись с помощью закрытого ключа Terra, выражающая намерение владельца потребовать вознаграждение. через их новый адрес на Марсе.
Если вы знаете данные об аирдропе, вы можете сгенерировать доказательство самостоятельно (подробнее об этом позже); но в целом это работа для внешнего веб-приложения. Для подписи вам понадобится кошелек, чтобы подписать сообщение. Для пользователей Ledger Ledger не поддерживает подписание произвольного текста, который не является транзакцией, поэтому пользователи Ledger не смогут выполнить этот шаг. Это ограничение типа монеты Terra, требующее миграции, и самого кошелька Ledger. Ожидается, что документация о том, как получить аирдроп для держателей кошельков Ledger, будет объявлена за некоторое время до даты аирдропа.
Доказательства Merkle
Дерево Меркла — это тип структуры данных для наборов данных. Для аирдропа Mars у нас есть набор данных с адресами пользователей и их подходящей суммой, на которую можно претендовать. Затем данные организуются в дерево Меркла.
В самом верху у нас есть корень. Внизу у нас есть листья, и каждый лист представляет точку данных в нашем наборе данных. Например, на изображении выше у нас есть простое дерево Меркла с 4 точками данных/записями. L1 — L4 каждый представляет пару {адрес Terra, требуемая сумма}.
В случае более крупного примера (30 000 точек данных) мы не хотели бы загружать каждую запись в блокчейн. Вместо этого нам нужен небольшой «отпечаток» данных фиксированного размера, который мы можем загрузить. Любой, у кого есть доступ к полному набору данных вне сети, может генерировать доказательства, которые вместе с корнем Merkle могут доказать, что определенная точка данных является частью набора данных.
Чтобы построить дерево, каждый лист сначала необходимо нормализовать до одинаковой длины. Мы достигаем этого, применяя хеш-функцию к листьям. Например, кодирование SHA-256 будет генерировать уникальный 32-битный хэш фиксированной длины, который детерминировано представляет базовые данные. Это также односторонняя функция, которая означает, что каждая запись будет генерировать уникальный хэш, но мы не можем создать запись из самого хэша.
Как только мы хешируем каждый лист, мы объединяем пары листьев. В нашем примере L1+L2 и L3+L4. Каждая группа берет два хэша из своих листьев и генерирует новый хэш, представляющий саму группу. Мы повторяем этот процесс, пока не доберемся до корневого хэша, который затем будет загружен в контракт как представление набора данных по отпечатку пальца.
Как это позволяет нам генерировать доказательства? Если мы изменим одну точку данных (например, дадим себе более крупный аирдроп, чем тот, на который мы фактически имеем право), мы сгенерируем совершенно новый хэш. В свою очередь, это создаст новый хэш для каждого узла в дереве, пока не будет сгенерирован новый корневой хеш. Чтобы доказательство было действительным, оно должно содержать правильную точку данных, иначе все доказательство не будет выполнено.
Получив доступ к набору данных вне сети, мы можем найти отдельные листья. Если у нас есть доступ к листовому хэшу и известны соответствующие пары групп, мы также можем сгенерировать такой же корневой хэш. Доказательство Меркла будет просто массивом или списком хэшей. Если доказательство Меркла генерирует тот же корневой хеш, что и в контракте, доказательство действительно. В противном случае транзакция не состоится.
Претензия Функция
Теперь, когда мы понимаем типы монет и доказательства Меркла, мы можем лучше понять дизайн функции «требование». Чтобы получить аирдроп $MARs, пользователь должен будет доказать, что он является законным владельцем соответствующей учетной записи Terra и суммы аирдропа. Именно здесь вступает в действие доказательство merkle. После того, как подходящий пользователь прошел аутентификацию, ему нужно будет подписать сообщение, выражающее намерение получить аирдроп через свою новую учетную запись Mars. Для подписи важно отметить, что мы подписываем хэш (мы можем подписывать только данные фиксированной длины).
Претензия Функция:
{
"требование": {
"terra_acct_pk": "...",
"mars_acct": "...",
"количество": "...",
"доказательство": [
"...",
".. .",
"..."
],
"подпись": "..."
}
}
Контракт сначала проверяет, заявлял ли уже соответствующий адрес право на раздачу. Для этого в контракте есть переменная `claimed`, хранящаяся в состоянии контракта. Если пользователь запрашивает аирдроп, в переменной Claims будет храниться заявленная сумма. Если переменная не пуста для пользователя, это означает, что аирдроп заявлен и транзакция отклонена.
Затем мы проверяем доказательство Меркле и сообщение подписи, как указано выше. Если какой-либо из этих шагов недействителен, будет выдана ошибка. Если оба варианта действительны, а аирдроп не был заявлен, то по контракту будут отправлены токены. Составляется ответ, содержащий сообщение об отправке соответствующего количества токенов на указанную учетную запись Mars, а также событие, которое помогает веб-приложениям индексировать действия в сети. Модуль wasm рассмотрит ответ и выполнит сообщение (отправит токены). Если транзакция прошла успешно, состояние контракта Airdrop будет обновлено.
Функция возврата
Функция «возврата» срабатывает после успешного голосования по управлению. В этот момент оставшиеся токены $MARS будут отправлены в пул сообщества Mars.
Оказывается, сделать пожертвование в пул сообщества не так просто, как отправить токены на учетную запись модуля пула сообщества.
В Cosmos SDK есть 2 типа учетных записей (базовая и модульная). Базовая учетная запись управляется закрытым ключом, а модульная учетная запись управляется кодом. Если вы из мира Ethereum, это похоже на различие между внешними учетными записями (EOA) и учетными записями смарт-контрактов.
В частности, средства в пуле сообщества хранятся на счете модуля «распределение». Можно предположить, что пожертвование средств в пул сообщества так же просто, как отправка средств на счета этого модуля. Тем не менее, это не так. Помимо пула сообщества, указанная учетная запись модуля также содержит другие средства, а именно невостребованные вознаграждения за стекинг и комиссии валидатора. Чтобы правильно отслеживать сумму каждого пула средств, модуль распределения определяет специальную функцию для пожертвования средств в пул сообщества.
Чтобы вызвать эту функцию «фондового сообщества», необходимо создать сообщение MsgFundCommunityPool и передать его маршрутизатору сообщений блокчейна. Это сообщение определяется языком Protobuf и находится в папке `proto`. Однако CosmWasm по умолчанию не поддерживает этот тип сообщений. Поэтому нам нужно будет прописать пользовательские плагины в нашей папке wasm (где у нас есть привязки). Как правило, подключаемый модуль запроса будет соответствовать QueryMsg и так далее. Нам понадобится обработчик выполнения сообщения, оформленный для нашего пользовательского плагина. Как только появляется пользовательское сообщение, оно отправляется. Если сообщение относится к варианту сообщества фонда, мы отправляем сообщение в пул сообщества, в противном случае выполняем отдельную функцию.
QueryMsg
Можно еще многое сказать о QueryMsg. Однако в этой разбивке мы просто проходим перечисляющие запросы.
Идея проста: каждая структура данных карты должна иметь перечисляющий запрос. Вместо отслеживания 1 элемента мы перечисляем все элементы карты. Для контракта Airdrop, если вы укажете адрес, он вернет определенную сумму. Вы также можете иметь параметры разбиения на страницы, чтобы вернуть несколько записей.
Чтобы написать перечислительный запрос, вам нужен метод диапазона, который захватывает массив результатов и анализирует каждый тип ответа.
Что дальше
Следующее заседание по обзору кода будет посвящено изменениям в модуле управления и договоре наделения правами. Слушайте, задавайте вопросы и помогайте выявлять ошибки в этой прямой видеотрансляции. Детали события:
- 15 июля 2022 г.
- 12:30 МСК | 8:30 по восточному поясному времени
- http://Discord.gg/марспротокол
Имейте в виду, что все вышеперечисленное отражает текущее мышление Центра управления полетами, но не гарантируется и не обещается. Настоящим не подразумевается никаких договоров или обязательств. Не принимайте никаких финансовых решений на основании этого объявления.
- Управление полетами
🔴
Следите за новостями Mars в Твиттере и подписывайтесь на электронную рассылку новостей Mars, чтобы быть в курсе последних обновлений от Центра управления полетами.
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ
Эта статья не является рекомендацией по инвестициям и полностью регулируется приведенными здесь заявлениями об отказе от ответственности Mars .