javascript 发送事务时未找到块哈希

tyu7yeag  于 2023-02-15  发布在  Java
关注(0)|答案(4)|浏览(167)

使用Solana web3发送交易时,有时会显示此错误:
Error: failed to send transaction: Transaction simulation failed: Blockhash not found
除了重试 x 次之外,处理此错误的正确方法是什么?
是否有办法保证发送事务时不会发生此问题?
下面是我如何发送事务的一个示例:

const web3 = require("@solana/web3.js")
const bs58 = require('bs58')

const publicKey = new web3.PublicKey(new Uint8Array(bs58.decode("BASE_58_PUBLIC_KEY").toJSON().data))
const secretKey = new Uint8Array(bs58.decode("BASE_58_SECRET_KEY").toJSON().data)

const connection = new web3.Connection(
  "https://api.mainnet-beta.solana.com", "finalized",
  {
    commitment: "finalized",
    confirmTransactionInitialTimeout: 30000
  }
)
const transaction = new web3.Transaction().add(
  web3.SystemProgram.transfer({
    fromPubkey: publicKey,
    toPubkey: publicKey,
    lamports: 1
  })
)
web3.sendAndConfirmTransaction(
  connection,
  transaction,
  [{publicKey: publicKey, secretKey: secretKey}],
  {commitment: "finalized"}
)

如何改进此问题以避免Blockhash not found错误?

elcex8rz

elcex8rz1#

重试并不是一件坏事!在某些情况下,它实际上是处理已删除事务的首选方法。例如,这意味着执行以下操作:

// assuming you have a transaction named `transaction` already
const blockhashResponse = await connection.getLatestBlockhashAndContext();
const lastValidBlockHeight = blockhashResponse.context.slot + 150;
const rawTransaction = transaction.serialize();
let blockheight = await connection.getBlockHeight();

while (blockheight < lastValidBlockHeight) {
  connection.sendRawTransaction(rawTransaction, {
    skipPreflight: true,
  });
  await sleep(500);
  blockheight = await connection.getBlockHeight();
}

您可能希望通读有关重试事务的详细说明:https://solanacookbook.com/guides/retrying-transactions.html
具体来说,它解释了如何实现某些重试逻辑:https://solanacookbook.com/guides/retrying-transactions.html#customizing-rebroadcast-logic
重试的具体含义是:https://solanacookbook.com/guides/retrying-transactions.html#when-to-re-sign-transactions

okxuctiv

okxuctiv2#

可以使用maxRetries选项:对于web 3/ Solana本机:

web3.sendAndConfirmTransaction(
  connection,
  transaction,
  {
     maxRetries: 5
  }
)

或对于SPL令牌:

const signature = await transfer(
  connection,
  sender,
  senderTokenAccount.address,
  recipientTokenAccount.address,
  sender.publicKey,
  amount,
  [],
  {
    maxRetries: 6,
  }
);
am46iovg

am46iovg3#

地层基金会有一个包索拉纳和它的生产级。
我在生产应用程序中使用过它。

const signature = await sendAndConfirmWithRetry(
      connection, 
      tx.serialize(), 
      {
        maxRetries: 5,
        skipPreflight: true
      },
      "processed");
gc0ot86w

gc0ot86w4#

从这里
RecentBlockhash是事务的重要值。如果使用过期的最近块哈希(超过150个块),您的事务将被拒绝
Solana阻塞时间是400毫秒也就是说

150 * 400ms = 60 seconds

这就是为什么你需要查询和发送交易非常快。否则,你的交易将永远下降,你会得到错误。正确的错误响应应该是"Blockhash过期"

相关问题