Как интегрировать контракт (программу) с web3 в Solana?

Я использую библиотеку @solana/web3.js и протестировал создание новой учетной записи и получение баланса. Теперь я собираюсь интегрировать контракт (Raydium Liqudity PoolV4) с web3.

Я googled и не могу найти хороший материал для изучения. Можете ли вы помочь мне, как интегрировать контракт в solana с помощью web3? Спасибо.

1 ответ

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

Давайте посмотрим на Raydium. Они имеют закрытый исходный код на стороне программы, но на стороне клиента .

Мы можем видеть, что dataLayoutявляется:

      const dataLayout = struct([u8('instruction'), nu64('amountIn'), nu64('minAmountOut')])

Это говорит нам о том, что инструкция swap принимает amountInа также minAmountOut. nu64является u64на стороне программы.

Вероятно, очень похоже на инструкцию по обмену spl-swap

      pub struct Swap {
    /// SOURCE amount to transfer, output to DESTINATION is based on the exchange rate
    pub amount_in: u64,
    /// Minimum amount of DESTINATION token to output, prevents excessive slippage
    pub minimum_amount_out: u64,
}

Затем мы видим, что данные закодированы с помощьюinstruction: 9, что означает swapинструкция является 9-й инструкцией в программе.

      const data = Buffer.alloc(dataLayout.span)
dataLayout.encode(
  {
    instruction: 9,
    amountIn,
    minAmountOut
  },
  data
)

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

Таким образом, программа на Rust будет выглядеть примерно так:

      pub enum RaydiumInstructions {
    /** 0 **/Instruction0 (/**/),
    /** 1 **/Instruction1 (/**/),
    /** 2 **/Instruction2 (/**/),
    /** 3 **/Instruction3 (/**/),
    /** 4 **/Instruction4 (/**/),
    /** 5 **/Instruction5 (/**/),
    /** 6 **/Instruction6 (/**/),
    /** 7 **/Instruction7 (/**/),
    /** 8 **/Instruction8 (/**/),
    /** 9 **/Swap (/**/)
}

Нам нужно знать счета, требуемые этой инструкцией для отправки с транзакцией. Если вы проверитеspl-swap, в нем точно указано, какие учетные записи, порядок и являются ли они подписывающими или доступными для записи. 11 аккаунтов.

      ///   0. `[]` Token-swap
///   1. `[]` swap authority
///   2. `[]` user transfer authority
///   3. `[writable]` token_(A|B) SOURCE Account, amount is transferable by user transfer authority,
///   4. `[writable]` token_(A|B) Base Account to swap INTO.  Must be the SOURCE token.
///   5. `[writable]` token_(A|B) Base Account to swap FROM.  Must be the DESTINATION token.
///   6. `[writable]` token_(A|B) DESTINATION Account assigned to USER as the owner.
///   7. `[writable]` Pool token mint, to generate trading fees
///   8. `[writable]` Fee account, to receive trading fees
///   9. `[]` Token program id
///   10. `[optional, writable]` Host fee account to receive additional trading fees
    Swap(Swap),

Вы можете увидеть в интерфейсе Raydium список всех учетных записей для транзакции:

      const keys = [
  // spl token
  { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
  // amm
  { pubkey: ammId, isSigner: false, isWritable: true },
  { pubkey: ammAuthority, isSigner: false, isWritable: false },
  { pubkey: ammOpenOrders, isSigner: false, isWritable: true },
  { pubkey: ammTargetOrders, isSigner: false, isWritable: true },
  { pubkey: poolCoinTokenAccount, isSigner: false, isWritable: true },
  { pubkey: poolPcTokenAccount, isSigner: false, isWritable: true },
  // serum
  { pubkey: serumProgramId, isSigner: false, isWritable: false },
  { pubkey: serumMarket, isSigner: false, isWritable: true },
  { pubkey: serumBids, isSigner: false, isWritable: true },
  { pubkey: serumAsks, isSigner: false, isWritable: true },
  { pubkey: serumEventQueue, isSigner: false, isWritable: true },
  { pubkey: serumCoinVaultAccount, isSigner: false, isWritable: true },
  { pubkey: serumPcVaultAccount, isSigner: false, isWritable: true },
  { pubkey: serumVaultSigner, isSigner: false, isWritable: false },
  { pubkey: userSourceTokenAccount, isSigner: false, isWritable: true },
  { pubkey: userDestTokenAccount, isSigner: false, isWritable: true },
  { pubkey: userOwner, isSigner: true, isWritable: false }
]

Итак, следующий шаг — отследить все эти учетные записи для отправки через транзакцию.

Наконец, мы добавляем их в объект транзакции и транслируем!

      let transaction = new Transaction().add(new TransactionInstruction({
    keys,
    programId,
    data
  })
await sendTransaction(connection, wallet, transaction)
Другие вопросы по тегам