Back to Blog

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

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

Sign up for the latest updates
Как решение BlockSec по обеспечению безопасности платежей помогает организациям оставаться защищёнными в эпоху ИИ
Security Services

Как решение BlockSec по обеспечению безопасности платежей помогает организациям оставаться защищёнными в эпоху ИИ

Узнайте, как BlockSec помогает платежным организациям защищать средства и данные, а также повышать устойчивость с помощью оценки безопасности, тестирования и непрерывного мониторинга.

Потери около 5,57 млн USD: атаки на X100 Freezer и NEM | Еженедельный обзор BlockSec
Security Insights

Потери около 5,57 млн USD: атаки на X100 Freezer и NEM | Еженедельный обзор BlockSec

Этот еженедельный отчёт охватывает два инцидента безопасности в сетях Ethereum и BNB Chain за период 19.10.2026–25.10.2026. В нём рассматриваются захват управления X100 Freezer, профинансированный с помощью флеш-кредита, и ошибка при расчёте налога, затронувшая пул ликвидности токена NEM в сети BNB Chain. Оценочные потери в рамках отчёта составляют в общей сложности около 5,57 млн USD: ~4,75 млн USD по рассматриваемой транзакции X100 и ~820 тыс. USD в результате инцидента с пулом NEM. В эту сумму не входят отдельно опубликованные данные о последующих выводах средств из X100.

Потери на сумму около 3,87 млн USD: взломы Autheo Network и UNCX | Еженедельный обзор BlockSec
Security Insights

Потери на сумму около 3,87 млн USD: взломы Autheo Network и UNCX | Еженедельный обзор BlockSec

В этом еженедельном отчёте рассматриваются 3 инцидента безопасности за период 12.10.2026–18.10.2026. Общий оценочный ущерб составил около 3,87 млн USD. Ущерб Autheo Network от компрометации закрытого ключа составил примерно 1,76 млн USD, Qubic Wallet потерял примерно 1,30 млн USD из-за ненадёжной генерации seed, а ошибка учёта в контрактах Smart Token Vesting V2 сети UNCX Network на Ethereum, BNB Chain, Base и Robinhood Chain привела к ущербу примерно в 807 тыс. USD. В подробном анализе инцидента UNCX объясняется, как некорректный расчёт совокупного количества долей смешивал транши вестинга, созданные при разных соотношениях токенов и долей, и позволял выводить из общих пулов больше положенного.