1. Введение
Solana — это высокопроизводительная блокчейн-система первого уровня (Layer 1) без разрешений (permissionless), которая поддерживает разработку программ (смарт-контрактов) на различных языках (например, Rust, C++ и C). Благодаря использованию механизма Tower BFT (византийская отказоустойчивость), сеть способна обрабатывать тысячи транзакций в секунду. Одной из ключевых инноваций Solana является Proof of History (PoH) — глобально доступный источник времени в сети без разрешений, который работает до достижения консенсуса. Мы более подробно обсудим PoH в будущем.
2. Наша миссия
BlockSec — это компания в сфере безопасности блокчейнов, чьей миссией является «обеспечение безопасности экосистемы DApp». Поэтому мы предоставляем не только услуги по аудиту контрактов, но и рекомендации о том, как писать безопасные смарт-контракты для всего сообщества. Учитывая популярность, высокую производительность и отличную архитектуру Solana, эта серия статей будет посвящена безопасности смарт-контрактов на Rust в сети Solana.
3. Привет, Solana
Прежде чем мы перейдем к обсуждению смарт-контрактов Solana с точки зрения безопасности, нам сначала нужно узнать, как писать, компилировать и развертывать смарт-контракты Solana. В качестве примера мы используем Hello World.
3.1 Обзор кода
В Solana смарт-контракт называется «программой». Программа Hello World предназначена для ведения счетчика, который записывает количество вызовов целевого аккаунта (принадлежащего программе) клиентом и выводит это число.
Давайте разберем контракт целиком.

Строки с 1 по 9 явно импортируют множество библиотек в область видимости с помощью ключевого слова use.

В строке 12 [derive(BorshSerialize, BorshDeserialize, Debug)] используется для сериализации и десериализации параметров, передаваемых в структуру GreetingAccount, которая определена в строках с 13 по 16. Структура содержит публичный член counter типа u32. После этого, как указано в комментарии, в строке 19 происходит экспорт точки входа программы — функции process_instruction.

Функция process_instruction принимает три параметра (а именно program_id, accounts и _instruction_data). Обратите внимание, что program_id — это публичный ключ (т.е. адрес) развернутой программы, а accounts содержит аккаунт, которому отправляется «приветствие». Параметр _instruction_data пуст и не используется.
Чтобы узнать больше о программах и аккаунтах в Solana, пожалуйста, обратитесь к документации Solana.
В строке 27 выводится приветственное сообщение. В строках с 30 по 33 происходит итерация по аккаунтам, и извлекается конкретный аккаунт, которому нужно отправить приветствие. После этого проверяется владелец аккаунта: он должен совпадать с program_id, чтобы гарантировать, что программа имеет право записывать данные в этот аккаунт. Наконец, greeting_account извлекается с помощью try_from_slice, и счетчик увеличивается на 1.
3.2 Компиляция программы
Для компиляции программы необходимо установить Solana CLI с помощью следующей команды:
sh -c "$(curl -sSfL https://release.solana.com/v1.9.9/install)"
Чтобы убедиться, что Solana CLI установлен успешно, можно проверить версию командой:
solana --version
Обратите внимание, что также требуются Rust и NodeJS.
Для компиляции программы используйте следующую команду:
cargo build-bpf --manifest-path=./src/program-rust/Cargo.toml --bpf-out-dir=dist/program
Скомпилированная программа будет создана в каталоге, указанном в --bpf-out-dir, под названием helloworld.so.
3.3 Развертывание контракта
Чтобы развернуть скомпилированную программу в Solana, сначала нужно выбрать кластер. В Solana существует четыре различных кластера: mainnet, testnet, devnet и localnet. В этой статье мы разворачиваем программу в devnet исключительно для демонстрации.
Мы используем следующую команду для выбора кластера:
solana config set --url https://api.devnet.solana.com
После этого нужно создать кошелек для развертывания. solana-keygen new --force помогает создать кошелек. Дополнительную информацию можно найти в документации Solana.
Поскольку у нового аккаунта нет баланса для оплаты комиссий за транзакции, мы получаем 1 SOL с помощью следующей команды:
solana airdrop 1 <YourPublicKey> --url https://api.devnet.solana.com
Теперь мы готовы развернуть контракт:
solana program deploy dist/program/helloworld.so
Пользователи могут просматривать программы и транзакции в обозревателе Devnet. В этой демонстрации вы можете найти развернутую программу по этой ссылке.
3.4 Отправка транзакции
Рекомендуется писать скрипты (клиенты) для отправки транзакций в Solana. К счастью, Solana предоставляет пример кода. Чтобы запустить клиент, сначала нужно установить его зависимости:
npm install
После завершения установки запустим функцию main в файле main.ts с помощью команды:
npm run start

В функции main клиент сначала устанавливает соединение с указанным кластером (т.е. Devnet) с помощью функции establishConnection(), проверяет плательщика комиссий с помощью establishPayer и подтверждает наличие программы и аккаунта, которому нужно отправить «приветствие», с помощью checkProgram. Обратите внимание: если требуемый аккаунт не существует, он будет создан путем отправки транзакции. В ходе нашей демонстрации аккаунт был создан (см. эту транзакцию).

Когда всё готово, вызывается функция sayHello. Транзакция состоит из одной инструкции. Эта инструкция получает keys, содержащие один аккаунт. Публичный ключ этого аккаунта (greetedPubkey) — это цель приветствия. Заметьте, этот аккаунт используется для хранения данных и не является подписантом (signer). В данном случае атрибут isSigner равен false, а isWritable — true. programId является владельцем greetedPubkey, он же — адрес развернутого контракта. Обратите внимание, data пуста и не используется в этой транзакции. В строке 208 вызывается функция sendAndConfirmTransaction, и транзакция отправляется в кластер.
Вы можете посмотреть детальную информацию о транзакции здесь.
4. Заключение
В этой статье мы кратко представили общую информацию о Solana и разобрали пример проекта (Hello World). Мы узнали, как развернуть программу в Solana и как использовать клиент для взаимодействия с программой в сети. Пожалуйста, продолжайте следить за нашим блогом: мы будем регулярно публиковать новые статьи в этой серии.
Читайте другие статьи из этой серии:
- Обеспечение безопасности экосистемы Solana (2) — Взаимодействие между программами
- Обеспечение безопасности экосистемы Solana (3) — Обновление программ
- Обеспечение безопасности экосистемы Solana (4) — Валидация аккаунтов
- Обеспечение безопасности экосистемы Solana (5) — Мультиподпись
- Обеспечение безопасности экосистемы Solana (6) — Мультиподпись 2
- Обеспечение безопасности экосистемы Solana (7) — Путаница типов



