Отладка «Ошибка моделирования транзакции» при отправке инструкции программы (Solana Solidity)

При попытке вызвать программу, скомпилированную с помощью @solana/solidity , я получаю следующую ошибку:

      Transaction simulation failed: Error processing Instruction 0: Program failed to complete 
    Program jdN1wZjg5P4xi718DG2HraGuxVx1mM7ebjXpxbJ5R3N invoke [1]
    Program log: pxKTQePwHC9MiR52J5AYaRtSLAtkVfcoGS3GaLD24YX
    Program log: sender account missing from transaction
    Program jdN1wZjg5P4xi718DG2HraGuxVx1mM7ebjXpxbJ5R3N consumed 200000 of 200000 compute units
    Program failed to complete: BPF program Panicked in solana.c at 285:0
    Program jdN1wZjg5P4xi718DG2HraGuxVx1mM7ebjXpxbJ5R3N failed: Program failed to complete

jdN1wZjg5P4xi718DG2HraGuxVx1mM7ebjXpxbJ5R3Nявляется открытым ключом программы и pxKTQePwHC9MiR52J5AYaRtSLAtkVfcoGS3GaLD24YXявляется открытым ключом отправителя.

Я использую ответвление библиотеки @solana/solidity , которое предоставляет Transactionобъект, чтобы его можно было подписать и отправить с помощью Phantom Wallet на внешнем интерфейсе. Код, который приводит к ошибке, выглядит следующим образом:

      // Generate the transaction
const transaction = contract.transactions.send(...args);

// Add recent blockhash and fee payer
const recentBlockhash = (await connection.getRecentBlockhash()).blockhash;
transaction.recentBlockhash = recentBlockhash;
transaction.feePayer = provider.publicKey;

// Sign and send the transaction (throws an error)
const res = await provider.signAndSendTransaction(transaction);

Я бы попытался отладить это самостоятельно, но я не уверен, с чего начать. Поиск сообщения об ошибке не дал никаких результатов, и сообщение об ошибке не очень описательно. Я не уверен, возникает ли эта ошибка в самом выполнении программы или это проблема с составом объекта транзакции. Если это проблема выполнения программы, есть ли способ добавить журналы в мой код Solidity? Если это проблема с объектом транзакции, чего может не хватать? Как я могу лучше отлаживать такие проблемы?

Спасибо за любую помощь.

Изменить: теперь я получаю другую ошибку, хотя я не изменил ни один из предоставленных кодов. Сообщение об ошибке теперь следующее:

      Phantom - RPC Error: Transaction creation failed. {code: -32003, message: 'Transaction creation failed.'}

К сожалению, это сообщение об ошибке еще менее полезно, чем предыдущее. Я не уверен, был ли обновлен Phantom Wallet или была ли обновлена ​​​​зависимость проекта в какой-то момент, но, учитывая расплывчатый характер обоих этих сообщений об ошибках и тот факт, что ни один из моих кодов не изменился, я полагаю, что они вызваны по тому же вопросу. Опять же, любая помощь или советы по отладке приветствуются.

1 ответ

Мне удалось решить эту проблему, и хотя я столкнулся с другой проблемой, она не связана с содержанием этого вопроса, поэтому я опубликую ее отдельно.

Что касается моего редактирования, я обнаружил, что разница между сообщениями об ошибках сводилась к тому, как я отправлял транзакцию. Сначала я пытался отправить его с помощью Фантома. .signAndSendTransaction()метод, который дал второе сообщение об ошибке (перечисленное под моим редактированием). Затем я попытался подписать и отправить транзакцию вручную, например:

      const signed = await provider.request({
  method: 'signTransaction',
  params: {
    message: bs58.encode(transaction.serializeMessage()),
  },
});

const signature = bs58.decode(signed.signature);
transaction.addSignature(provider.publicKey, signature);

await connection.sendRawTransaction(transaction.serialize())

Что привело к более подробной ошибке, включенной в мой исходный пост. Это сообщение об ошибке оказалось полезным, как только я понял, что искать — открытый ключ отправляющей учетной записи отсутствовал в keysполе на TransactionInstructionна Transaction. Я добавил его в свой форк библиотеки @solana/solidity , и ошибка исчезла.

Короче говоря, способ, которым я смог отладить это, был

  1. С использованием provider.request({ method: 'signTransaction' })а также connection.sendRawTransaction(transaction)а не у Фантома provider.signAndSendTransaction()метод для более подробного сообщения об ошибке
  2. Регистрация объекта транзакции и тщательная проверка инструкций

Я надеюсь, что это поможет кому-то еще в будущем.

Другие вопросы по тегам