Разработка системы кошелька для биржи — интеграция цепочки Solana

金色财经_
SOL0,79%
ETH0,51%
USDC-0,01%

В прошлой статье мы дополнили систему риск-менеджмента биржи, а в этой — подключаем кошельки к цепочке Solana. Модель аккаунтов, логирование и механизм подтверждения в Solana существенно отличаются от цепочек на базе Ethereum. Если использовать подходы Ethereum, легко наткнуться на ошибки. Ниже мы разберем общую концепцию работы с Solana.

Понимание особенностей Solana

Модель аккаунтов Solana

Solana использует разделение программ и данных: программы могут быть общими, а данные хранятся в отдельных PDA (Program Derived Address) аккаунтах. Поскольку программы — общие, для различения токенов используют Token Mint. Аккаунт Token Mint хранит глобальные метаданные токена, такие как права на создание (mint_authority), общее предложение (supply), количество десятичных знаков (decimals) и т.д.
У каждого токена есть уникальный адрес Mint, например, USDC в основной сети Solana — EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v.

На Solana существует две системы программ для токенов: SPL Token и SPL Token-2022. Для каждого токена создается отдельный ATA (Associated Token Account), в котором хранится баланс пользователя. При переводе токенов вызывается соответствующая программа для перемещения средств между ATA.

Ограничения логов в Solana

В Ethereum для получения информации о переводах используют логи транзакций. В Solana логирование по умолчанию не сохраняется навсегда, и логи не являются частью состояния блокчейна (отсутствует фильтр Bloom). Также возможна обрезка логов во время выполнения.
Поэтому для сверки пополнений нельзя просто сканировать логи — нужно использовать getBlock или getSignaturesForAddress для анализа команд.

Подтверждение и реорганизация блоков в Solana

Блоки в Solana создаются примерно за 400 мс. После 32 подтверждений (около 12 секунд) блок считается окончательным (finalized). Если требования к скорости не очень высоки, достаточно доверять только finalized-блокам.
Для более высокой скорости необходимо учитывать возможные реорганизации блоков, хотя они случаются редко. В отличие от Ethereum, в Solana цепочка не строится на основе parentBlockHash, поэтому нельзя определить ветвление по сравнению parentBlockHash и хеша блока.
Для обнаружения реорганизаций нужно хранить в локальной базе данных хеши блоков по слотам. Если для одного слота меняется блокхеш, значит произошел откат.

Понимание особенностей Solana позволяет приступить к реализации. Ниже — изменения в базе данных:

Дизайн таблиц базы данных

Поскольку в Solana есть два типа токенов, в таблице tokens добавляем поле token_type для различения SPL Token и SPL Token-2022.

Несмотря на отличия адресов Solana и Ethereum, их можно получать через BIP32/BIP44 с разными путями. Поэтому оставляем таблицу wallets без изменений, а для поддержки ATA и отслеживания блоков добавляем три таблицы:

Название таблицы Основные поля Описание
solana_slots slot, block_hash, status, parent_slot Хранит слоты, помогает обнаруживать реорганизации и откаты
solana_transactions tx_hash, slot, to_addr, token_mint, amount, type Детали транзакций пополнения/вывода, tx_hash — уникальный для отслеживания
solana_token_accounts wallet_id, wallet_address, token_mint, ata_address Отслеживание связки ATA и кошелька, используется при сканировании

Объяснение полей:

  • solana_slots: хранит статус подтверждения (confirmed, finalized, skipped).
  • solana_transactions: хранит суммы в минимальных единицах (лампорт), тип операции (deposit/withdraw).
  • solana_token_accounts: связывает ATA с кошельком и токеном, обеспечивает уникальность.

Поддержка пополнений

Для обработки пополнений необходимо постоянно сканировать цепочку. Есть два подхода:

  1. Сканирование подписей (getSignaturesForAddress):
    Передается адрес ATA, вызывается с параметрами before, until, limit, чтобы получать новые подписи. Эти адреса — сгенерированные для пользователя ATA или programID. После получения подписей вызывается getTransaction для получения деталей.

  2. Сканирование блоков (getBlock):
    Постоянно запрашиваем последние слоты, вызываем getBlock для получения транзакций и анализируем инструкции.

Первый метод подходит при небольшом числе аккаунтов, второй — при большом. В нашем случае используем второй.

