Skip to main content
5 человек
в команде
5 месяцев
в работе
Спроектировали и разработали совместно с IOHK децентрализованное приложение на платформе Plutus. Созданный DApp — это один из первых NFT-маркетплейсов на Cardano
Узнать больше

Фреймворк Anchor на Solana: что такое и как работает

anchors
Разработка смарт-контрактов на блокчейне Solana может быть сложной задачей. Особенно для тех, кто привык к экосистемам Ethereum и EVM. Фреймворк Anchor нужен, чтобы упростить процесс, — это инструмент для создания программ на Rust с минимальным количеством кода. В статье разберем, что такое Anchor, как он работает и какие преимущества дает разработчикам dapp.
Интерфейс Solana

Безопасность и валидация данных

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

Один из механизмов безопасности — макросы, которые позволяют описывать требования к аккаунтам — участникам транзакций, и автоматически проверяют их состояние.

Фрейм позволяет ограничить доступ к функциям смарт-контракта с помощью атрибутов для аккаунтов. Так, использование типа Signer гарантирует, что транзакция может быть выполнена только после цифровой подписи пользователя. Это важно для защиты операций с изменением данных, поскольку только владельцы соответствующих учетных записей могут выполнять действия.

Для более сложных проверок разработчики могут использовать макрос require!, который разрешает вручную задавать условия для выполнения транзакций. Если условие не выполнено, ошибка возвращается автоматически и отклоняет транзакцию. Это помогает избежать некорректных операций и защищает данные пользователей.

Rust, на котором основан Anchor, изначально защищен от таких распространенных ошибок, вроде переполнения целых чисел и проблемы с доступом к памяти.

Написание

Дальше мы поделимся инструкцией по разработке вашей программы, но до этого установите зависимости и настройте окружение. Фрейм работает поверх Rust и Solana CLI, поэтому сначала требуется скачать:

  • Rust (через rustup)
  • Solana CLI (через официальный установщик)
  • Anchor (через Cargo)

При работе с проектом Anchor можно создать fork репозитория на GitHub для внесения изменений.

Программа состоит из трех частей. #[program] — основная логика, где описаны обработчики функций. #[derive(Accounts)] — предоставляет info об участвующих аккаунтах. #[account] — структуры для хранения данных в блокчейне.

Пример структуры:

#[program]
pub mod example {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize {}

#[account]
pub struct ExampleData {
    pub value: u64,
}

Создадим новый проект с помощью команды:

anchor init my_anchor_project
Эта команда создаст базовую структуру проекта с файлом (file) lib.rs, который содержит основной код smart-контракта. Программная логика оформляется в виде структур и методов с аннотациями. Например, базовый шаблон программы может выглядеть так:
use anchor_lang::prelude::*;

#[program]
pub mod my_anchor_project {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        msg!("Программа Anchor успешно инициализирована!");
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize {}

В этом коде:

  • #[program] указывает, что это основная логика программы.
  • Context<Initialize> используется для управления учетными записями.
  • msg! — сообщение (message) об успешном обновлении выводится через макрос msg!.

Код нужно скомпилировать и развернуть в сети Solana.

Создание записи в журнале

Для хранения записей в журнале можно использовать PDA (Program Derived Addresses). Добавим в код структуру данных (datum) для хранения записи:
#[account]
pub struct JournalEntry {
    pub author: Pubkey,
    pub content: String,
}


Теперь создадим обработчик для добавления новой записи:
pub fn create_entry(ctx: Context<CreateEntry>, content: String) -> Result<()> {
    let entry = &mut ctx.accounts.entry;
    entry.author = *ctx.accounts.author.key;
    entry.content = content;
    msg!("Создана новая запись в журнале: {}", entry.content);
    Ok(())
}

#[derive(Accounts)]
pub struct CreateEntry<'info> {
    #[account(init, payer = author, space = 8 + 32 + 256)]
    pub entry: Account<'info, JournalEntry>,
    #[account(mut)]
    pub author: Signer<'info>,
    pub system_program: Program<'info, System>,
}

Здесь:

  • Аннотация #[account(init)] создает новый аккаунт (newaccount).
  • payer = author означает, что пользователь оплачивает транзакцию.
  • space = 8 + 32 + 256 выделяет память для записи.

Обновление записи журнала

Чтобы обновить существующую запись, добавим новый обработчик:
pub fn update_entry(ctx: Context<UpdateEntry>, new_content: String) -> Result<()> {
    let entry = &mut ctx.accounts.entry;
    require!(entry.author == *ctx.accounts.author.key, CustomError::Unauthorized);
    entry.content = new_content;
    msg!("Запись обновлена: {}", entry.content);
    Ok(())
}

#[derive(Accounts)]
pub struct UpdateEntry<'info> {
    #[account(mut, has_one = author)]
    pub entry: Account<'info, JournalEntry>,
    pub author: Signer<'info>,
}

Удаление записи журнала

Для удаления записи добавим обработчик:
pub fn delete_entry(ctx: Context<DeleteEntry>) -> Result<()> {
    require!(ctx.accounts.entry.author == *ctx.accounts.author.key, CustomError::Unauthorized);
    Ok(())
}

#[derive(Accounts)]
pub struct DeleteEntry<'info> {
    #[account(mut, close = author, has_one = author)]
    pub entry: Account<'info, JournalEntry>,
    #[account(mut)]
    pub author: Signer<'info>,
}

Аннотация close = author означает, что после удаления запись возвращает оставшиеся средства владельцу.

Создание и развертывание программы

Чтобы развернуть программу, выполним:
anchor build
anchor deploy

Anchor создаст ID программы. Он понадобится, чтобы работать с фронтендом. При инициализации проекта важно указать его имя (name), например, anchor init my_anchor_project

Подключение программы к пользовательскому интерфейсу

Чтобы связать смарт-контракт с фронтендом, используется @project-serum/anchor в TypeScript.
Устанавливаем зависимости:
npm install @project-serum/anchor @solana/web3.js

Пример кода для вызова функции create_entry из браузера:
import * as anchor from "@project-serum/anchor";

const provider = anchor.AnchorProvider.local();
anchor.setProvider(provider);

const program = anchor.workspace.MyAnchorProject;

async function createEntry(content) {
    const entryAccount = anchor.web3.Keypair.generate();
    await program.rpc.createEntry(content, {
        accounts: {
            entry: entryAccount.publicKey,
            author: provider.wallet.publicKey,
            systemProgram: anchor.web3.SystemProgram.programId,
        },
        signers: [entryAccount],
    });
    console.log("Запись создана:", entryAccount.publicKey.toString());
}
Эта функция подключается к смарт-контракту и отправляет транзакцию для создания записи.

Разработка на стороне клиента

Чтобы работать с программами Solana с фронтенда, нужны JavaScript/TypeScript и @project-serum/anchor. Эта библиотека упрощает вызов RPC-функций программ.

Пример подключения программы:
import * as anchor from "@project-serum/anchor";

const provider = anchor.AnchorProvider.local(); // Локальный провайдер для тестов
anchor.setProvider(provider);

const program = anchor.workspace.MyAnchorProject; // Доступ к программе

Разработка on-chain программ

Onchain программы на «Солана» реализуются на языке Rust с использованием фреймворка Anchor. Они выполняются непосредственно на блокчейне, и это накладывает ограничения.

У каждой программы фиксированный объем памяти, поэтому данные оптимизируются. Результат выполнения программы всегда должен быть предсказуемым. Использование аккаунтов и операций требует оплаты в SOL. Anchor предоставляет макросы для более простого управления аккаунтами и транзакциями. Например, макрос #[account] определяет структуру данных, которая хранится в блокчейне.

Для разработки программ полезно использовать:

  • Solana CLI, чтобы управлять сетью, аккаунтами и программами.
  • Anchor CLI, чтобы упростить создание, тестирование и развертывание программ.
  • Localnet, чтобы использовать локальную сеть для тестирования программ без затрат на SOL.
  • Solana Explorer, чтобы получить интерфейс для просмотра транзакций, программ и аккаунтов.
  • Solana Devnet, чтобы бесплатно развернуть программы для тестирования.

Можно использовать IDE с поддержкой Rust, например, Visual Studio Code с плагинами для Rust.

Создание на примере

Рассмотрим простой пример программы. Она будет записывать и обновлять текст.

