Back to Blog

Безопасность экосистемы Solana (5) — Мультиподпись

April 10, 2022
5 min read

0. Обзор

1. Обзор

В предыдущем блоге мы обсуждали проверку аккаунтов, которая важна для контроля доступа в программах Solana. Однако для децентрализованных DApp и для защиты от потенциальной утечки закрытых ключей крайне важна мультиподпись (Multi-Sig). В этой статье мы представим реализацию мультиподписи.

2. Концепция мультиподписи

Мультиподпись — это схема цифровой подписи, которая позволяет группе пользователей подписывать одну транзакцию. Транзакция может быть вызовом привилегированной функции (например, минтинг), инструкцией по переводу средств и т.д. Механизм мультиподписи заключается в том, что при наличии n участников с собственными закрытыми ключами, для выполнения транзакции должны подписаться как минимум m из них. Это делает средства в DeFi намного безопаснее и защищает от таких рисков, как утечка закрытого ключа или мошенничество (rug pull).

3. Использование мультиподписи

В Solana существует программа мультиподписи от Serum, которая очень похожа на логику мультиподписи, разработанную компанией OpenZeppelin. Она позволяет нескольким пользователям подписывать транзакцию полностью в блокчейне. Однако процесс можно упростить, если собрать все необходимые подписи вне сети (off-chain). Чтобы проиллюстрировать это, мы добавили функциональность мультиподписи в тестовый код из предыдущей статьи. Весь тестовый код можно найти здесь.

3.1 Обзор кода

В предыдущем проекте мы заменили администратора аккаунта config на аккаунт multisig. В этом случае, чтобы выполнить инструкции Lock (блокировка) и Unlock (разблокировка), клиент должен будет включить в транзакцию достаточное количество подписей от действительных владельцев.

Мы добавили структуру под названием Multisig, состоящую из четырех атрибутов. Это количество подписей, необходимых для выполнения инструкции, общее количество действительных подписантов, статус аккаунта (инициализирован или нет) и массив открытых ключей действительных подписантов.

Соответственно, мы также добавили инструкцию InitializeMultisig в instruction.rs. Обратите внимание, что она принимает аргумент m (u8) со стороны клиента. Это значение будет передано в функцию InitializeMultisig().

Функция InitializeMultisig() получает созданные аккаунты и значение m. Чтобы предотвратить повторную инициализацию аккаунта злоумышленниками, мы проверяем, был ли аккаунт уже инициализирован (строки 385-388). После этого мы инициализируем мультисиг-аккаунт, присваивая значения m, n и открытые ключи подписантов.

В функции Lock() мы проверяем, является ли административный аккаунт config мультисиг-аккаунтом. Если да, то он проверяет и подсчитывает переданные подписи (строки 151-158). Как только количество действительных подписей достигает или превышает требуемое количество, двери блокируются (строки 163-168). Реализация мультиподписи в функции Unlock() аналогична функции Lock().

Мы развернули программу в тестовой сети (testnet), её можно найти по следующей ссылке:

https://explorer.solana.com/address/4g5ZA47pDQ1Bv93aNYdSKAXB6DvPAnnbi9cNEx7722SK?cluster=testnet

3.2 Отправка транзакции

В функции InitializeMultisig() массив keys включает четыре аккаунта. Это мультисиг-аккаунт и три аккаунта действительных подписантов. Обратите внимание, что один из подписантов также является плательщиком комиссии за транзакцию. Мы устанавливаем значение m равным 2, что означает, что для выполнения привилегированных функций требуются подписи двух из трех подписантов.

Мы также устанавливаем администратора аккаунта config в качестве аккаунта multisig, передавая открытый ключ мультисиг-аккаунта в данных инструкции.

В функции lock(), помимо аккаунта config (строка 410), мы передаем мультисиг-аккаунт (строка 411) и два (минимум) аккаунта действительных подписантов (строки 412-413). Мы устанавливаем атрибут isSigner в значение true для подписантов. Опять же, логика функции unlock() аналогична.