Обратите внимание: из-за высокого трафика и TPS в Solana, в реальной среде может возникнуть задержка обработки. Для этого используют очередь сообщений (Kafka, RabbitMQ), чтобы фильтровать и сохранять потенциальные события пополнения. Также для ускорения можно использовать Redis для хранения горячих данных. При большом числе адресов — деление по ATA для параллизации.

Альтернативно — сторонние индексеры (например, RPC-провайдеры с Webhook и расширенными фильтрами), которые позволяют получать события без самостоятельного сканирования.

Процесс сканирования блоков

Используем метод 2 — сканирование блоков. Основные шаги:

  1. Инициализация и загрузка истории (performInitialSync):
    Обрабатываем слоты с последнего завершенного, проверяя каждый слот, обновляем целевые параметры. Используем подтверждение confirmed.

  2. Постоянное сканирование новых слотов (scanNewSlots):
    Обновляем информацию о новых слотах, проверяем подтверждение и возможные откаты.

  3. Анализ блока (txParser.parseBlock):
    Вызываем getBlock для слота, перебираем транзакции, инструкции и метаданные. Обрабатываем только успешные транзакции.

  4. Анализ инструкций (txParser.parseInstruction):

  • SOL переводы: по системной программе, проверяем destination.
  • Токен переводы: по программам SPL Token и SPL Token-2022, ищем transfer или transferChecked, сопоставляем ATA с кошельком через базу данных.

Обработка откатов:
Постоянно сравниваем текущий блокхеш с сохраненным для слота. Если есть изменение — происходит откат.

Пример кода:

// scanSingleSlot.ts
async function scanSingleSlot(slot: number) {
  const block = await solanaClient.getBlock(slot);
  if (!block) {
    await insertSlot({ slot, status: 'skipped' });
    return;
  }
  const finalizedSlot = await getCachedFinalizedSlot();
  const status = slot <= finalizedSlot ? 'finalized' : 'confirmed';
  await processBlock(slot, block, status);
}

// txParser.ts
for (const tx of block.transactions) {
  if (tx.meta?.err) continue; // пропускаем неуспешные
  const instructions = [
    ...tx.transaction.message.instructions,
    ...(tx.meta.innerInstructions ?? []).flatMap(i => i.instructions)
  ];
  for (const ix of instructions) {
    // SOL перевод
    if (ix.programId === SYSTEM_PROGRAM_ID && ix.parsed?.type === 'transfer') {
      if (monitoredAddresses.has(ix.parsed.info.destination)) {
        // обработка
      }
    }
    // Токен перевод
    if (ix.programId === TOKEN_PROGRAM_ID || ix.programId === TOKEN_2022_PROGRAM_ID) {
      if (ix.parsed?.type === 'transfer' || ix.parsed?.type === 'transferChecked') {
        const ataAddress = ix.parsed.info.destination;
        const walletAddress = ataToWalletMap.get(ataAddress);
        if (walletAddress && monitoredAddresses.has(walletAddress)) {
          // обработка
        }
      }
    }
  }
}

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

Вывод средств

Процесс вывода схож с EVM, но есть отличия:

  1. В Solana два типа токенов: SPL Token и SPL Token 2022, их programId различаются. При формировании транзакции нужно учитывать это.
  2. Транзакция состоит из message и signatures. В качестве nonce используется recentBlockhash, который нужно получать в реальном времени.

Процесс:

  • Формируем инструкции для перевода SOL или токенов.
  • Создаем сообщение транзакции, подписываем его.
  • Отправляем через RPC.

Пример кода:

// Создание инструкции перевода SOL
const instruction = getTransferSolInstruction({
  source: hotWalletSigner,
  destination: solanaAddress,
  amount: BigInt(amount)
});

// Создание инструкции перевода токенов
const instruction = getTransferInstruction({
  source: sourceAta,
  destination: destAta,
  authority: hotWalletSigner,
  amount: BigInt(amount)
});

// Создание и подпись транзакции
const transactionMessage = createTransactionMessage({
  feePayer: hotWalletSigner,
  recentBlockhash: await getRecentBlockhash(),
  instructions: [instruction]
});
const signedTx = await signTransaction(transactionMessage);
const encodedTx = getBase64EncodedWireTransaction(signedTx);

Отправка осуществляется через @solana/web3.js:

const solanaRpc = chainConfigManager.getSolanaRpc();
const txSignature = await solanaRpc.sendTransaction(encodedTx);

Реализация находится в файлах:

  • Wallet: walletBusinessService.ts (строки 405–754)
  • Signer: solanaSigner.ts (строки 29–122)
  • Тест: requestWithdrawOnSolana.ts