Создайте проект:
anchor init example_project
cd example_project

В lib.rs добавьте логику для записи данных:
use anchor_lang::prelude::*;

#[program]
pub mod example_project {
    use super::*;

    pub fn set_data(ctx: Context<SetData>, data: String) -> Result<()> {
        let account = &mut ctx.accounts.data_account;
        account.data = data;
        msg!("Данные установлены!");
        Ok(())
    }
}

#[derive(Accounts)]
pub struct SetData<'info> {
    #[account(init, payer = user, space = 8 + 64)]
    pub data_account: Account<'info, DataAccount>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>,
}

#[account]
pub struct DataAccount {
    pub data: String,
}


Разверните программу:
anchor build
anchor deploy

А это — пример программы-счетчика:

use anchor_lang::prelude::*;

#[program]
pub mod counter_program {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        let counter = &mut ctx.accounts.counter;
        counter.count = 0;
        msg!("Счетчик инициализирован!");
        Ok(())
    }

    pub fn increment(ctx: Context<Increment>) -> Result<()> {
        let counter = &mut ctx.accounts.counter;
        counter.count += 1;
        msg!("Счетчик увеличен до {}", counter.count);
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(init, payer = user, space = 8 + 8)]
    pub counter: Account<'info, Counter>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(mut)]
    pub counter: Account<'info, Counter>,
}

#[account]
pub struct Counter {
    pub count: u64,
}

Что еще важно знать

Anchor действительно упрощает разработку программ, но, как и любой инструмент, требует погружения. Во-первых, несмотря на автоматизацию многих процессов вроде управления учетными записями и верификации данных, разработчику нужно четко представлять, как блокчейн обрабатывает транзакции и взаимодействует с аккаунтами. Программы на Anchor тесно связаны с архитектурой Solana: каждый объект здесь — отдельный аккаунт с определенной структурой и объемом памяти.

При работе с памятью стоит учитывать строгое ограничение на размер данных. В отличие от традиционных баз данных, хранение информации в блокчейне платное и требует эффективного использования ресурсов. Anchor позволяет частично решить эту проблему за счет использования структур данных с минимальным накладным расходом и макросов для экономного управления памятью.

Кроме того, Anchor предоставляет безопасную модель разработки, автоматически генерируя проверки прав доступа и условия выполнения транзакций. Но разработчику все равно нужно следить за безопасностью своих программ. Например, важно корректно настраивать проверку прав на запись и выполнение, чтобы предотвратить несанкционированные изменения данных.

Еще одна деталь — интеграция с клиентской стороной через JavaScript и TypeScript. Библиотека @project-serum/anchor облегчает взаимодействие с программами через удобные функции по вызову методов контрактов. Тем не менее, необходимо понимать RPC-запросы и работу с ключами доступа.

Тестирование тоже важно. Anchor дает встроенные инструменты для локального тестирования программ — нет необходимости развертывать их в публичной сети. Это позволяет разработчикам быстрее находить ошибки и оптимизировать код.

Фреймворк заметно упрощает работу со смарт-контрактами на Solana. Код можно написать быстрее, безопаснее и с меньшим количеством ошибок. За счет удобного API и встроенных инструментов для работы с учетными записями, он снижает порог входа для новых разработчиков. Создавать децентрализованные приложения становится проще, а код программы можно выложить на GitHub для общего доступа и контроля версий.
Получите бесплатную консультацию
Заполните форму, чтобы связаться с нашим менеджером.
Нажимая на кнопку, вы соглашаетесь с политикой конфиденциальности
Или можно запланировать встречу в Calendly calendly
p2e
новое
anchors
новое
gamefi_what_is_it
smart_contracts_solana
trump_coins
gamefi_2025
solana
defii
defi_pools
web3app
dapps
rwa_tokens_2024

Главные RWA токены в 2024 году

Редакция MetaLamp

Энциклопедия

web3-wiki
rwa-wiki
rwa_tokens
coins
yield
pool_defi
rwa_what_is

Что такое RWA?

Редакция MetaLamp

Энциклопедия

web3-wiki
rwa-wiki
smart_contracts

Что такое смарт-контракты

Редакция MetaLamp

Энциклопедия

web3-wiki
smart-contract-wiki
EVM-кошелек