Все тестовые транзакции перечислены ниже. Весь процесс выглядит так: AllocatePDA() -> InitializeMultisig() -> InitializeDoor() -> InitializeConfig() -> Unlock() -> Open() -> Close() -> Lock().

https://explorer.solana.com/tx/2inXLHv34NzkmwmvQ7iimdNbEX2Hj8qWS3MVteAPtwhCAPy1yxXXdvfzMmUL7tESsd4wat4LMcPNiEQav18kQTrZ?cluster=testnet
https://explorer.solana.com/tx/4GErNusHLXpUHBsAJ55c7v1Ur1jfv5hAR88CK8nabLnzc92b1UhDnNRryKVjKmcnJDXppmyk6m5RUdpR2w7MEbrU?cluster=testnet
https://explorer.solana.com/tx/2S8h66oWfh7cn4fwFCVPtgGw1o3NgzyWwU1GyRpDjH4PEBfe8LDMZGAEBYLRJpzL3anH9ENShntjg3q5K8gcZSrN?cluster=testnet
https://explorer.solana.com/tx/nVKxPYegbpH324y57uHDZiajpNA5u4bSSJ2gHFHHRx4GJBy1DcpxnccKh1Ltkv9dah1qJNi9jWuBnXbyHWXCJyw?cluster=testnet
https://explorer.solana.com/tx/3KK5CU88oV59VfdTrNpT4LsiUsetuGdc6qW3sNyyGEWVYtKJfD6XA2Nfknrriwuka9wknHpZs3WZ1WkeduDA1pZX?cluster=testnet
https://explorer.solana.com/tx/3rFo37CrLSsMehLk4kwmMSDnbRfLfoPCWZzRDXhwwLg1uq32gu4ddxkYYB3pJX1yiMN8MofnV1Y9CSaf8bQaNJ9Y?cluster=testnet
https://explorer.solana.com/tx/5yFq4dZAMpccn96jKNkYFVcmhmtrwZYSFEQ6pkNgSMd7e1Vy1ztAM3RdFUZjEtThjFssz1TFytowePPyY59we9rX?cluster=testnet
https://explorer.solana.com/tx/3Ut4DqjCQi1MoCsjRx24DxykyDMsmyRsjJSXS7D4FBeZQwrx4UzxWt2gDe6YRiwUHzFkH3eWkFHub6FNSp2Us4Q7?cluster=testnet

3.3 Тестовая транзакция

Чтобы проверить, действительно ли работает мультиподпись, мы модифицируем скрипт клиента.

Как показано выше, мы передаем только один аккаунт подписанта и предоставляем только одну действительную подпись.

Мы заметили, что дверь не может быть разблокирована из-за недостаточного количества подписей.

4. Итоги

В этой статье мы представили простую реализацию мультиподписи в Solana. Она предназначена для сценариев, в которых вы можете собрать подписи от нескольких пользователей вне сети (off-chain). Сценарий, в котором транзакции должны быть полностью подписаны в блокчейне (on-chain), будет представлен позже. Продолжайте следить за нами, мы поделимся большим количеством информации в следующих публикациях.

Читайте другие статьи из этой серии:


О компании BlockSec

BlockSec — это передовая компания в области безопасности блокчейнов, основанная в 2021 году группой всемирно признанных экспертов по безопасности. Компания стремится повысить уровень безопасности и удобства использования для развивающегося мира Web3, чтобы способствовать его массовому внедрению. С этой целью BlockSec предоставляет услуги по аудиту безопасности смарт-контрактов и EVM-сетей, платформу Phalcon для безопасной разработки и проактивной блокировки угроз, платформу MetaSleuth для отслеживания и расследования транзакций, а также расширение MetaSuites для эффективного использования Web3-инструментов.

На сегодняшний день компания обслужила более 300 уважаемых клиентов, таких как MetaMask, Uniswap Foundation, Compound, Forta и PancakeSwap, и получила десятки миллионов долларов США в рамках двух раундов финансирования от ведущих инвесторов, включая Matrix Partners, Vitalbridge Capital и Fenbushi Capital.

Официальный сайт: https://blocksec.com/

Официальный аккаунт в Twitter: https://twitter.com/BlockSecTeam