Оптимизации, которые еще нужно реализовать:

  • Проверка существования ATA перед выводом (создавать при необходимости).
  • Установка computeUnitPrice для повышения приоритета при перегруженности сети.

Итог

Интеграция Solana в биржу не требует кардинальных изменений архитектуры, главное — адаптировать модель аккаунтов, структуру транзакций и механизм подтверждения.
Для пополнений важно заранее создавать и поддерживать таблицу соответствия ATA и кошелькам, а также отслеживать изменения blockhash для обнаружения реорганизаций.
При выводе — получать актуальный recentBlockhash и учитывать различия в токенах.

Посмотреть Оригинал
Отказ от ответственности: Информация на этой странице может поступать от третьих лиц и не отражает взгляды или мнения Gate. Содержание, представленное на этой странице, предназначено исключительно для справки и не является финансовой, инвестиционной или юридической консультацией. Gate не гарантирует точность или полноту информации и не несет ответственности за любые убытки, возникшие от использования этой информации. Инвестиции в виртуальные активы несут высокие риски и подвержены значительной ценовой волатильности. Вы можете потерять весь инвестированный капитал. Пожалуйста, полностью понимайте соответствующие риски и принимайте разумные решения, исходя из собственного финансового положения и толерантности к риску. Для получения подробностей, пожалуйста, обратитесь к Отказу от ответственности.

Связанные статьи

На этой неделе спотовые ETF на Ethereum в США чистый отток составил 60 миллионов долларов, а спотовые ETF на Solana чистый приток составил 20,40 миллиона долларов

Gate News, на 21 марта, согласно данным мониторинга Farside, спотовые ETF на эфириум в США на этой неделе накопили чистый отток в размере 60 миллионов долларов, а спотовые ETF на Solana накопили чистый приток в размере 20,4 миллиона долларов.

GateNews2ч назад

Кит Solana разблокирует $163 миллионов ставки за раз - U.Today

Solana пережила значительное разблокирование более 1.8 миллиона токенов SOL стоимостью $163.86 миллиона, что может повлиять на стабильность цены около $90. Это движение может увеличить циркулирующее предложение, в то время как смешанные ценовые движения следуют после недавней волатильности.

UToday2ч назад

Прогноз цены BTC накаляется, Solana расширяется, а APEMARS появляется среди лучших альткойнов для инвестиций...

Крипто-рынки снова нагреваются, поскольку инвесторы ищут лучшие альткоины для инвестирования, а следующий ход Bitcoin вызывает новые спекуляции. Трейдеры внимательно следят за последними тенденциями в прогнозах цены BTC и растущей экосистемой Solana, которые оба подогревают возобновленный интерес по всему рынку.

BlockChainReporter6ч назад

GalaChain запускает план расширения экосистемы, GalaSwap поддерживает подключение активов Solana, TON и Ethereum

Gate News сообщает, что 21 марта Gala Games официально объявила о запуске плана расширения экосистемы GalaChain. Её децентрализованная биржа GalaSwap теперь поддерживает подключение токенов из экосистем Solana, TON и Ethereum к сети GalaChain. По словам официального представителя, это позволит обеспечить кросс-экосистемный доступ к активам и взаимодействие, активизировать сообщество и повысить видимость токенов различных проектов.

GateNews10ч назад

Председатель Фонда Solana Лили Лю объявила о «смерти блокчейн-игр», общая капитализация упала на 87%

Председатель фонда Solana Лили Лю заявила в X, что «блокчейн-игры больше не вернутся», вызвав оживленные обсуждения в сообществе GameFi. Рыночная капитализация криптоигр рухнула с пика в 35 миллиардов долларов в 2022 году до 4,5 миллиардов долларов, что представляет падение на 87%. Она указала, что механики заработка игр имели приоритет над самими играми, что привело к постепенному сокращению рынка, тогда как внутри Solana реакция неоднозначна: некоторые проекты все еще корректируют свои стратегии для выживания.

動區BlockTempo15ч назад

Председатель фонда Solana: блокчейн-игры умерли и не вернутся

Председатель Solana Foundation Лили Лю заявила, что блокчейн-игры не вернутся, ссылаясь на пример Meta от Марка Цукерберга, который отказался от видения метавселенной после инвестиций в размере 80 миллиардов долларов, хотя стратегия Meta не явно связана с блокчейном.

GateNews16ч назад
комментарий
0/400
Нет комментариев