Разработка SPL-токена (Solana)

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка SPL-токена (Solana)
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1221
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1163
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    855
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1056
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    828

Разработка SPL-токена (Solana)

EVM-разработчики, приходящие на Solana, обычно ожидают аналог ERC-20 с похожими концепциями. Реальность сильно отличается. В Solana нет концепции "контракта токена" как такового — есть Token Program (системная программа), которая управляет всеми токенами, и Mint account — аккаунт с метаданными конкретного токена. Логика настройки и кастомизации токена реализуется не через наследование контракта, а через комбинацию extension'ов Token-2022 и отдельных программ (например, Transfer Hook).

Token Program vs. Token-2022

На Solana существует два стандарта:

spl-token (Token Program) — оригинальный стандарт 2020 года. Простой, проверенный временем, поддерживается всеми кошельками и DEX. Возможности: mint, burn, transfer, freeze, multisig authority.

Token-2022 (Token Extensions Program) — новый стандарт с расширяемой архитектурой. Рекомендован для новых проектов. Ключевые расширения:

Extension Назначение
TransferFee Комиссия на каждый transfer (аналог reflection/tax token)
TransferHook Вызов кастомной программы при каждом transfer
ConfidentialTransfer Приватные балансы через ZK proofs (ElGamal шифрование)
PermanentDelegate Адрес с постоянным правом сжигать/переводить токены
MintCloseAuthority Возможность закрыть Mint account (вернуть rent)
NonTransferable Soulbound токены — нельзя передать
InterestBearingMint Начисление процентов on-chain
MetadataPointer + TokenMetadata Метаданные прямо в Mint account

Создание Mint account

С помощью @solana/spl-token (TypeScript SDK):

import {
    createMint,
    createAssociatedTokenAccount,
    mintTo,
    TOKEN_2022_PROGRAM_ID,
    ExtensionType,
    getMintLen,
    createInitializeMintInstruction,
    createInitializeTransferFeeConfigInstruction,
} from "@solana/spl-token";
import { Connection, Keypair, SystemProgram, Transaction } from "@solana/web3.js";

async function createTokenWithTransferFee(
    connection: Connection,
    payer: Keypair,
    mintAuthority: PublicKey,
    decimals: number,
    feeBasisPoints: number,    // 100 = 1%
    maxFee: bigint,            // максимальная комиссия в lamports
) {
    const mintKeypair = Keypair.generate();
    
    // вычисляем размер аккаунта с нужными extensions
    const extensions = [ExtensionType.TransferFeeConfig];
    const mintLen = getMintLen(extensions);
    
    const lamports = await connection.getMinimumBalanceForRentExemption(mintLen);
    
    const transaction = new Transaction().add(
        // создаём аккаунт нужного размера
        SystemProgram.createAccount({
            fromPubkey: payer.publicKey,
            newAccountPubkey: mintKeypair.publicKey,
            space: mintLen,
            lamports,
            programId: TOKEN_2022_PROGRAM_ID,
        }),
        // инициализируем TransferFee extension ДО инициализации mint
        createInitializeTransferFeeConfigInstruction(
            mintKeypair.publicKey,
            payer.publicKey,       // transferFeeConfigAuthority
            payer.publicKey,       // withdrawWithheldAuthority
            feeBasisPoints,
            maxFee,
            TOKEN_2022_PROGRAM_ID,
        ),
        // инициализируем mint
        createInitializeMintInstruction(
            mintKeypair.publicKey,
            decimals,
            mintAuthority,
            null, // freeze authority — null если не нужна
            TOKEN_2022_PROGRAM_ID,
        ),
    );
    
    await sendAndConfirmTransaction(connection, transaction, [payer, mintKeypair]);
    return mintKeypair.publicKey;
}

Критически важный момент: extensions инициализируются до InitializeMint. Это контрнтуитивно для EVM-разработчиков, но так устроена архитектура Token-2022 — сначала настраиваем расширения, потом финализируем mint.

Associated Token Accounts

