发送程序指令时调试 "Transaction simulation failed" (Solana Solidity)

Debugging "Transaction simulation failed" when sending program instruction (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 是程序的 public 键,pxKTQePwHC9MiR52J5AYaRtSLAtkVfcoGS3GaLD24YX 是发件人的 public 键。

我在前端使用 a fork of the @solana/solidity library that exposes the Transaction object so that it can be signed and sent by 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 是否已更新或项目依赖项是否在某个时候更新了,但考虑到这两个错误消息的模糊性质以及我的代码 none 已更改的事实,我相信他们' 是由同一个问题引起的。再次感谢任何帮助或调试提示。

我已经解决了这个问题,虽然我已经运行到另一个问题,但它与这个问题的内容无关,所以我会单独post它。

关于我的编辑,我发现错误消息之间的区别在于我发送交易的方式。起初,我尝试使用 Phantom 的 .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())

这产生了我原来 post 中包含的更详细的错误。一旦我意识到要寻找什么,该错误消息确实很有帮助——[=14= 上的 TransactionInstruction 上的 keys 字段中缺少发送帐户的 public 密钥].我将它添加到 my fork of the @solana/solidity 库中,错误消失了。

简而言之,我调试它的方法是

  1. 使用 provider.request({ method: 'signTransaction' })connection.sendRawTransaction(transaction) 而不是 Phantom 的 provider.signAndSendTransaction() 方法以获得更详细的错误消息
  2. 记录交易对象并仔细检查说明

我希望这对以后的其他人有所帮助。