В Solana каждый пользователь должен иметь отдельный Token Account для каждого токена. Associated Token Account (ATA) — детерминированный адрес, производный от кошелька пользователя и адреса mint. ATA создаётся один раз, адрес всегда предсказуем:

import { getAssociatedTokenAddress, createAssociatedTokenAccountInstruction } from "@solana/spl-token";

const ata = await getAssociatedTokenAddress(
    mintAddress,
    walletAddress,
    false,                  // allowOwnerOffCurve — обычно false
    TOKEN_2022_PROGRAM_ID,
);

// создаём ATA если не существует (idempotent)
const createATAIx = createAssociatedTokenAccountInstruction(
    payer.publicKey,   // кто платит rent
    ata,
    walletAddress,     // владелец
    mintAddress,
    TOKEN_2022_PROGRAM_ID,
);

Rent за Token Account (~0.002 SOL) платит создающая сторона — это важный UX-момент. Многие проекты берут на себя создание ATA для пользователей при первой операции (airdrop, покупка), включая стоимость rent в свою operational expenses.

Transfer Hook: кастомная логика при переводах

Transfer Hook — наиболее мощный extension, позволяющий выполнять произвольную логику при каждом transfer. Это Solana-аналог ERC-20 хуков или transfer callbacks.

Кастомная программа (Transfer Hook program) вызывается автоматически Token-2022 при каждом transfer. В программе можно реализовать: whitelist/blacklist проверку, royalty для токенов, блокировку переводов в locked period, integration с protocol state.

// Transfer Hook program (Anchor framework)
use anchor_lang::prelude::*;
use spl_transfer_hook_interface::instruction::ExecuteInstruction;

#[program]
pub mod transfer_hook {
    use super::*;
    
    // эта функция вызывается Token-2022 при каждом transfer
    pub fn transfer_hook(ctx: Context<TransferHook>, amount: u64) -> Result<()> {
        let sender = &ctx.accounts.source_token;
        let receiver = &ctx.accounts.destination_token;
        
        // проверяем whitelist
        let config = &ctx.accounts.hook_config;
        require!(
            config.whitelist.contains(&receiver.owner),
            TransferError::ReceiverNotWhitelisted
        );
        
        // логируем transfer для off-chain анализа
        emit!(TransferEvent {
            from: sender.owner,
            to: receiver.owner,
            amount,
            timestamp: Clock::get()?.unix_timestamp,
        });
        
        Ok(())
    }
}

Transfer Hook требует что все additional accounts, нужные хуку, были переданы в транзакцию заранее. Это усложняет клиентский код — нужно знать какие accounts нужны хуку перед отправкой транзакции. SDK предоставляет addExtraAccountMetasForExecute для автоматического разрешения этих accounts.

Метаданные токена

Метаданные (name, symbol, image, описание) хранятся двумя способами:

Metaplex Metadata Program — legacy подход, стандарт для NFT и большинства fungible токенов сегодня. Отдельный аккаунт с метаданными, привязанный к mint. Широкая поддержка кошельками и маркетплейсами.

Token Metadata Extension (Token-2022) — новый подход, метаданные прямо в Mint account. Проще архитектурно, не требует Metaplex. Поддержка кошельками растёт, но пока менее универсальна чем Metaplex.

Для production fungible токена (DeFi, governance) в 2024–2025 году рекомендуется Metaplex — максимальная совместимость с экосистемой (кошельки, DEX, агрегаторы цен).

Работа с Anchor framework

Большинство Solana-программ пишется на Rust с Anchor framework. Anchor генерирует IDL (Interface Definition Language) — аналог ABI в EVM — что упрощает клиентскую интеграцию:

anchor build   # компиляция + генерация IDL
anchor test    # тесты на localnet
anchor deploy  # деплой на devnet/mainnet

Для токена без кастомной программы Anchor не нужен — достаточно @solana/spl-token SDK. Anchor необходим если строится dApp поверх токена с кастомной бизнес-логикой (стейкинг, вестинг, governance).